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

Создание префаба врага

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

Враг и Игрок выглядят практически одинаково. Чтобы различить их, к объекту враг будет добавлен материал. Чтобы создать материал, сначала создайте для проекта новую папку под названием Материалы. Просто щелкните правой кнопкой мыши по этой папке и создайте новый материал. Щелкните новый материал и выберите цветное пятно рядом с параметром «Альбедо». Поскольку враги считаются злыми, установите цвет ползунка на красный. Когда этот шаг будет завершен, переименуйте материал «Враг».

Враг почти готов! Чтобы изменить цвет врага, перетащите только что созданный материал на врага. Если все сделано правильно, он должен стать красным. Теперь перетащите вражеский объект из иерархии в папку prefabs.

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

Чтобы создать тег, выберите префаб врага, нажмите на раскрывающийся список тегов и выберите новый тег. Назовите этот тег Enemy и назначьте его префабу врага.

Наконец-то пришло время кодить!

Сценарий врага

Следующее, что нужно сделать, - это создать скрипт врага. Поместите скрипт в папку Scripts и перетащите его на префаб Enemy. Откройте сценарий и удалите методы по умолчанию.

Как и игрок, которого мы создали в Основном руководстве по перемещению игрока, противнику нужно будет двигаться. Поэтому перед запуском ему потребуются некоторые переменные. Одна переменная будет с плавающей точкой с именем _spd со значением 1.0f, а другая - с int с именем _health установлено значение 1. Обе переменные потребуют атрибута [SerializeField].

Затем создайте три метода для нашего врага. Первым будет Update (), за которым следуют EnemyMovement () и EnemyDamage ().

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

Движение врага будет упрощено по сравнению с движением игрока. Направление будет установлено на движение влево со скоростью, с которой он движется. Затем будет вызван метод transform.Translate для фактического перемещения врага. Если требуется более подробное объяснение, ознакомьтесь с этой ссылкой, чтобы увидеть, как движется игрок.

Наконец, противнику нужно будет получить урон. Этот метод будет использовать аргумент. Аргумент обычно представляет собой изменяющееся значение, которое передается в метод. EnemyDamage () принимает в качестве аргумента целое число. Причина этого может заключаться в том, что противник может получить урон от нескольких видов оружия и / или предметов. Урон будет вычтен из здоровья врага, затем, когда оно достигнет нуля, враг уничтожит.

Последнее, что нужно врагу, - это умереть, если он выйдет за пределы экрана. Это можно сделать, проверив, меньше ли текущая позиция x врага в EnemyMovement () определенного значения. Я обнаружил, что -12,5 работает хорошо. Тот же код можно использовать для уничтожения пули. Просто примените его к метке Update () пули. Убедитесь, что значение указано для правой стороны экрана!

Создать диспетчер появления

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

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

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

Как обычно, первое, что нужно сделать, это создать переменные, которые нам понадобятся, чтобы начать порождать врагов. В этом случае переменными будут: Vector3 с именем _spawnPos для генерации случайной позиции нереста; Переменная SerializeField GameObject с именем _enemies для хранения врага, который должен появиться; Переменная Player с именем _player для связи с объектом игрока; Наконец, переменную _spawnTimer WaitforSeconds, чтобы повысить производительность игры.

Идея SpawnManager состоит в том, чтобы порождать врагов в случайном месте, пока игрок жив. Имея эту информацию, мы можем добавить несколько методов. Первый из них - Start (). Здесь можно инициализировать объект проигрывателя, а значение _spawnTimer можно установить на две с половиной секунды. Последнее, что нужно сделать, это проверить, существует ли объект игрока, если он существует, тогда мы можем порождать врагов. Использование StartCoroutine (SpawnEnemies ()).

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

Чтобы начать использовать эту функцию, создайте другой метод под названием IEnumerator SpawnEnemies (). Первое, что нужно сделать в этой сопрограмме, - дождаться возврата значения таймера. Это будет порождать врагов через определенные промежутки времени. Перед тем, как создать экземпляр врага, должна быть сгенерирована позиция возрождения, при этом позиция будет случайной для каждого врага. Мы можем создать другой метод под названием GenerateSpawnPos () и вызвать его в сопрограмме. Наконец, мы создаем экземпляр врага в сгенерированном _spawnPos без ротации.

В методе GenerateSpawnPos необходимо сгенерировать случайное значение для позиции врага y, чтобы игрок не мог все время разбивать лагерь… никому не нравится кемпер. Для этого локальной переменной с плавающей запятой под названием pos может быть присвоено случайное число в определенном диапазоне. Лучше всего мне подошли значения от -3,5 до 5,5.

Затем _spawnPos можно установить равным новому Vector3, переменная pos - это значение y.

Метод врага OnTriggerEnter ()

Перед последним шагом создайте еще один тег. Тег должен называться Маркер. Назначьте маркер префабу маркера.

Классный метод - OnTriggerEnter (). С помощью этого метода мы можем проверить, не столкнулись ли мы с объектом определенного тега. Если да, то пока просто уничтожим врага. Осторожно! Это будет работать с объектом, только если в компоненте коллайдера установлен флажок Is Trigger.

В этом методе мы можем проверить, равен ли тег другого коллайдера Player или Bullet. Если это так, мы просто уничтожим объекты, чтобы показать, что он работает. . Позже будет реализована более подробная система повреждений.

Ограничить движение игрока

Ограничение передвижения игрока звучит сложно, но на самом деле это не так уж и плохо. Задача будет облегчена с помощью функции Mathf.Clamp ().

Mathf.Clamp () гарантирует, что любые значения, переданные в функцию, ограничивают эти значения между минимальным и максимальным аргументами. Значение, которое необходимо зафиксировать, - это позиция игрока.

Для ограничения x и y могут быть созданы две локальные переменные. Все эти переменные и функция должны вызываться после вызова функции перевода игрока. Причина этого в том, что значения для зажима x и y обновились до положения текущего игрока после того, как игрок переместился. . Затем он может проверить, не превышают ли значения значения ограничения. Если да, то позиция игроков будет обновлена ​​до максимального или минимального значения.

К сожалению, была обнаружена ошибка с перемещением игрока. Это происходит, когда игрок перемещается по горизонтали и вертикали одновременно, и заставляет игрока двигаться быстрее, чем если бы была нажата только одна кнопка. Чтобы решить эту проблему, можно добавить атрибут .normalized к вектору направления игрока. Этот атрибут делает все значения равными 1.

Поздравляю!

Хорошо сделано! Спасибо, что прошли со мной этот урок! Следующим шагом будет повреждение игрока и создание простой системы пользовательского интерфейса.