Unity — Движение персонажа по вектору камеры (3D)

unityДолго-долго откладывалась эта тема для публикации, но сейчас было накоплено уже немеренно материала, которым будет интересно поделиться. Тема этой статьи «Движение персонажа по вектору камеры» или «Движение персонажа «куда смотрит камера»». Сам очень долго искал материалы на эту тему и решил начать именно с нее, так как потратил достаточно много времени и в итоге все равно пришлось брать несколько решений и адаптировать под свои нужны. Сразу скажу, статей будет много. Это инди-проект по разработке игры. Сама по себе концепция простая, но делался он для получения опыта. Проект написан не на var-ах и хорошо прокомментирован. Хотелось сделать хорошо настолько, насколько позволяли представления о игростроении. Язык использовался — C#/C Sharp.

Движение персонажа по вектору камеры в Unity.

Для начала давайте определимся с системой. Она должна работать по следующему принципу:

  1. W,A,S,D направляют персонажа вперед/влево/назад/вправо относительно вектора камеры. То есть куда бы не смотрела камера, персонаж при нажатии клавиш двигался в соответствующих направлениях.
  2. В своем проекте я хотел, чтобы физика принимала непосредственное участие в передвижении персонажа, поэтому в систему передвижения необходимо, чтобы персонаж учитывал предыдущее направление движения, чтобы создавать ощущение применения усилия.
  3. При нажатии клавиш W/A, S/A, W/D, S/D — персонаж двигался по диагонали относительно вектора камеры.
  4. В прыжке, нажатие клавиш так же учитываться.
  5. Если в прыжке не нажата ни одна клавиша, персонаж прыгает просто вверх.
  6. Должно учитываться условие «на земле ли персонаж».
  7. Так же, я не хочу, чтобы у игрока была возможность передвигаться после надписи «Game Over», в случае проигрыша.

Итак, что мы сделали: составили техническое задание с проработанной логикой движения и применение физики для персонажа. Прежде, чем браться за задачу — ее нужно описать. Далее — если все то, что тут написано, вам необходимо — начинаем кодить. Кстати, учтем, что персонаж должен обладать скоростью передвижения. Это важно, т.к. это отдельная переменная, участвующая в расчетах остальных формул.

Окей, свои «хотелки» мы описали. Поехали:

Теперь давайте разбираться.

В методе Start():

Инициализируются стандартные значения, а именно:

  1. Персонаж на земле.
  2. rb — эта переменная получает компонент Rigid Body из объекта Player.
  3. Игра не проиграна.
  4. Скорость 300.
  5. Остальные переменные отвечают за флаг движения в любом из четырех направлений.

В методе Update() проверяется значение нажатой клавиши (W,A,S,D), так же проверяется флаг проиграна ли игра и далее начинается что-то странное скажите вы… Но нет, проверяется далее значение «на земле ли персонаж». Если значение «true», то к компоненту rb (RigidBody) применяется физическая сила.

«MainCamera.transform.forward/right» — отвечает за определение вектора взгляда камеры.
«speed» — скорость.
«Time.deltaTime» — отвечает за плавность (так как все применяется не в 1/1000 секунды, а сила применяется каждую секунду, плавно и красиво.

Далее мы видим, что проставляется флаг движения, но он относится к прыжкам, которые появятся в следующей статьей. Дальше идет else, который сообщает, что делать, если физическое тело находится не на земле. Соответственно в попытках применить физическую силу на тело ничего не произойдет — потому что такова логика, вектор по нулям — rb.AddForce(0f, 0f, 0f); (Важно: это не ОФ, а ноль и латинская ЭФ)

После чего скобочки и занавес… Вешаете этот скрипт на персонажа. У вас должно в Unity Inspector (правая панель с компонентами, текстурами и т.д.) в окне со скриптом появиться 2 новых поля с названиями: Main Camera и Player. Камеру и персонажа аттачите в соответствующие поля. Далее можно проверять работоспособность кода в плеере. Можете брать этот код и адаптировать под свои нужды. В одной из следующих статей по Unity, я опишу скрипт, который заставляет камеру двигаться за спиной вашего персонажа, она будет такой второй частью или продолжением. Надеюсь, что для вас данная статейка была полезна. Буду искренне рад, если внизу увижу много фидбэка 🙂

Подписывайтесь на нашу группу в ВК и канал Youtube! Большое спасибо за внимание!

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

Поделиться в соц. сетях:

Понравилась статья? Поблагодари автора, накорми печеньками! :)

7 комментариев

  1. Не работает ничерта. Пытался сделать движение вперёд относительно камеры. На самом деле, мне другое нужно: чтобы модель поворачивалась лицом в разных направлениях относительно камеры. Движение — уже после поворота, чтобы чар не ходил задом наперёд и боком. Декларировал переменные speed, rb, Player и MainCamera. Заассайнил в старте спид. Привязал скрипт к плейеру и добавил к нему ригидбади. Вставил камеру в переменную мейнкамера скрипта и свою модель в переменную плейер. Модель(в моём случае пока куб) не двигается. В апдейте прописал:

    if (Input.GetKey (KeyCode.W)) {
    rb.AddForce(camera.transform.forward * speed * Time.deltaTime);
    }

    Привязывать скрипт нужно было не к модели? Тогда к чему?

    • Добрый день. Тогда вам нужно написать функцию, которая будет проверять направление модели (взгляда) и направление камеры. Соответственно так же в этой функции должен быть кусок, который будет в случае изменения вектора камеры, менять вектор направления модели, чтобы модель поворачивалась в соответствии с вектором камеры. Функцию запихнуть в update.

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

  2. error CS0116: A namespace cannot directly contain members such as fields or methods
    можете подсказать в чем проблема?
    ни на одном форуме не нашел решение этой проблемы (ps может плохо искал)

    • Двойным кликом по ошибке — вас должно переместить на строку, в которой зафиксирована ошибка, пришлите ее пожалуйста сюда. А вообще ошибка указывает на то, что у вас есть переменные или методы, которые вы пытаетесь напрямую использовать из других скриптов.

  3. Не работает пишет ошибка я кликнул 2 раза меня не переместло на ту строку!

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