Читать книгу Делаем PC игру вместе - Ар'лан ис'Дрекхэм - Страница 12

«Делаем PC игру вместе»
9. Движенине

Оглавление

Добавим следующую строку кода, которая формирует локальную переменную вектора в пространстве, в трех координатах – X, Y, Z:

Vector3 movement = new Vector3 (offsetX, 0, offsetZ);

Vector3 (вектор 3) в Unity3d фактически представляет собой просто 3 собранные вместе переменные типа float описанные ранее, но используется для описания положения в пространстве и направления движения.

Мы видим новый оператор под названием new (новый), этот оператор нужен для создания нового экземпляра типа данных. В данном случае мы создаем новый вектор с указанием двух переменных offsetX и offsetZ. Отсутствует переменная Y, которая описывает движение вверх-вниз, и сейчас не нужна.

Правильные направления по осям в Unity3d можно легко запомнить используя ассоциативное запоминание. Например, чтобы запомнить, что координата Z (зэт) это движение вперед, то можно представить себе, что Z похоже на зигзагообразное движение лодки по воде уходящей вдаль, т.е. плывем вперед (вперед-назад). Y (игрек) похожа на песочные часы, которые сыпятся только вниз (вверх-вниз), а для X (икс) остается только влево-вправо.

Сейчас мы сделали вектор движения movement (движение), который будет ответственным за движение нашего персонажа вперед-назад и влево-право, в зависимости от того какие клавиши на клавиатуре будет нажимать играющий человек. Но сейчас при текущем нашем коде движение вперед-назад и влево-право будут происходить медленнее, чем движения по диагонали. Это будет происходить потому, что при движении по диагонали будут учитываться значения смещений и offsetX и offsetZ вместе. Чтобы сделать движение по всем направлениям равномерным нужно добавить такой код следующей строкой:

movement = Vector3.ClampMagnitude (movement, speedfast);

ClampMagnitude это внутренний метод Unity3d, который ограничит величину нашего вектора движения так, что скорость перемещения будет равномерной по всем направлениям.

Добавим такую строчку кода:

movement. y = gravity;

Чуть выше мы не использовали переменную Y, которая нужна для движения вверх и вниз. Сейчас мы добаваляем и ее. В нашем векторе movement есть 3 переменные и мы можем получить или задать каждую из них в отдельности, сейчас это выглядит как movement. y, т.е. мы задаем эту переменную равной gravity (гравитация) для того чтобы наш будущий игрок мог свободно падать вниз если у него не будет опоры под ногами.

Следующий важный нюанс состоит в том чтобы наш будущий игрок мог двигаться одинаково на разных по мощности компьютерах, при разной скорости работы игры, при разных FPS игры и т. п. Для этого дальше напишем такую строчку кода:

movement = movement * Time.deltaTime;

В данной строке кода мы увязываем наш вектор движения movement через класс Time (многозадачный класс категории игрового времени) со временем рендеринга (визуализации) предыдущего кадра – deltaTime. Таким образом, любое движение в игре сможет рассчитываться вне зависимости от конкретного компьютера и его мощности. Используйте умножение на Time.deltaTime всегда в любом коде основанном на каком-то изменении значений во времени.

Также в языке C# предусмотрена возможность записи последней строки кода, так сказать, укороченно, что мы и сделаем:

movement *= Time.deltaTime;

В таком виде строка кода полностью соответсвтует предыдущей, так мы ее и оставим.

Теперь нужно «подковать еще одну ногу», а именно, наш персонаж скоро сможет двигаться, но как только он повернется его движение нарушится, т.е. персонаж будет смотреть куда-нибудь в сторону, а двигаться будет продолжать строго вперед-назад, влево-вправо. Чтобы такого не было нужно преобразовать вычисления нашего вектора movement из локальных координат в глобальные. Запишем далее такую строку:

movement = transform.TransformDirection (movement);

Слово transform это ссылка на соответствующий компонент, который находится на нашем игровом объекте Player. Здесь такая же технология как и с GetComponent <> () описанным ранее. Если после знака равенства сразу пишется transform или GetComponent <> (), это означает, что операции производятся с текущим игровым объектом на котором находится наш сценарий кода. TransformDirection () это метода Unity3d преобразующий наш вектор в мировые координаты (глобальные). Коротко поясню, что мировые координаты это основа всей 3д сцены среды разработки Unity3d, и они неизменны. А локальные координаты принадлежат какому-либо объекту сцены и постоянно изменяют свои направления, в зависимости от вращения этого объекта.

Теперь движения нашего персонажа вперед-назад, влево-вправо будут происходить в соответствии с его поворотом.

Программа движения персонажа готова и нужно ее исполнить, вернее применить к нашему игровому объекту Player. Для этого сообщим наш вектор движения компоненту CharacterController используя его внутренний метод Move (Двигать), добавим строчку кода:

CharControl.Move (movement);

Таким образом, наши строчки кода запускаясь бесконечно каждый кадр в методе Update () будут считывать нажимаемые игроком клавиши, формировать вектор направления и скорости передвижения игрока и двигать его. Теперь весь написанный код выглядит так:

using UnityEngine;

public class FPCharacter: MonoBehaviour

{

public float speed = 2.0f;

public float speedfast = 50.0f;

public float gravity = -9.8f;


CharacterController CharControl;

float _speedfast;


void Start ()

{

CharControl = GetComponent <CharacterController> ();

}


void Update ()

{

if (Input.GetKey (KeyCode. LeftShift))

{

_speedfast = speedfast;

}

else

{

_speedfast = 1;

}


float offsetX = Input.GetAxis («Horizontal») * speed * _speedfast;

float offsetZ = Input.GetAxis («Vertical») * speed * _speedfast;

Vector3 movement = new Vector3 (offsetX, 0, offsetZ);

movement = Vector3.ClampMagnitude (movement, speedfast);

movement. y = gravity;

movement *= Time.deltaTime;

movement = transform.TransformDirection (movement);

CharControl.Move (movement);

}

}

Сохраним наш сценарий и переключимся в редактор Unity3d.

Делаем PC игру вместе

Подняться наверх