Изучите позицию преобразования и изучите простые методы перемещения игровых объектов в Unity.

Ресурсы

Гитхаб: https://github.com/Jerga99/YT-Example-Proj-Unity

Лекция на Youtube: https://www.youtube.com/watch?v=6L9aYyRg3A0

Полный курс: https://academy.eincode.com/courses/the-complete-unity-guide-3d-beginner-to-rpg-game-dev-in-c

Сначала основы

Каждый объект в Unity содержит Transform. Преобразование отвечает за положение, вращение и масштабирование объекта.

Каждый объект, помещенный в сцену Unity, имеет некоторую начальную позицию, вращение и трансформацию.

Объект находится либо в 3D, либо в 2D пространстве, в зависимости от типа проекта. В нашем случае мы будем работать над 3D-проектом.

Давайте рассмотрим пример объекта Capsule, расположенного в трехмерном пространстве.

Центр плоскости расположен в позиции (0,0,0), тогда как точка в трехмерном пространстве определяется тремя значениями, лежащими на оси (X, Y, Z).

Каждая позиция на оси имеет другое значение. Начиная с центрального положения (0,0,0), движение вправо увеличивает значение X, движение вверх увеличивает значение Y и, наконец, движение вперед увеличивает значение Z. Движение в направлении, противоположном упомянутой оси, приводит к уменьшению значения.

Чтобы найти точку в трехмерном пространстве, вам нужно знать все 3 координаты (X, Y, Z).

Теперь давайте посмотрим, где будет располагаться капсула в позиции (1,1,1)

Капсула теперь расположена ровно на 1 метр Unity по оси X, на 1 метр по оси Z и на 1 метр вверх по оси Y. Возможно, вы задаетесь вопросом «Почему капсула 1 метр на Y?»

Итак, у объекта «Капсула» 2 метра, поэтому центр капсулы находится на высоте 1 метр над землей.

Вот почему его нужно разместить на 1 метр по оси Y. В противном случае это было бы полпути тела посередине самолета.

Изменить позицию в коде

Вы можете изменить положение объекта в коде, манипулируя свойством преобразования объекта.

Позиция представлена ​​внутри структурой с именем Vector3. Vector3 содержит 3 значения –> x, y, z

Переместим игровой объект в позицию (1,1,1)

transform.position = new Vector3(1.0f, 1.0f, 1.0f);

Просто как тот!

Это основное, что вам нужно знать о позиции. Помните, что положение — это место в пространстве, представленное значением (X, Y, Z), каждое из которых лежит на своей оси.

Теперь мы собираемся создать функцию для перемещения капсулы, когда игрок нажимает клавиши ввода на клавиатуре.

Сценарий движения

Сначала создайте новый скрипт с именем Movement.cs и добавьте его в объект Capsule.

Мы поместим функцию перемещения в метод Update. Обновление выполняется в течение всего игрового времени — насколько часто это зависит от частоты кадров вашей игры.

Об обновлении

Метод Update вызывается один раз для каждого кадра.

Если игра работает со скоростью 140 кадров в секунду, то обновление вызывается 140 раз в секунду. Это делает его отличным местом для функциональности, которая должна происходить постоянно во время игры.

Обработка ввода игрока обычно представляет собой функцию, размещенную в методе Update.

Захват ввода игрока

Чтобы переместить игровой объект, нам нужно зафиксировать ввод игрока. Если игрок использует в качестве устройства ввода клавиатуру, мы хотим запечатлеть, как он нажимает клавиши со стрелками или клавиши AWSD на клавиатуре.

Для этого мы можем написать следующий код в Update.

void Update() {
  float horizontalInput = Input.GetAxis("Horizontal");
  float verticalInput = Input.GetAxis("Vertical");
  Debug.Log("H-> " + horizontalInput);
  Debug.Log("V-> " + verticalInput);
}

Входные значения обычно находятся в диапазоне от -1 до 1. Попробуйте.

Горизонтальная ось

Горизонтальное значение 0 означает, что НИКАКАЯ клавиша «движения» не нажата.

Значение 1 означает, что игрок нажимает стрелку «вправо» или клавишу «D» (игрок хочет двигаться вправо)

Значение -1 означает, что игрок нажимает стрелку «влево» или клавишу «A» (игрок хочет двигаться влево)

Вертикальная ось

Вертикальное значение 0 означает, что НИКАКАЯ клавиша «движения» не нажата.

Значение 1 означает, что игрок нажимает стрелку «вверх» или клавишу «W» (игрок хочет двигаться вперед)

Значение -1 означает, что игрок нажимает стрелку «вниз» или клавишу «S» (игрок хочет двигаться назад)

Получить значение от 0 до 1 или от 0 до -1, пока пользователь удерживает клавиши перемещения, не произойдет мгновенно, но с настройками Unity по умолчанию это произойдет очень быстро!

Таким образом, удерживая стрелку «вправо» в течение одной секунды, вы можете получить значения в горизонтальном вводе, 0, 0,1, 0,3, 0,5, 0,7, 1, 1, 1, 1… почти мгновенно достигнув 1 значения.

Это просто иллюстративные значения, вы можете получить совершенно другие.

Поскольку мы можем захватить ввод игрока, мы почти готовы к перемещению.

Готов к переезду

Давайте расширим текущую реализацию.

void Update() {
  float horizontalInput = Input.GetAxis("Horizontal");
  float verticalInput = Input.GetAxis("Vertical");
  Vector3 movement = new Vector3(horizontalInput, 0, verticalInput);
  transform.Translate(movement);
}

Мы переезжаем!

Вы заметите одну вещь. Мы движемся слишком быстро.

Во-первых, давайте объясним код выше.

Мы храним значения по вертикали и горизонтали в структуре Vector3, чтобы применять их для изменения положения игрового объекта.

Как я упоминал ранее, у каждого игрового объекта есть позиция, представленная значением (X, Y, Z).

Нам нужно применить это изменение положения в форме Vector3, а затем предоставить его методу Translate. Метод Translate перемещает игровой объект в направлении и на расстояние перевода.

Представьте себе эти 3 случая:

Объект будет двигаться вправо, когда игрок удерживает стрелку «вправо» или «D», потому что Vector3 содержит значение (1,0,0), которое выражает изменение в направлении оси X.

Объект будет двигаться вперед, когда игрок удерживает стрелку «вверх» или «W», потому что Vector3 содержит значение (0,0,1), которое выражает изменение направления по оси Z.

Объект будет двигаться по диагонали, когда игрок удерживает стрелку «вверх» или «W» одновременно со стрелкой «вправо». или клавишу «D», потому что Vector3 содержит значение (1,0,1), которое выражает изменение направления по осям X и Z.

Эти изменения применяются к текущему положению игрового объекта. Вы можете думать об игровом объекте как о центре плоскости.

Почему объект движется быстро?

Игровой объект движется быстро, потому что Update вызывается много раз в секунду. Представьте, что стабильная частота кадров (FPS) равна 50. 50 FPS означает, что ваша игра обновляется 50 раз в секунду, поэтому Update вызывается 50 раз в секунду.

Это также означает, что удержание клавиш ввода в течение 1 секунды приведет к выполнению 50 операций.

Vector3 movement = new Vector3(horizontalInput, 0, verticalInput);
transform.Translate(movement);

поэтому, если бы Vector3 был (1,0,0), я бы каждую секунду перемещался на 50 метров вправо, потому что Update вызывается 50 раз в секунду.

Наша функциональность зависит от фрейма. Чтобы двигаться только на 1 метр в секунду, нам нужно уменьшить значение движения.

Дельта времени

Во-первых, обновление переводится так

transform.Translate(movement * Time.deltaTime);

Если вы будете играть в игру сейчас, вы заметите, что движение зафиксировано, и вы двигаетесь красиво и медленно.

Дельта времени – это время завершения последнего кадра в секундах.

Опять же, представьте себе стабильную частоту кадров 50 кадров в секунду. Время завершения каждого кадра будет 0,02 секунды, потому что 50 * 0,02 = 1 секунда.

Если вы умножите движение на 0,02, вы уменьшите его значение, если это произойдет 50 раз в секунду, тогда Vector3 (0,0,1) применит движение на 1 метр в секунду.

Теперь функциональность механизма зависит от времени. Вы будете часто использовать Time.deltaTime.

Окончательные улучшения

Если движение слишком медленное, умножьте движение на более высокое значение. Допустим, вы хотите, чтобы капсула двигалась со скоростью 6 метров в секунду.

Vector3 movement = new Vector3(horizontalInput, 0, verticalInput);
transform.Translate(movement * 6.0f * Time.deltaTime);

Вот и все.

Теперь окончательный код.

void Update() {
  float horizontalInput = Input.GetAxis("Horizontal");
  float verticalInput = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(horizontalInput, 0, verticalInput);
  movement.Normalize();
  transform.Translate(movement * 6.0f * Time.deltaTime);
}

Вы можете заметить, что я вызвал метод Normalize для движения. В случае диагонального движения вы будете двигаться быстрее. Normalize «исправит» это, и движение будет одинаковым во всех направлениях.

Я более подробно объясняю Normalize в другом моем видео на Youtube: https://www.youtube.com/watch?v=oCU8Ew1XTbs&t=3s.

Резюме

Теперь у вас должно быть общее представление о том, как перемещать игровой объект в Unity. Все дело просто в изменении положения через какой-то промежуток времени.

Обязательно проверьте и другие ресурсы:

Гитхаб: https://github.com/Jerga99/YT-Example-Proj-Unity

Лекция на Youtube: https://www.youtube.com/watch?v=6L9aYyRg3A0

Полный курс: https://academy.eincode.com/courses/the-complete-unity-guide-3d-beginner-to-rpg-game-dev-in-c

Ваше здоровье,

Филип