Скриптинг в Unity: переменные, input и первый скрипт

Создание сценариев — неотъемлемая часть даже самых простых игр. Эти небольшие части кода работают сообща, чтобы делать самые разные вещи: от перемещения персонажа по экрану до отслеживания вашего инвентаря. Разработчики игр пишут сценарии в Unity на C#, мощном объектно-ориентированном языке программирования, разработанном Microsoft около 2000 года. С тех пор он стал одним из самых популярных языков программирования. Команда Unity выбрала C # в качестве основного языка программирования, потому что он хорошо документирован, прост в изучении и достаточно гибок.

В основе Unity лежит хорошо документированный API, с которым могут взаимодействовать скрипты. В этом руководстве вы создадите простую игру, начав с нескольких моделей и изучите как использовать наиболее важные части Unity API. Вы узнаете, как создавать сценарии C# в Unity:

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

Введение

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

Обратите внимание на окно Project и разверните папку RW. Этот проект содержит в себе набор готовых ассетов, которые вы будете использовать, чтобы вдохнуть жизнь в игру с помощью скриптов:

Разберем содержимое папки Assets:

  • Materials: общий материал, используемый всеми моделями для оптимальной работы;
  • Models: некоторые модели варьируются от небольших дымовых облаков до больших наземных моделей;
  • Music: фоновая музыка для игры;
  • Prefabs: набор готовых префабов, предназначенный для того, чтобы упростить внесение изменений в GameObject, присутствующих в сценах;
  • Scenes: игра и заглавная сцена;
  • Scripts: Пусто! Здесь вы разместите сценарии, которые будете создавать;
  • Sounds: несколько 8-битных звуковых эффектов;
  • Sprites: одна таблица спрайтов для некоторых небольших элементов пользовательского интерфейса;
  • Textures: одна текстура, которая используется общим материалом.

Теперь откройте сцену Game в RW/Scenes, если она еще не открыта, и посмотрите вокруг в режиме сцены

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

Краткий обзор GameObjects:

  • Music: источник звука, воспроизводящий счастливую мелодию в цикле;
  • Main Camera: камера, которая направлена ​​вниз на сцену, чтобы обеспечить хороший обзор;
  • Directional Light: единственный источник света, имитирующий солнце;
  • Scenery: этот GameObjects удерживает землю и ветряные мельницы;
  • Hay Machine: это синяя вагонетка, стоящая на рельсах. Он состоит из нескольких GameObject, чтобы облегчить настройку в дальнейшем.

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

Единственные признаки жизни на данный момент — частицы дыма, вылетающие из вагонетки. В ближайшее время эта игра не выиграет ни одной награды за игру года, но это хорошая основа для дальнейшего развития.

Нажмите кнопку воспроизведения еще раз, чтобы остановить тестирование «игры».

Теперь, когда вы знакомы с проектом, пора приступить к написанию сценариев!

Первый скрипт

Создавать новые скрипты в Unity довольно просто. Щелкните правой кнопкой мыши папку RW/Scripts, выберите Create ►C# Script и назовите сценарий Rotate.

Теперь Unity создаст и немедленно скомпилирует голый скрипт MonoBehaviour.

Хотя сценарий еще ничего не делает, вы уже можете использовать его как компонент, прикрепив его к GameObject. В этом случае скрипт Rotate будет вращать колеса всех ветряных мельниц.

Компоненты — это экземпляры скриптов, что означает, что вы можете добавить столько компонентов к любому GameObject, сколько захотите. Любые изменения, внесенные в сценарий, отразятся на всех его компонентах.

Разверните Scenery в Иерархии, чтобы раскрыть его содержимое. Откройте Windmill в редакторе префабов, щелкнув стрелку рядом с ее названием.

Выберите Wheel, который наследуется от Windmill. Теперь нажмите кнопку «Add Component» в нижней части инспектора, начните вводить «rotate», пока в списке не появится компонент Rotate, и выберите его.

Это добавит компонент Rotate к колесам всех ветряных мельниц.

Чтобы отредактировать скрипт, вам нужно открыть его в редакторе кода, например, Visual Studio. Есть несколько способов открыть скрипт, но самый простой — найти исходный файл в окне «Project» и дважды щелкнуть его. Двойной щелчок по полю Script любого компонента также работает:

Используйте любой из описанных выше методов, чтобы открыть скрипт Rotate в редакторе кода. Вот как это выглядит в Visual Studio:

Сам скрипт представляет собой единый класс, производный от MonoBehaviour, базового класса Unity, от которого должны быть унаследованы все скрипты, если их нужно использовать в качестве компонентов.

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

Функции — это другое название методов, все они являются подпрограммами. В языках ООП, таких как C#, вам следует использовать термин «метод», но Unity предпочла вместо этого использовать функцию при описании большинства своих встроенных методов.

Unity добавляет Start и Update методы по умолчанию для всех новых сценариев. На самом деле это функции событий, они вызываются, когда их запускает определенное действие. Вот несколько наиболее распространенных функций обработки событий и времени их вызова:

  • Start: при первой инициализации компонента;
  • Update: каждый кадр;
  • OnEnable: когда компонент включен (повторно);
  • OnDestroy: когда компонент уничтожен.

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

Добавьте следующую строку внутри Update:

transform.Rotate ( 0 , 50 * Время.deltaTime, 0 );

Эта единственная линия, которая постоянно вращается по оси Y с течением времени, уже демонстрирует некоторые возможности Unity API:

  • transform является унаследованным свойством MonoBehaviour. Оно возвращает преобразование GameObject, к которому прикреплен компонент. Класс transform позволяет считывать и изменять положение, поворот и масштаб GameObject.
  • Rotate является одним из общедоступных методов класса Transform, одна из его сигнатур используется здесь для передачи поворота в градусах по осям X, Y и Z соответственно.
  • Значение, переданное для оси Y, равно 50 * Time.deltaTimeTime.deltaTime является частью UnityEngine пространства имен и возвращает время в секундах между последним и текущим кадром. Это значение может меняться со временем независимо от частоты кадров. По сути, это предотвращает замедление движения объекта на медленных устройствах и в гиперрежим на более быстрых. Умножение значения Time.deltaTime на 50 означает, что вы хотите, чтобы значение увеличивалось на 50 в секунду. В данном случае это поворот на 50 градусов по оси Y в течение секунды.

Поскольку эта строка была добавлена внутри Update, она запускается каждый кадр, пока компонент включен. Это приводит к плавному и постоянному вращению.

Редактор Unity использует углы Эйлера для изменения поворота GameObject — это знакомые оси X, Y и Z. На самом деле движок Unity внутренне использует кватернионы, которые состоят из значений X, Y, Z и W. Эти значения очень сложно интерпретировать и не предназначены для прямого использования.

Сохраните этот сценарий и вернитесь в редактор.

Можно заметить, что редактор не будет отвечать в течение короткого времени во время компиляции. Вы можете проверить, когда происходит эта компиляция, посмотрев в нижний правый угол редактора, там будет небольшой анимированный значок:

Если вы еще не вышли из режима редактирования префаба, сделайте это сейчас, щелкнув стрелку влево рядом с префабом Windmill в окне иерархии. Вам будет предложено сохранить или отменить. Щелкните Save.

Теперь посмотрим в сцену. Вы заметите, что колесо ветряной мельницы теперь медленно вращается, так что все идет по плану.

Переменные

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

Откройте скрипт Rotate в редакторе кода и добавьте следующую строку прямо над методом Start:

public Vector3 rotationSpeed;

Эта переменная задаст скорость и ось, по которой будет происходить вращение.

Public является модификатор доступа и означает, что эта переменная будет доступна редактору и другим классам.
Vector3 — это структура, в которой хранятся значения X , Y и Z, Vector3 может использоваться для передачи положения, поворота или масштаба GameObject.

Теперь заменим эту строку:

transform.Rotate ( 0 , 50 * Время.deltaTime, 0 );

На эту:

transform.Rotate (RotationSpeed ​​* Time.deltaTime);

Скорость вращения теперь передается в метод Rotate с помощью переменной, что упрощает ее изменение. Векторы могут быть умножены на переменные с одним типом значения, например, deltaTime для изменения всех включенных значений вектора сразу. Например, Vector3 со значением (X: 1, Y: 2, Z: 3), умноженное на floatсо значением 3, приведет к результату Vector3 со значением (X: 3, Y: 6, Z: 9).

Всегда выбирайте переменную вместо сферического числа в ваккуме, такого как 50, которые вы добавили ранее. Это позволит вам изменять и повторно использовать значения, не открывая скрипт.

Теперь сохраните сценарий и вернитесь в редактор. Откройте префаб Windmill из Иерархии, как вы делали раньше, и снова выберите GameObject Wheel .

Взгляните на инспектор, у компонента Rotate теперь есть поле, которое вы можете настроить:

Измените значение Y в поле Rotation Speed на 120 и выйдите из редактирования префаба, щелкнув стрелку в верхнем левом углу Иерархии, сохранив свои изменения при появлении запроса.

Теперь посмотрим в сцену. Колесо вращается как и раньше, но чуть быстрее.

Огромным преимуществом наличия переменных в редакторе является то, что вы можете изменять их в режиме воспроизведения! Выберите колесо одной из ветряной мельницы в иерархии и попробуйте изменить скорость вращения. Вы можете перемещать значение Y слева направо или изменять число напрямую.

Это приведет к тому, что колесо изменит свою скорость в реальном времени:

После выхода из режима воспроизведения все значения, которые вы установили для GameObjects в иерархии, будут сброшены. Это отличный способ поиграть со значениями и посмотреть, что работает лучше. Вы можете настроить высоту прыжка персонажа, количество здоровья вражеских игроков или даже расположение элементов пользовательского интерфейса.

Конечно, как только вы найдете нужные значения, вы можете сохранить их, чтобы они применялись каждый раз при запуске игры. Самый надежный способ сделать это — скопировать и вставить значения в компоненты и использовать префабы.

Находясь в режиме воспроизведения, измените вращение одного из колес на такое, какое, по вашему мнению, выглядит хорошо, например, на 150 по оси Y. Теперь щелкните правой кнопкой мыши на имя компонента Rotate в Инспекторе или щелкните левой кнопкой мыши шестеренку параметров в правом верхнем углу компонента и выберите Copy Component. Это скопирует компонент и его значения в буфер обмена.

Далее остановите режим воспроизведения. Вы заметите, что скорость в инспекторе вернется к своему прежнему значению. Щелкните правой кнопкой мыши на имя компонента Rotate и выберите Paste Component Values. Все значения, которые вы скопировали, теперь вставятся в компонент Rotate.

Хотя это изменило скорость вращения одной из ветряных мельниц, вы хотите применить это ко всем. Для этого выберите родительский компонент Windmill и в верхней правой части инспекторав ыберите Overrides ► Apply All, чтобы применить изменения ко всем ветреным мельницам.

Ввод игрока и создание экземпляров префабов

Игра не была бы игрой, если бы не требовала определенного участия в ней игрока. Скрипты могут получить состояние клавиатуры, мыши и любых подключенных девайсов. Первая цель — заставить вагонетку двигаться по рельсам слева направо.

Движение

Создайте новый сценарий C # в RW/Scripts , назовите его HayMachine и откройте его в редакторе кода.

Добавьте следующие переменные прямо вверху Start:

public float movementSpeed;

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

Теперь добавьте этот метод ниже Update:

private void UpdateMovement()
{
    float horizontalInput = Input.GetAxisRaw("Horizontal"); // 1

    if (horizontalInput < 0) // 2
    {
        transform.Translate(transform.right * -movementSpeed * Time.deltaTime);
    }
    else if (horizontalInput > 0) // 3
    {
        transform.Translate(transform.right * movementSpeed * Time.deltaTime);
    }
}

Этот фрагмент кода перемещает вагонетку, используя горизонтальный ввод игрока:

  1. Получите ввод горизонтальной оси с помощью класса Input и сохраните его в horizontalInput. Класс Input содержит все методы для опроса устройств ввода. GetAxisRaw возвращает текущее значение ввода, как определено в диспетчере ввода для горизонтальной оси:

В этом случае вы можете использовать клавиши со стрелками влево и вправо, клавиши A и D или левый аналоговый джойстик в качестве входа.

  1. Если horizontalInput меньше 0, это означает, что было обнаружено движение влево по оси X. В этом случае, произойдет движение вагонетки влево со скоростью movementSpeed в секунду.
  2. Если вместо этого horizontalInput больше 0, движение вагонетки произойдет вправо.

Когда Unity не обнаруживает никаких входных данных, horizontalInput будет оставаться на 0 и вагонетка двигаться не будет.

Теперь, чтобы вызывать метод в каждом кадре, добавьте вызов к нему в Update:

UpdateMovement();

Затем сохраните этот сценарий и вернитесь в редактор. Выберите Hay Machine в иерархии и добавьте к нему компонент Hay Machine.

Установите его Movement Speed на 14 и воспроизведите сцену. Используйте клавиши со стрелками или A и D для перемещения вагонетки слева направо. Работает!

Упс, вы можете переместить машину за пределы рельсов и даже за экран, а это нехорошо. Вам нужно будет установить некоторые границы, чтобы этого не происходило.

Снова откройте скрипт HayMachine и добавить эту переменную ниже других:

public float horizontalBoundary = 22;

Эта переменная будет использоваться для ограничения движения по оси X. В качестве значения по умолчанию ему присваивается 22, это будет начальное значение, которое также будет заполнено в редакторе.

Теперь отредактируйте  UpdateMovement оператор if-else, чтобы он использовал границу при проверках:

if (horizontalInput < 0 && transform.position.x> -horizontalBoundary) // 1
{
    transform.Translate (transform.right * -movementSpeed ​​* Time.deltaTime);
}
else  if (horizontalInput> 0 && transform.position.x <horizontalBoundary) // 2
{
    transform.Translate (transform.right * motionSpeed ​​* Time.deltaTime);
}

Вот что поменялось:

  1. Мало того, что горизонтальный ввод должен быть отрицательным, прежде чем разрешить движение влево, положение X вагонетки также должно быть больше, чем отрицательное значение horizontalBoundary.
  2. Чтобы переместиться вправо, горизонтальный ввод должен быть положительным, а положение вагонетки по оси X должно быть меньше, чем horizontalBoundary.

Изображение ниже более наглядно иллюстрирует происходящее:

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

Сохраните скрипт и вернитесь в редактор. Попробуйте воспроизвести сцену и еще раз переместить вагонетку влево и вправо. Вагонеткаа останавливается, как только она перемещается к одному из краев.

Создание и стрельба снарядами

Прежде чем вы сможете начать что-либо запускать, вам нужно создать GameObject для стога сены. Начните с создания нового пустого GameObject в иерархии, щелкнув правой кнопкой мыши на пустое пространство и выбрав Create Empty. Это создаст пустой GameObject с именем GameObject в корне иерархии.

Не снимая выделения с пустого GameObject, измените его имя на Hay Bale в инспекторе и сбросьте его компонент Transform, щелкнув правой кнопкой мыши компонент Transform и выбрав Reset.

Теперь добавьте 3D-модель в Hay Bale, перетащив модель Hay Bale из RW/Models на Hay Bale в иерархии. Не снимая выделения с модели Hay Bal , назовите ее Hay Bale Model и сбросьте ее Tranform. Теперь вы увидите стог сена, твердо посаженное в землю, как в окне сцены, так и в окне игры.

Затем выберите Hay Bale и добавьте следующие компоненты с помощью кнопки  Add Component:

  • Box Collider
  • Rigidbody
  • Rotate

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

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

Для начала установите флажок Is Trigger на Box Collider, чтобы тюк не мог толкать твердые тела. Затем установите флажок Is Kinematic на его Rigidbody, чтобы сено не провалилось сквозь землю. Наконец, установите Rotation Speed в Rotation на (X: 300, Y: 50, Z: 0) .

Сохраните сцену и нажмите кнопку воспроизведения. Вы увидете, что сено крутится на месте.

Чтобы сено двинулось вперед, вам нужно написать еще один служебный скрипт. Создайте новый сценарий C# в RW/Scripts, назовите его Move и откройте его в редакторе кода.

Добавьте следующие объявления переменных в начало класса прямо над методом Start:

public Vector3 movementSpeed; //1
public Space space; //2

Вот для чего они нужны:

  1. Присоединенный GameObject будет двигаться со скоростью в метрах в секунду по осям X, Y и Z.
  2. Пространством движения будет являться World или Self. World пространство перемещает GameObject в пространстве Unity, не обращая внимания на вращение GameObject, в то время как Self считает вращение GameObject в своих расчетах.

Теперь добавьте следующее Update:

transform.Translate(movementSpeed * Time.deltaTime, space);

Это то, что на самом деле перемещает GameObject с помощью translation, это геометрический термин, который означает преобразование точки на расстояние в заданном направлении. По сути, это означает перемещение GameObject в контексте Unity.

Метод Translate принимает два параметра: первое направление и скорость, в то время как второе — пространство, в котором происходит движение. Движение умножается на Time.deltaTime, чтобы выполнить плавное движение в течение определенного периода времени.

Сохраните этот скрипт и вернитесь в редактор. Добавьте компонент Move в Hay Bale, установите его Movement Speed на (X: 0, Y: 0, Z: 20) и оставьте в Space выбор World.

Теперь включите сцену, и вы увидите, что тюк сена летит к мостам и исчезает с экрана, отлично!

Перетащите Hay Bale в папку RW/Prefabs, чтобы превратить его в префаб, и удалите оригинал из иерархии. Теперь вы сможете ссылаться на этот префаб, чтобы создавать больше, когда захотите.

Чтобы вагонетка выбрасывала тюки, вам нужно написать скрипт. Откройте скрипт HayMachine и добавьте следующие объявления переменных прямо вверху Start:

public GameObject hayBalePrefab; // 1
public Transform haySpawnpoint; // 2
public float shootInterval; // 3
private float shootTimer; // 4

Вот краткое объяснение переменных:

  1. Ссылка на префаб Hay Bale .
  2. Точка, в которой будет появляться сено.
  3. Наименьшее время между выстрелами. Это не даст игроку спамить кнопку стрельбы и заполнить экран тюками сена.
  4. Таймер, который постоянно уменьшается, чтобы отслеживать, может ли вагонетка стрелять или нет.

Теперь добавьте метод ShootHay ниже UpdateMovement:

private void ShootHay()
{
    Instantiate(hayBalePrefab, haySpawnpoint.position, Quaternion.identity);
}

Метод Instantiate создает экземпляр заданного префаба или GameObject и помещает его в сцену. Он принимает три параметра: префаб или GameObject, позицию и поворот. В этом случае ссылка на префаб Hay Bale используется для создания экземпляра с начальной позицией, такой же, как у haySpawnpoint Transform . Quaternion.identity используется для поворота, это значение поворота по умолчанию и аналогично тому как  Vector3.Zero устанавливает поворот на (X: 0, Y: 0, Z: 0).

Чтобы вызвать приведенный выше код, вам понадобится код для запроса ввода. Добавьте следующий метод чуть выше ShootHay:

private void UpdateShooting()
{
    shootTimer -= Time.deltaTime; // 1

    if (shootTimer <= 0 && Input.GetKey(KeyCode.Space)) // 2
    {
        shootTimer = shootInterval; // 3
        ShootHay(); // 4
    }
}

Вот что делает этот блок кода:

  1. Вычтите время между предыдущим и текущим кадрами shootTimer, это будет уменьшать его значение на 1 каждую секунду.
  2. Если значение shootTimer равно или меньше 0 и нажата клавиша пробела…
  3. Сбросьте таймер.
  4. Стреляйте в тюк сена!

Наконец, добавьте эту строку Update прямо под UpdateMovement();:

UpdateShooting();

Это вызывает метод в каждым кадре.

Теперь сохраните этот скрипт и вернитесь в редактор. Выберите Hay Machine в иерархии, разверните его, щелкнув стрелку слева, и посмотрите в инспектор.

Новые общедоступные переменные, которые вы только что добавили, стали полями, которые можно назначать. Перетащите Hay Bale из RW/Prefabs на слот Hay Bale Prefabe, перетащите Hay Spawnpoint на слот Hay Spawnpoint и установить Shoot Interval 0,8.

Теперь сохраните сцену и нажмите кнопку воспроизведения. Перемещайте вагонетку с помощью клавиш со стрелками и стреляйте сеном с помощью клавиши пробела!

Все должно работать как на GIF-изображении выше.

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

Теги и реакция на физику

Чтобы идентифицировать типы GameObject, вы можете использовать теги. Теги — это справочные слова, такие как «Player» или «Collectible», которые вы можете назначить GameObjects, чтобы легко их находить и отличать от других GameObject. В качестве тега можно использовать любое слово или короткое предложение.

Создать новый тег довольно просто: выберите Edit ► Project Settings в верхнем меню и откройте вкладку Tags and Layers в окне Project Settings. Теперь разверните список Tags, и вы заметите, что в проекте уже есть два предварительно загруженных тега : DestroyHay и DropSheep.

Нажмите кнопку «+» под списком «Tags» , назовите новый тег «Hay» и нажмите кнопку «Save» , чтобы добавить этот новый тег в список.

После добавления тега Hay закройте окно нProject Settings и выберите Hay Bale в папке RW /Prefabs . Откройте раскрывающееся меню Tag под полем имени и выберите Hay.

Теперь разница между тюками сена и другими игровыми объектами очевидна: вы можете добавить область, которая разрушает сено при соприкосновении с ним. Добавьте новый пустой GameObject в иерархию и назовите его Triggers. Сбросьте его Transform и добавьте пустой GameObject в качестве его дочернего элемента. Назовите его Hay Destroyer.

Выберите Hay Destroyer, установите его положение на (X: 0, Y: 4, Z: 68) и добавьте к нему Box Collider. Проверьте флажок на Box Collider и установите его размер в (X: 60, Y: 8, Z: 12) . Затем измените тег Hay Destroyer на DestroyHay. Теперь вы должны увидеть огромный коллайдер в форме прямоугольника, появившийся в окне сцены, прямо за пределами поля зрения камеры.

Теперь, чтобы этот триггер уничтожал каждое сено, вам нужно написать еще один служебный скрипт. Создайте новый сценарий C# внутри RW /Scripts, назовите его DestroyOnTrigger и откройте его в редакторе кода. Полностью удалите методы Start и Update и добавьте вместо них это объявление переменной:

public string tagFilter;

Эта строка позволит вам ввести имя любого тега, который уничтожит этот GameObject.

Теперь добавьте этот метод под только что добавленной переменной:

private void OnTriggerEnter(Collider other) // 1
{
    if (other.CompareTag(tagFilter)) // 2
    {
        Destroy(gameObject); // 3
    }
}

Вот что происходит:

  1. OnTriggerEnter — это функция MonoBehaviour, один из специальных методов, вызываемых движком Unity в определенных обстоятельствах. В этом случае вызывается OnTriggerEnter когда GameObject с Rigidbody и Collider входит в область триггера GameObject.
  2. Проверяем, что GameObject, входящий в триггер, имеет тег, определенный в tagFilter.
  3. Уничтожаем GameObject, к которому прикреплен этот скрипт.

Сохраните этот сценарий и вернитесь в редактор. Пришло время его проверить!

Выберите Hay Bale в RW /​Prefabs, добавьте компонент Destroy On Trigger и измените Tag Filter на DestroyHay.

Теперь нажмите кнопку воспроизведения и попробуйте снова. Вы заметите, что любое сено, попавшее в «Hay Destroyer», мгновенно уничтожается.

Скрипты для овец

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

Для начала создайте новый пустой GameObject в иерархии и назовите его Sheep. Сбросьте его Transform , установите его поворот по оси Y на 180 и добавьте Box Collider и Rigidbody. Установите флажок Is Trigger для Box Collider и измените его центр и размер на (X: 0, Y: 1,4, Z: -0,3) и (X: 2,5, Y: 2, Z: 4) соответственно. Наконец, установите флажок Is Kinematic на Rigidbody.

Теперь овца в инспекторе должна выглядеть так:

Теперь перетащите модель Sheep из RW /Models на Sheep, чтобы придать ей визуальные эффекты. Назовите GameObject, который вы только что добавили, Sheep Model, сбросьте его Transform и установите его поворот по оси X на -90, чтобы его голова выходила из земли.

Теперь эта овца готова к написанию сценария!

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

Создайте новый сценарий C# с именем Sheep в RW /​​Scripts и откройте его в редакторе кода.

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

public float runSpeed; // 1
public float gotHayDestroyDelay; // 2
private bool hitByHay; // 3

Вот для чего они нужны:

  1. Скорость бега овцы в метрах в секунду.
  2. Задержка в секундах перед тем, как овца будет уничтожена после удара сеном.
  3. Логическое значение, которое принимает значение true, когда в овцу попало сено.

Разобравшись с этим, добавьте эту строку в Update:

transform.Translate(Vector3.forward * runSpeed * Time.deltaTime);

Это заставляет овцу бежать к своему forward vector (локальной оси Z) со скоростью, установленной в переменной runSpeed.

Затем добавьте этот метод ниже Update:

private void HitByHay()
{
    hitByHay = true; // 1
    runSpeed = 0; // 2

    Destroy(gameObject, gotHayDestroyDelay); // 3
}

Вот суть этого метода:

  1. Устанавливает hitByHay в значение true, чтобы проверить, был ли уже вызван метод, чтобы его не вызывали дважды.
  2. Устанавливает скорость бега на 0, это остановит овцу.
  3. Вы уже видели этот вызов метода, но на этот раз есть дополнительный параметр. DestroyМетод принимает второй параметр, то delay в секундах до того, как GameObject разрушится. В этом случае используется переменная задержки, которую вы добавили выше.

Последняя часть заставляет овцу реагировать на физику, добавляя следующий код:

private void OnTriggerEnter(Collider other) // 1
{
    if (other.CompareTag("Hay") && !hitByHay) // 2
    {
        Destroy(other.gameObject); // 3
        HitByHay(); // 4
    }
}

Вот что он делает:

  1. Этот метод вызывается, когда триггер входит в этот GameObject (или наоборот).
  2. Если объекту GameObject, который попал в этот объект, назначен тег Hay, и овца еще не попала в сено…
  3. Уничтожить другой GameObject (тюк сена).
  4. Вызвать метод HitByHay, который вы добавили перед этим.

На этом пока что все, сохраните сценарий и вернитесь в редактор. Выберите Sheep в иерархии и добавьте компонент Sheep. Установите скорость бега на 10 и задержку уничтожения сена на 1.

Теперь запустите сцену, выстрелите в овцу и посмотрите, что произойдет!

Потрясающие! Овца перестает двигаться и исчезает, как вы и написали. Что произойдет, если овца пробежит мимо, а вы ее не пристрелите? Перезапустите сцену и проверьте это.

Овечка пролетает через край как по волшебству, это нехорошо! Вам нужно будет создать еще одну зону срабатывания, чтобы сценарий Sheep мог обнаруживать столкновения с ней и соответствующим образом реагировать.

Создайте новый пустой GameObject как дочерний для Triggers, назовите его Sheep Dropper и сбросьте его Transform. Установите позицию (X: 0, Y: 4, Z: -54) и добавить флажок Box Collider, размер из (X: 60, Y: 8, Z: 12). Теперь измените его тег на DropSheep, и у вас будет хороший большой триггер позади вагонетки для сена, готовый к использованию.

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

public float dropDestroyDelay; // 1
private Collider myCollider; // 2
private Rigidbody myRigidbody; // 3

Они говорят сами за себя, но вот краткий обзор:

  1. Время в секундах до того, как овца будет уничтожена, когда она выйдет за край и начнет падать.
  2. Ссылка на компонент Collider овцы.
  3. Ссылка на Rigidbody овцы.

Теперь назначьте необходимые ссылки, добавив это в Start:

myCollider = GetComponent<Collider>();
myRigidbody = GetComponent<Rigidbody>();

Это находит и кэширует коллайдер овцы и твердое тело для дальнейшего использования.

Затем необходимо настроить коллайдер овцы, чтобы на него повлияла гравитация. Для этого добавьте этот метод:

private void Drop()
{
    myRigidbody.isKinematic = false; // 1
    myCollider.isTrigger = false; // 2
    Destroy(gameObject, dropDestroyDelay); // 3
}

Этот метод прост:

  1. Делает твердое тело овцы некинематическим, чтобы на него воздействовала сила тяжести.
  2. Отключает триггер, чтобы овца превратилась в твердый объект.
  3. Уничтожает овцу после задержки, указанной в dropDestroyDelay.

Теперь добавьте следующее OnTriggerEnter прямо под существующим оператором if:

else if (other.CompareTag("DropSheep"))
{
    Drop();
}

Если овца была сбита чем-то другим, кроме тюка сена, он проверяет, имеет ли столкнувший коллайдер тег DropSheep; Drop вызывается, если это так.

Теперь сохраните этот сценарий и вернитесь в редактор. Выберите Sheep и измените значение Drop Destroy Delay на 4 .

Снова воспроизведите сцену и позвольте овце пройти мимо вагонетки, чтобы увидеть, что произойдет.

Теперь падает и пропадает, когда игроку не удается в нее попасть. 

Теперь, когда овца действует так, как задумано, перетащите ее из иерархии в папку RW/Prefabs, чтобы превратить ее в префаб и удалить оригинал из иерархии.

Это первая часть этого урока! Похвалите себя, вы узнали основы создания скриптов для реализации игрового процесса в Unity.

Оцените статью
3dgame-creator
Добавить комментарий