Туториал 4: 2Д платформер (для новичков). Часть 1.
Введение:
В этом уроке мы сделаем простой 2D платформер на движке Unity. В туториале будет использоваться встроенная физика2D. Также я хочу показать основы анимации (мы будем работать с листами спрайтов). Для этого урока вам понадобятся несколько разных файлов, таких как спрайты, звуки. Вы можете скачать архив .zip здесь.1. Шаг
Запустите Unity и создайте новый 2D-проект.2. Шаг
Сначала создайте землю для нашей игры. Импортируйте largeGround из загруженного архива ( здесь ссылка снова, если ещё не скачали. Распакуйте архив .zip после его загрузки).Перетащите largeGround в сцену. Переименуйте созданный игровой объект как Ground . Проверьте, что Z-позиция равна нулю (измените её на 0 , если отличается). Добавьте к нему Box Collider 2D.
3. Шаг
Теперь мы можем сделать игрока. Для этого у меня есть лист спрайтов с крысой. Импортируйте ratIdle (из скаченного архива) в окно Assets. Нам надо разделить спрайты. Выберите ratIdle и переключите Sprite Mode на Multiple. Нажмите Apply .Нажмите на Sprite Editor и новое окно будет открыто. Нажмите Slice. Измените Type на Grid By Cell Count. Установите Column на 4 и Row на 5. Нажмите на кнопку Slice. Нажмите на Apply. Закройте это окно.
Раскройте спрайт. В нем должно быть теперь 20 кадров. Перетащите первый кадр в сцену. Будет создан новый игрвой объект. Выделите этот объект и назовите его Rat. Посмотрите на его Inspector. Измените Tag на Player. Убедитесь, что его Z-позиция 0. Добавьте к нему Capsule Collider 2D. Измените Direction на Horizontal. Нажмите на кнопку Edit и настройте размер коллайдера (тяните за зеленые точки). Теперь добавьте Rigidbody 2D. Установите Interpolate на Interpolate. Разверните Constraints и включите Freeze Rotation Z.
4. Шаг
Для крысы нужен скрипт движения. Создайте новый C# скрипт (правый клик в Assets) и назовите его PlayerMove. Для движения будем использовать встроеннную физику 2Д, то-есть будем использовать Rigidbody2D. Мы можем изменять скорость в зависимости о данных, полученных от Input Manager (я надеюсь, вы смотрели предыдущие туториалы и мне не надо будет повторяться). Откройте PlayerMove скрипт.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour {
//переменная для скорости движения
public float speed;
//ссылочная переменная для компонента Rigidbody2D
Rigidbody2D rb;
void Start () {
//делаем ссылку на Rigidbody2D
rb = GetComponent <Rigidbody2D> ();
}
void FixedUpdate () {
//декларация переменной с её инициализацией значением полученным с горизонтальной оси (значение лежит в области между -1 и 1)
float x = Input.GetAxis ("Horizontal");
//декларация локального вектора и инициализация посчитанным значением
//x: значение от InputManager * speed
//y: принять текущее значение, мы не будем его менять, из-за использования силы тяжести
//z: должно быть равно нулю, нам не нужно движение по оси Z
Vector3 move = new Vector3 (x * speed, rb.velocity.y, 0f);
//Изменить скорость игрока на вычисленный вектор
rb.velocity = move;
}
}
Выберите крысу в иерархии и добавьте к ней скрипт PlayerMove . Измените переменную Speed (около 3). Вы можете запустить игру и проверить сцену. Крыса должна двигаться влево и вправо (использовать левую/правую стрелку или A/D).using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour {
//переменная для скорости движения
public float speed;
//ссылочная переменная для компонента Rigidbody2D
Rigidbody2D rb;
void Start () {
//делаем ссылку на Rigidbody2D
rb = GetComponent <Rigidbody2D> ();
}
void FixedUpdate () {
//декларация переменной с её инициализацией значением полученным с горизонтальной оси (значение лежит в области между -1 и 1)
float x = Input.GetAxis ("Horizontal");
//декларация локального вектора и инициализация посчитанным значением
//x: значение от InputManager * speed
//y: принять текущее значение, мы не будем его менять, из-за использования силы тяжести
//z: должно быть равно нулю, нам не нужно движение по оси Z
Vector3 move = new Vector3 (x * speed, rb.velocity.y, 0f);
//Изменить скорость игрока на вычисленный вектор
rb.velocity = move;
}
}
5. Step
Теперь мы можем добавить прыжок крысе. Мы будем применять силу вдоль оси Y для прыжка. Смотрите Unity Manual для подробностей. Сила не должна добавляться каждый раз, когда нажимается кнопка прыжка, или крыса полетит как ракета. Также нам понадобится логическая переменная для управления прыжком. И нам нужна функция для переключения этой переменной относительно положения крысы к земле. Есть очень много способов достичь этого (триггер, raycast, таймер или что-то еще). Мы будем использовать Physics2D.OverlapPoint , чтобы определить, какой слой находится под контрольной точкой. Смотрите Unity Manual для деталей. Откройте PlayerMove скрипт снова.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour {
//в инспекторе мы можем выбрать, какие слои будут землёй
public LayerMask whatIsGround;
//позиция для проверки касания земли
public Transform groundCheck;
//переменная, которая будет true, если крыса находится на земле
public bool isGrounded;
//значение величины силы
public float jumpForce;
//переменная для скорости движения
public float speed;
//ссылочная переменная для компонента Rigidbody2D
Rigidbody2D rb;
void Start () {
//делаем ссылку на Rigidbody2D
rb = GetComponent <Rigidbody2D> ();
}
//я буду использовать Update() для более точного определения прыжка
void Update () {
//проверка, нажат-ли прыжок и находится-ли крыса на земле
if (Input.GetButtonDown ("Jump") && isGrounded) {
//применяем силу на Rigidbody2D вдоль оси Y для прыжка
rb.AddForce (Vector2.up * jumpForce, ForceMode2D.Impulse);
//переключаем переменную, чтобы предотвратить следующий прыжок, или мы могли бы снова прыгнуть (до того, как isGrounded будет переключена в FixedUpdate ())
isGrounded = false;
}
}
void FixedUpdate () {
//изменяем переменную, зависящую от результата Physics2D.OverlapPoint
isGrounded = Physics2D.OverlapPoint (groundCheck.position, whatIsGround);
//декларация переменной с её инициализацией значением полученным с горизонтальной оси (значение лежит в области между -1 и 1)
float x = Input.GetAxis ("Horizontal");
//декларация локального вектора и инициализация посчитанным значением
//x: значение от InputManager * speed
//y: принять текущее значение, мы не будем его менять, из-за использования силы тяжести
//z: должно быть равно нулю, нам не нужно движение по оси Z
Vector3 move = new Vector3 (x * speed, rb.velocity.y, 0f);
//Изменить скорость игрока на вычисленный вектор
rb.velocity = move;
}
}
Выберите Rat в иерархии, щелкните по нему правой кнопкой мыши и выберите Create Empty . Выберите этот созданный объект и переименуйте его в GroundCheck . using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour {
//в инспекторе мы можем выбрать, какие слои будут землёй
public LayerMask whatIsGround;
//позиция для проверки касания земли
public Transform groundCheck;
//переменная, которая будет true, если крыса находится на земле
public bool isGrounded;
//значение величины силы
public float jumpForce;
//переменная для скорости движения
public float speed;
//ссылочная переменная для компонента Rigidbody2D
Rigidbody2D rb;
void Start () {
//делаем ссылку на Rigidbody2D
rb = GetComponent <Rigidbody2D> ();
}
//я буду использовать Update() для более точного определения прыжка
void Update () {
//проверка, нажат-ли прыжок и находится-ли крыса на земле
if (Input.GetButtonDown ("Jump") && isGrounded) {
//применяем силу на Rigidbody2D вдоль оси Y для прыжка
rb.AddForce (Vector2.up * jumpForce, ForceMode2D.Impulse);
//переключаем переменную, чтобы предотвратить следующий прыжок, или мы могли бы снова прыгнуть (до того, как isGrounded будет переключена в FixedUpdate ())
isGrounded = false;
}
}
void FixedUpdate () {
//изменяем переменную, зависящую от результата Physics2D.OverlapPoint
isGrounded = Physics2D.OverlapPoint (groundCheck.position, whatIsGround);
//декларация переменной с её инициализацией значением полученным с горизонтальной оси (значение лежит в области между -1 и 1)
float x = Input.GetAxis ("Horizontal");
//декларация локального вектора и инициализация посчитанным значением
//x: значение от InputManager * speed
//y: принять текущее значение, мы не будем его менять, из-за использования силы тяжести
//z: должно быть равно нулю, нам не нужно движение по оси Z
Vector3 move = new Vector3 (x * speed, rb.velocity.y, 0f);
//Изменить скорость игрока на вычисленный вектор
rb.velocity = move;
}
}
Выберите GroundCheck и включите иконку для лучшей видимости (смотрите скриншот). Включите moving tool и передвиньте GroundCheck под крысу, но не в сам коллайдер крысы. Убедитесь, что его Z-Position равна 0.
Выберите Ground в иерархии и смените Layer на Ground (добавьте новый Layer с этим названием, если в списке нет такого).
Выделите Rat в иерархии. В компоненте PlayerMove есть теперь новые поля. Включите Ground в whatIsGround. Поместите GroundCheck в поле GroundCheck. Измените JumpForce на 5.
Проверьте игру. Крыса должна теперь двигаться налево/направо и прыгать.
6. Step
Крыса должна уметь поворачиваться. Нам нужна функция для этого. В этой функции мы будем проверять значение "Horizontal" оси в Input Manager и поворачивать крысу в зависимости от этого значения. Для поворота будем использовать обратное значение x Scale в Transform компоненте. Откройте PlayerMove скрипт.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour {
//в инспекторе мы можем выбрать, какие слои будут землёй
public LayerMask whatIsGround;
//позиция для проверки касания земли
public Transform groundCheck;
//переменная, которая будет true, если крыса находится на земле
public bool isGrounded;
//значение величины силы
public float jumpForce;
//переменная для скорости движения
public float speed;
//ссылочная переменная для компонента Rigidbody2D
Rigidbody2D rb;
//переменная контроля направления крысы
public bool isLookingLeft;
void Start () {
//делаем ссылку на Rigidbody2D
rb = GetComponent <Rigidbody2D> ();
}
//я буду использовать Update() для более точного определения прыжка
void Update () {
//проверка, нажат-ли прыжок и находится-ли крыса на земле
if (Input.GetButtonDown ("Jump") && isGrounded) {
//применяем силу на Rigidbody2D вдоль оси Y для прыжка
rb.AddForce (Vector2.up * jumpForce, ForceMode2D.Impulse);
//sпереключаем переменную, чтобы предотвратить следующий прыжок, или мы могли бы снова прыгнуть (до того, как isGrounded будет переключена в FixedUpdate ())
isGrounded = false;
}
}
void FixedUpdate () {
//изменяем переменную, зависит от результата Physics2D.OverlapPoint
isGrounded = Physics2D.OverlapPoint (groundCheck.position, whatIsGround);
//декларация переменной с её инициализацией значением полученным с горизонтальной оси (значение лежит в области между -1 и 1)
float x = Input.GetAxis ("Horizontal");
//декларация локального вектора и инициализация посчитанным значением
//x: значение от InputManager * speed
//: принять текущее значение, мы не будем его менять, из-за использования силы тяжести
//z: должно быть равно нулю, нам не нужно движение по оси Z
Vector3 move = new Vector3 (x * speed, rb.velocity.y, 0f);
//изменить скорость игрока на вычисленный вектор
rb.velocity = move;
//проверка, совпадает ли направление взгляда с направлением движения
if (x < 0 && !isLookingLeft)
//вызов функции поворота крысы, если проверка совпала
TurnTheRat ();
//проверка, совпадает ли направление взгляда с направлением движения
if (x > 0 && isLookingLeft)
//вызов функции поворота крысы, если проверка совпала
TurnTheRat ();
}
//функция поворота крысы
void TurnTheRat ()
{
//смена переменной показывающей направление взгляда на обратное значение
isLookingLeft = !isLookingLeft;
//поворот крысы через инвертацию размера по оси х
transform.localScale = new Vector3 (transform.localScale.x * -1, transform.localScale.y, transform.localScale.z);
}
}
Выберите крысу. В скрипте PlayerMove появилась новая переменная для обозначения направления взгляда. Включите её, так как крыса смотрит налево.using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour {
//в инспекторе мы можем выбрать, какие слои будут землёй
public LayerMask whatIsGround;
//позиция для проверки касания земли
public Transform groundCheck;
//переменная, которая будет true, если крыса находится на земле
public bool isGrounded;
//значение величины силы
public float jumpForce;
//переменная для скорости движения
public float speed;
//ссылочная переменная для компонента Rigidbody2D
Rigidbody2D rb;
//переменная контроля направления крысы
public bool isLookingLeft;
void Start () {
//делаем ссылку на Rigidbody2D
rb = GetComponent <Rigidbody2D> ();
}
//я буду использовать Update() для более точного определения прыжка
void Update () {
//проверка, нажат-ли прыжок и находится-ли крыса на земле
if (Input.GetButtonDown ("Jump") && isGrounded) {
//применяем силу на Rigidbody2D вдоль оси Y для прыжка
rb.AddForce (Vector2.up * jumpForce, ForceMode2D.Impulse);
//sпереключаем переменную, чтобы предотвратить следующий прыжок, или мы могли бы снова прыгнуть (до того, как isGrounded будет переключена в FixedUpdate ())
isGrounded = false;
}
}
void FixedUpdate () {
//изменяем переменную, зависит от результата Physics2D.OverlapPoint
isGrounded = Physics2D.OverlapPoint (groundCheck.position, whatIsGround);
//декларация переменной с её инициализацией значением полученным с горизонтальной оси (значение лежит в области между -1 и 1)
float x = Input.GetAxis ("Horizontal");
//декларация локального вектора и инициализация посчитанным значением
//x: значение от InputManager * speed
//: принять текущее значение, мы не будем его менять, из-за использования силы тяжести
//z: должно быть равно нулю, нам не нужно движение по оси Z
Vector3 move = new Vector3 (x * speed, rb.velocity.y, 0f);
//изменить скорость игрока на вычисленный вектор
rb.velocity = move;
//проверка, совпадает ли направление взгляда с направлением движения
if (x < 0 && !isLookingLeft)
//вызов функции поворота крысы, если проверка совпала
TurnTheRat ();
//проверка, совпадает ли направление взгляда с направлением движения
if (x > 0 && isLookingLeft)
//вызов функции поворота крысы, если проверка совпала
TurnTheRat ();
}
//функция поворота крысы
void TurnTheRat ()
{
//смена переменной показывающей направление взгляда на обратное значение
isLookingLeft = !isLookingLeft;
//поворот крысы через инвертацию размера по оси х
transform.localScale = new Vector3 (transform.localScale.x * -1, transform.localScale.y, transform.localScale.z);
}
}
Крыса может теперь бежать влево и вправо и менять направление взгляда. Вы можете проверить сцену.
7. Step
Теперь можем начать анимировать крысу. Выберите Rat в иерархии и добавьте Animator к ней.Создайте Animator Controller в Assets. Назовите его RatAnimator.
Выберите Rat и добавьте RatController в поле Controller.
Нам понадобится окно Animation. Включите его в меню Window м поместите его там, где вам удобно (я поместил над Assets).
Выберите Rat в иерархии. Создайте новую анимацию (нажмите на кнопку Create). Назовите эту новую анимацию IdleRatAnimation.
Теперь можем добавить спрайтовый лист. Выделите Rat в иерархии. Разверните ratIdle спрайт. Надо выделить все кадры. Выберите первый кадр, зажмитеShift-Key и выделите последний кадр. Все 20 кадров должны выбраться. Перетащите все кадры в окошко Animation. Установите samples на 20. Сделайте двойной клик на первом кадре, чтобы сделать правильную длину анимации (возможно баг моей версии).
Включите окошко Animator в меню Window.
Анимация должна быть зацикленна. Убедитесь в этом на всякий случай. Перейдите к окну Animator и сделайте двойной клик на IdleRatAnimation Проверьте Loop Time.
У крысы есть теперь анимация покоя. Запустите сцену и проверьте.
8. Шаг
Теперь создадим анимацию бега. Импортируйте спрайт ratRun в Assets. Смените Sprite Mode на Multiple. Перейдите в Sprite Editor и переключите на Grid By Cell Count и установите Column 4, Row 5 (смотрите 3. Шаг). Выделите Rat в иерархии. Перейдите в окно Animations и нажмите на IdleRatAnimation потом нажмите на Create New Clip. Назовите новую анимацию RunRatAnimations.Раскройте спрайт ratRun и выделите все 20 кадров (нажмите первый кадр, держите кнопку шифт и нажмите последний кадр). Перетащите все кадры в окошко Animations. Установите samples на 20. Сделайте двойной клик на первом кадре, чтобы сделать правильную длину анимации (возможно баг моей версии).
Откройте окно Animator (включите его в меню Window, если не видите его).
IdleRatAnimation стандартная анимация. Нам нужны transition (переходы) к другим анимациям и параметры контроля этих transition. Нажмите на закладку Parameters. Добавьте новый float speed параметр. Сделайте правый клик на IdleRatAnimation и сделайте transition из IdleRatAnimation в RunRatAnimation. Потом правый клик на RunRatAnimation и добавьте transition на IdleRatAnimation.
Выберите transition от IdleRatAnimation к RunRatAnimation. Отключите Has Exit Time. Добавьте новое condition (условие). Измените его на speed greater 0.01.
Выберите transition от RunRatAnimation к IdleRatAnimation. Отключите Has Exit Time. Добавьте новое condition (условие). Измените его на speed less 0.01.
Анимация бега сейчас слишком медленная. Выберите RunRatAnimation в Animator и измените скорость на 2.5 (можете потом настроить по желанию).
9. Шаг
Нам нужен скрипт для смены условий в Animator. Мы могли бы добавить новые команды в скрипт PlayerMove, но для тренировки сделаем новый скрипт и с него получим нужные доступы. Мы будем проверять двигается ли крыса, и менять анимации в зависимости от движения. Создайте новый С# скрипт и назовите его PlayerAnim.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAnim : MonoBehaviour {
//ссылочная переменная для аниматора
Animator anim;
//ссылочная переменная для rigidbody2D
Rigidbody2D rb;
void Start () {
//делаем ссылку на аниматор
anim = GetComponent <Animator> ();
//делаем ссылку на Rigidbody2D
rb = GetComponent <Rigidbody2D> ();
}
void Update () {
//меняем параметр speed в Animator. Используем значение скорости по оси х
anim.SetFloat ("speed", Mathf.Abs (rb.velocity.x));
}
}
Добавьте этот скрипт к крысе Rat.using System.Collections.Generic;
using UnityEngine;
public class PlayerAnim : MonoBehaviour {
//ссылочная переменная для аниматора
Animator anim;
//ссылочная переменная для rigidbody2D
Rigidbody2D rb;
void Start () {
//делаем ссылку на аниматор
anim = GetComponent <Animator> ();
//делаем ссылку на Rigidbody2D
rb = GetComponent <Rigidbody2D> ();
}
void Update () {
//меняем параметр speed в Animator. Используем значение скорости по оси х
anim.SetFloat ("speed", Mathf.Abs (rb.velocity.x));
}
}
Запустите сцену. У крысы должна появиться анимация бега
10. Шаг
Теперь сделаем анимацию прыжка. Выберите Rat в иерархии. Добавьте новую анимацию (в окошке Animation) и назовите её JumpRatAnimation.Я не сделал анимацию прыжка, просто используем замедленную анимацию бега. Выделите Rat в иерархии. Проверьте в окошке Animation, что JumpRatAnimation выбранна. Разверните спрайт ratRun. Надо выделить все кадры. Выберите первый кадр, зажмитеShift-Key и выделите последний кадр. Все 20 кадров должны выбраться. Перетащите все кадры в окошко Animation. Установите samples на 20. Сделайте двойной клик на первом кадре, чтобы сделать правильную длину анимации (возможно баг моей версии).
11. Шаг
Переключитесь на Animator. Нам нужно условие для анимации прыжка. Добавьте новую Bool и назовите её isJumping. Сделайте теперь transition (переход) (правый клик) из Any State к JumpRatAnimation. Добавьте transition от JumpRatAnimation к IdleRatAnimation.Выделите transition от Any State к JumpRatAnimation. Отключите Has Exit Time. Разверните Settings и отключите Can Transition To (чтобы избежать перезапуска анимации, пока isJumping true). Добавьте condition (условие) isJumping true.
Выберите transition от JumpRatAnimation к IdleRatAnimation. Отключите Has Exit Time. Добавьте condition isJumping false.
Выделите JumpRatAnimation и измените Speed на 0.5. Замедленная анимация бега должна заменить анимацию прыжка.
12. Шаг
Нужен скрипт для контроля анимации прыжка. Откройте скрипт PlayerAnim. Из этого скрипта мы сделаем доступ на скрипт PlayerMove и сможем проверить переменную isGrounded. Если крыса не будет на земле, то сменим анимацию на анимацию прыжка. Также анимация прыжка будет включена при падении крысы.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAnim : MonoBehaviour {
//ссылочная переменная для аниматора
Animator anim;
//ссылочная переменная для rigidbody2D
Rigidbody2D rb;
//ссылочная переменная для PlayerMove
PlayerMove pm;
void Start () {
//делаем ссылку на Animator
anim = GetComponent <Animator> ();
//делаем ссылку на Rigidbody2D
rb = GetComponent <Rigidbody2D> ();
//делаем ссылку на PlayerMove
pm = GetComponent <PlayerMove> ();
}
void Update () {
//проверка, находится ли крыса на земле
if (pm.isGrounded) {
//меняем параметр isJumping на false
anim.SetBool ("isJumping", false);
//меняем параметр speed. Используем абсолютное значение вектора скорости по х
anim.SetFloat ("speed", Mathf.Abs (rb.velocity.x));
// если крыса не на земле
} else {
//меняем параметр speed на 0
anim.SetFloat ("speed", 0);
//меняем параметр isJumping на true
anim.SetBool ("isJumping", true);
}
}
}
Можете проверить сцену.using System.Collections.Generic;
using UnityEngine;
public class PlayerAnim : MonoBehaviour {
//ссылочная переменная для аниматора
Animator anim;
//ссылочная переменная для rigidbody2D
Rigidbody2D rb;
//ссылочная переменная для PlayerMove
PlayerMove pm;
void Start () {
//делаем ссылку на Animator
anim = GetComponent <Animator> ();
//делаем ссылку на Rigidbody2D
rb = GetComponent <Rigidbody2D> ();
//делаем ссылку на PlayerMove
pm = GetComponent <PlayerMove> ();
}
void Update () {
//проверка, находится ли крыса на земле
if (pm.isGrounded) {
//меняем параметр isJumping на false
anim.SetBool ("isJumping", false);
//меняем параметр speed. Используем абсолютное значение вектора скорости по х
anim.SetFloat ("speed", Mathf.Abs (rb.velocity.x));
// если крыса не на земле
} else {
//меняем параметр speed на 0
anim.SetFloat ("speed", 0);
//меняем параметр isJumping на true
anim.SetBool ("isJumping", true);
}
}
}
13. Step
Теперь добавим звуки шагов. Нам нужна функция для проигрывания звука. Вызывать функцию будем через аниматор. Создайте новый C# скрипт и назовите его PlayerSound.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerSound : MonoBehaviour {
//ссылочная переменная для звукового файла
public AudioClip footsteps;
//публичная функция, получим доступ к ней из аниматора
public void FootStepsAudio () {
//воспроизвести заданный звук на позиции крысы
AudioSource.PlayClipAtPoint (footsteps, transform.position);
}
}
Выберите Rat в иерархии и добавьте этот скрипт к крысе. Импортируйте аудио-файл ratStep. И добавьте ratStep в Footsteps поле компонента PlayerSound.using System.Collections.Generic;
using UnityEngine;
public class PlayerSound : MonoBehaviour {
//ссылочная переменная для звукового файла
public AudioClip footsteps;
//публичная функция, получим доступ к ней из аниматора
public void FootStepsAudio () {
//воспроизвести заданный звук на позиции крысы
AudioSource.PlayClipAtPoint (footsteps, transform.position);
}
}
Выделите Rat в иерархии и перейдите в Animation. Смените анимацию на RunRatAnimation. Выберите кадр, когда хотите воспроизвести звук (кликните на полоску времени). Нажмите на Add Event (смотрите скриншот). Выберите добавленный Animations Event и установите Function на FootStepsAudio().
14. Шаг
Теперь добавим звук после прыжка. Используем OnCollisionEnter2D для этого. Смотрите Unity Manual для деталей. Откройте скрипт PlayerSound.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerSound : MonoBehaviour {
//ссылочная переменная для аудио-файла
public AudioClip footsteps;
//публичная функция, получим доступ к ней из аниматора
public void FootStepsAudio () {
//воспроизвести заданный звук на позиции крысы
AudioSource.PlayClipAtPoint (footsteps, transform.position);
}
//запустится если было касание другого Collider2D
void OnCollisionEnter2D (Collision2D coll) {
//проверка тэга на тэг "Ground"
if (coll.gameObject.tag == "Ground") {
//воспроизвести заданный звук на позиции крысы
AudioSource.PlayClipAtPoint (footsteps, transform.position);
}
}
}
Выберите Ground в иерархии. Добавьте новый тэг Ground и измените тэг объекта Ground на тэг Ground.using System.Collections.Generic;
using UnityEngine;
public class PlayerSound : MonoBehaviour {
//ссылочная переменная для аудио-файла
public AudioClip footsteps;
//публичная функция, получим доступ к ней из аниматора
public void FootStepsAudio () {
//воспроизвести заданный звук на позиции крысы
AudioSource.PlayClipAtPoint (footsteps, transform.position);
}
//запустится если было касание другого Collider2D
void OnCollisionEnter2D (Collision2D coll) {
//проверка тэга на тэг "Ground"
if (coll.gameObject.tag == "Ground") {
//воспроизвести заданный звук на позиции крысы
AudioSource.PlayClipAtPoint (footsteps, transform.position);
}
}
}
15. Шаг
Выберите Ground в иерархии. Создайте prefab Ground (перетащите объект в Assets). Поместите prefab Ground в сцену, как следующую платформу.Выберите Main Camera и сделайте её дочерним объектом Rat (перетащите Main Camera на Rat). Камера будет следовать за крысой.
Можете изменить X-position камеры на 0, чтобы убрать рывки при повороте.
Я думаю, этого достаточно для первой части. Надеюсь, что вторая часть будет готова в мае-июне (у меня сейчас мало времени).
скачать готовый проект