Содержание всех постов:
- Вступительный пост
- Обучение разработке на Unity3D. Установка, настройка и описание окон
- Обучение разработке на Unity3D. Написание небольшого шутера. Разбираемся с террейном.
- Онлайн-обучение. Урок 3. Разработка игр на Unity3D: создание персонажа
- Онлайн-обучение. Урок 4. Разработка игр на Unity3D: продолжаем создавать персонажей
Всем привет. Сегодня мы разберемся с кодом скрипта Enemy из предыдущего урока:
Начнем с первой строчки: using UnityEngine;
Она означает, что мы хотим использовать в нашем скрипте библиотеку классов и других данных движка Unity. В данном скрипте из движка мы использовали такие типы как MonoBehaviour, GameObject, Vector3 и Rigidbody
, а так же некоторые из их методов и свойств.
Строки 3, 4 и 15 объявляют класс Enemy
, который наследует поведение от MonoBehaviour
.
Строки 6-14 обозначают метод FixedUpdate()
, который и выполняет всю работу по передвижению нашего врага. Это стандартная функция Unity, которую можно использовать в любом классе, который наследуется от MonoBehaviour
. Эта функция выполняется фиксированное количество раз в секунду и используется в основном для рассчета физики.
Строки 8-13 это тело метода. Давайте разберемся что оно делает:
GameObject player = GameObject.FindObjectWithTag("Player");
- поиск объекта с тегом Player на сцене. Если помните, в предыдущем уроке мы присваивали этот тег нашему игроку (FPSController).
Vector3 playerDirection = (player.transform.position - transform.position).normalized;
- здесь мы расчитываем направление к нашему игроку, которого мы нашли в предыдущей строке. В векторной алгебре, как и в Юнити, направление, позиция в пространстве и скорость движения обозначается с помощью вектора. Чтобы рассчитать вектор, который показывает направление от нашего Enemy до игрока, нужно отнять от позиции игрока, позицию Enemy. Что мы и делаем - player.transform.position - transform.position
. На рисунке наглядно видно, что результат - это вектор, который показывает сколько клеток нужно двигаться по оси x (4) и по оси y (2). Все очень просто.
Чтобы использовать вектор направления далее в коде, нужно получить так называемый единичный вектор направления. То есть длина такого вектора равна 1. Для этого мы и берем normalized
.
transform - это как раз и есть тот компонент Transform, который имеет каждый объект на сцене и который содержит в себе позицию, поворот и размер (scale).
GetComponent<Rigidbody>().MovePosition(transform.position + playerDirection*Time.fixedDeltaTime*3f);
.
Здесь мы сначала получаем доступ к компоненту Rigidbody, который висит на нашем Enemy. Делается это с помощью кода GetComponent<Rigidbody>()
.
Далее мы вызываем метод MovePosition
у компонента Rigidbody
, которому нужно передать в какую позицию нужно двигаться.
Эта позиция рассчитывается с помощью кода transform.position + playerDirection*Time.fixedDeltaTime*3f
. Мы берем нашу позицию (позицию Enemy) и добавляем к нему вектор с направлением в сторону игрока (playerDirection). Обычно метод FixedUpdate выполняется 50 раз в секунду и если к позиции Enemy добавлять просто единичный вектор направления, то Enemy настигнет игрока очень быстро. Поэтому и используется переменая Time.fixedDeltaTime
, чтобы уменьшить наш единичный вектор в соответствии с частотой выполнения функции. Псле этого наш Enemy будет за 1 секунду передвигаться на 1 метр. Далее коэффициентом 3 мы увеличиваем эту скорость до 3 метров в секунду.
На этом расчет движения закончен. Теперь нам надо развернуться в сторону игрока. Для начала с помощью кода Quaternion lookRotation = Quaternion.LookRotation(playerDirection);
расчитывается такой поворот, чтобы наш Enemy смотрел в сторону игрока. Далее мы этот поворот присваиваем нашему Enemy через вызов метода MoveRotation.
Это все, что нам было нужно - узнать в какую сторону двигаться, в какую сторону смотреть и задать скорость движения.
Давайте теперь немного оптимизируем наш код. В самом начале метода FixedUpdate мы ищем игрока. И делаем мы это 50 раз в секунду, что не очень то хорошо сказывается на производительности игры. Если такой скрипт всего один, это почти не заметно, а если таких Enemy на сцене будет штук 20, это будет довольно накладно. Вместе они будут искать игрока 1000 раз в секунду. На самом деле нам нужно найти игрока всего один раз на самом старте. Сделаем мы это так:
Все, что мы сделали, это перенесли поиск нашего игрока в метод Start, который тоже является стандартным методом Юнити и вызывается всего один раз при старте сцены. В итоге, если на сцене будет 20 врагов, то игрок будет искаться всего 20 раз при старте сцены, что есть очень хорошо.
Еще мы можем вынести нашу скорость движения так, чтобы ее можно было менять прямо в редакторе Юнити. Давайте это сделаем:
Все, что я сделал, это создал публичную переменную moveSpeed типа float и подставил ее вместо нашей тройки.
Теперь, если мы перейдем в редактор Юнити и выберем наш/наши префабы (Enemy1, Enemy2), то увидим, что у нас в компоненте Enemy появилось дополнительное поле Move Speed, которое мы можем менять прямо в игре, если нужно. Или перед запуском. Вот так это выглядит:
На сегодня все. Можно поэкспериментировать с изменением значения скорости для разных врагов на сцене, добавить 20 и больше врагов и т.д.
В следующем уроке мы научим нашего игрока стрелять, чтобы как-то спасаться от назойливых тыкв.
Всем пока, всем удачи!
Автор поста Алексей, @litovets —
Авторские получил, спасибо
Ваш пост поддержали следующие Инвесторы Сообщества "Добрый кит":
litrbooh, littleboo, vas, max-max, urii, tristamoff, vasilisapor2, olga-olga, semasping, gromozeka, karusel1, sharps, oksana0407, fyyf, vika-teplo, bag, polojayigor, zhenek, mirumir, leminger, amidabudda, xsen, anr, kr-alexey, sansey, alexko, anandasurya
Поэтому я тоже проголосовал за него!
Узнать подробности о сообществе можно тут:
Разрешите представиться - Кит Добрый
Правила
Инструкция по внесению Инвестиционного взноса
Вы тоже можете стать Инвестором и поддержать проект!!!
Если Вы хотите отказаться от поддержки Доброго Кита, то ответьте на этот комментарий командой "!нехочу"
dobryj.kit теперь благодарит за взаимность! - https://golos.id/ru--dobryijkit/@dobryj.kit/vzaimnost
Вчера весь вечер пытался запустить Unity 3D на виртуалке с седьмой виндой - не взлетело. Либо не запускалась среда, либо запускалась, но очень сильно тормозила и в итоге крашилась вся виртуальная машина О_о
Похоже надо на реальном железе винду запускать.
А какая видяха? Возможно нужно аппаратную поддержку видяхи врубить на виртуалке? У меня Юнити на виртуалке MacOS запускается, но работать там конечно невозможно. Но там и поддержки аппаратной нет.
Пишут, что нужно включить поддержку 2D и 3D ускорения, я включил-не помогло. Ещё там с гостевой ОС колдовал, с дописыванием команд в ярлыке запуска.
GeForce GT 610
Я себе на винде даже антивирус не ставил. Уже больше 3 лет стоит 10-ка и все гуд.
Я тоже либо не ставил, либо бесплатный аваст. И это уже 14 лет. Но лучше перебдеть. Если важной инфы на компе нет - то пофиг конечно.
На самом деле я бы не советовал работать в Юнити на виртуалке. Это будет себе дороже - нервные клетки не восстанавливаются. Установи рядом с линухом винду и будет тебе счастье :)
Да, винда стоит даже. Я хочу всё купить терабайт места на яндексе и все личные фото туда закинуть. А то на винду шифровальщик пролезет и покоцает все мои фотки. А я этого не переживу))
Там кроме поддержки 2D и 3D в настройках, надо еще установить гостевые тулзы. Вот тут в видео показывается как это делается.
Если ты юзаешь VirtualBox. Я так понимаю для линуха выбор не богат.
Да,я это делал. После этого Unity стала запускаться, но только главное меню. Рабочая область почти не прогружалась. А вскоре вся виртуалка падала.