Научитесь программированию в Unity
Хотите программировать собственные компьютерные игры? Начните с бесплатных наборов и обучающих материалов по программированию на Unity Learn, а также не забывайте про наше замечательное сообщество.
Unity FPS Microgame
Новички могут загрузить Unity бесплатно и начать с готовых ресурсов Unity Microgame и Mod. Затем углубите знания с помощью обучающих материалов и изучите структуру C#, языка программирования игр в Unity. Научитесь разрабатывать простые скрипты на C# для программирования игрового процесса, механики, визуальных эффектов, систем ИИ и других элементов.
Реализуйте свои способности к программированию в Unity! Это может стать началом вашей успешной карьеры. Unity — самая популярная платформа разработки игр в мире: 50% всех мобильных игр созданы в Unity! Профессия Unity-разработчика находится в первой десятке по росту востребованности в США согласно данным LinkedIn.
Introduction to C# scripting in Unity
Скрипты в Unity разрабатываются на языке C# (произносится как «си-шарп»), который имеет богатые возможности и прост в изучении. Предлагаем вашему вниманию простое и понятное введение в программировании на C# в Unity, которое также включает информацию о базовом синтаксисе языка, то есть о переменных, функциях и классах.
Unity Creator Kit: Code
Наборы Creator Kit — это простые игровые проекты, доступные на Unity Learn. Каждый из них можно изучить и освоить за несколько часов В наборе Creator Kit для начинающих программистов вы познакомитесь с основами разработки скриптов на C# для Unity в контексте игры жанра экшен-RPG.
Create with Code course from Unity
Create with Code — это официальный вводный курс Unity по программированию, содержащий более 37 часов насыщенного образовательного контента. В процессе разработки прототипа, решения задач по программированию и ответов на вопросы вы освоите базовые принципы программирования на примере разработки собственного игрового проекта на C# с нуля.
Другие способы учиться программированию в Unity
Обучающие материалы по программированию на C# в Unity
У нас есть масштабная коллекция коротких уроков, где рассматриваются основы программирования на C# в Unity. Начните с материалов для начинающих, а затем переходите к коллекции для опытных пользователей.
Learn C# from Brackeys
Советуем вам изучить эту серию видеороликов с популярного канала Brakeys на YouTube, где рассматриваются основы разработки скриптов на C# в Unity.
Автор: Jabrils
Разработчик ПО и опытный блогер Jabrils рассказывает на YouTube о том, как он учился программировать, и публикует собственные материалы для начинающих в плейлисте Everything you need to start programming.
Уроки Unity C#
Видеоурок
Полезные ссылки:
Информация про Unity
Unity – это игровой движок, на котором строится большая часть современных игр на разных платформах. Посредством движка реально создавать игры, ориентированные на запуск на компьютерах (Windows, Linux, MacOS), мобильных телефонах, планшетных компьютерах (Android, iOS, Windows Phone) и даже игровых приставках PlayStation, Xbox, Nintendo.
Устанока Unity
Установка Unity является простым процессом. Чтобы установить программу её необходимо скачать с официального сайта и далее установите к себе на компьютер.
Вы можете просмотреть видео по установки Unity ниже:
Разработка игры
Мы изучим как создать свои 2D и 3D игры на Unity. Процесс создания 2Д и 3Д игр на Unity прост. Он разделяется на два этапа:
План курса
За курс мы будем изучать язык C# в связке с игровым движком Unity. Мы изучим базовый синтаксис C# файлов, изучим основные библиотеки, а также поговорим про встроенные Unity функции для манипуляции проектом и объектами в нём.
К концу курсу у вас будет хорошее представление про написание скриптов на Unity при помощи языка C#.
Курсы по Unity разработке
За курс мы с вами учимся прописывать C# Unity код и изучаем в целом построения функционала на основе Unity c#. Эти Unity уроки не описывают полностью весь детальный процесс построения игр. Е сли вы хотите получить больше информации относительно разработки игр на Unity, то рекомендую вам большую программу обучения по Unity.
В ходе программы обучения вы научитесь делать как 2Д, так и 3Д игры на Unity. Игры будут разрабатывать под обе платформы: Андроид и iOS. За программу вы научитесь создавать анимации, дизайн, прописывать скрипты, добавлять рекламу и монетизацию и выполнять публикацию игр в магазины Google Play и App Store.
Установите Unity, а также текстовый редактор для работы со скриптами.
Вступление:
Скажу честно, я не программист, так что вполне возможно будут какие-то неточности. Это не игровой туториал. Я постараюсь рассказать, как работают скрипты в Юнити 3Д.
С# относительно не сложный язык. Точнее сама основа языка простая, сложности начинаются, когда уже совсем далеко углубляешься в него. Но на самом деле с помощью Юнити3Д можно делать простенькие игрушки только используя основы С#. C# объектно ориентированный язык програмирования. Это пишут все, но как я понял большинство не особо понимает смысл этого, как и я. Но учитывая, что придется работать со скриптами, это не так и важно для начала. Не стоит пытаться создать один огромный трудно понимаемый скрипт для всей игры. Пробуйте разделить игру на части. В свою очередь эти части могут взамодействовать друг с другом. Используйте эти части как кирпичи для создания итоговой игры. В C# используется class, который исполняет роль кирпичика. В Юнити довольно просто создать такой class. Создаете новый C# скрипт и называете его по желанию. И, грубо говоря, созданный скрипт и выполняет роль class в Юнити3Д. Далее можно использовать скрипт как компонет для игрового объекта.
Небольшой пример:
Не забываем, это не игровой туториал, только вкратце о принципе работы с Юнити3Д.
using UnityEngine;
using System.Collections;
public class Moving : MonoBehaviour <
// Use this for initialisation
void Start () <
>
//Update is called once per frame
void Update () <
>
>
Например мы хотим переместить астероид в центр при старте игры.
Если надо получить доступ на какой-то компонент игрового объекта, то обычно надо сделать следующие шаги:
1. Найти нужный игровой объект: Тут много разных вариантов, все зависит от условий.
— Можно использовать поиск из C# скрипта GameObject.Find («Name») / GameObject.FindWithTag («Tag»). Это поиск по имени или тэгу.
— можно создать переменную типа игровой объект public GameObject; и потом в эдиторе указать к какому объекту привязана эта переменная.
— можно получить линк на игровой объект с различных функций. Например: (Trigger, Raycast. ).
— и не нужен поиск объекта, если скрипт уже находится на этом объекте.
2. Получить доступ на компонент этого объекта: через команду gameobject.GetComponent (); или GetComponent (); если скрипт на том-же объекте.
Доступ к Transform компоненту:
using UnityEngine;
using System.Collections;
public class Moving : MonoBehaviour <
//Update is called once per frame
void Update () <
>
>
Если мы запустим нашу игру, то астероид будет перемещён в центр игрового мира.
Теперь посмотрим на Transform компонент:
Используйте команду transform. для доступа к Transform компоненту на том-же игровом объекте. И в нём можно изменить позицию, вращение и размер игрового объекта (пример: transform.localScale = new Vector3 (0.5F, 1, 1);). Ваш IDE (редактор) будет пытаться помочь в наборе команд и будут показанны различные возможные варианты.
Можно не только изменять переменные, но и просто запросить их значения.
Теперь посмотрим как работать с другими компонентами. У нашего астероида есть компонент для его отрисовки (рендерер).
Например мы хотим зеркально повернуть астероид вдоль y-оси. Так как наш скрипт уже прикреплён к астероиду, то нам не нужен его поиск в игровом мире. Мы можем получить доступ на компонент командой GetComponent ().. Название компонента можно посмотреть в инспекторе игрового объекта (только осторожно с пробелами). C# команда будет:
GetComponent SpriteRenderer >().flipY = true ;
И скрипт будет:
using UnityEngine;
using System.Collections;
public class Moving : MonoBehaviour <
//Update is called once per frame
void Update () <
>
>
using UnityEngine;
using System.Collections;
public class Moving : MonoBehaviour <
//декларация ссылочной переменной для компонента отрисовки спрайтов
SpriteRenderer sr;
//Update is called once per frame
void Update () <
>
>
Похожим образом мы можем получить и доступ к компонентам на других игровых объектах.
Для начала нам надо «найти» другой игровой объект. Как я уже и писал, тут довольно много различных вариантов в зависимости от ситуации. Например в сцене есть другой игровой объект. Его имя Ship и тэг Player (Tag используется для идентификации объектов (похоже на имя, только скорость обработки быстрее)).
using UnityEngine;
using System.Collections;
public class Moving : MonoBehaviour <
//декларация ссылочной переменной для компонента отрисовки спрайтов
SpriteRenderer sr;
//публичная ссылочная переменная для корабля игрока
public GameObject playerShip;
//Update is called once per frame
void Update () <
>
>
using UnityEngine;
using System.Collections;
public class Moving : MonoBehaviour <
//декларация ссылочной переменной для компонента отрисовки спрайтов
SpriteRenderer sr;
//публичная ссылочная переменная для корабля игрока
public GameObject playerShip;
//Update is called once per frame
void Update () <
>
>
using UnityEngine;
using System.Collections;
public class Moving : MonoBehaviour <
//декларация ссылочной переменной для компонента отрисовки спрайтов
SpriteRenderer sr;
//публичная ссылочная переменная для корабля игрока
public GameObject playerShip;
//Update is called once per frame
void Update () <
>
>
3. Мы можем получть объект с различных игровых функций. Я покажу некотрые из них в последующих туториалах (как пример: OnTriggerEnter2D (Collider2D otherCollider) <> Ссылка на объект попавший в триггер будет в otherCollider переменной).
Основы С# скриптов:
1. Переменные:
2. Ссылочные переменные классов:
3. Массивы (статические и динамические):
4. Модификаторы доступа:
5. Области видимости(действия) переменных:
Spoiler глобально в классе:
Переменная декларированная в классе, но не входящая в функции этого класса может быть использована глобально всеми функциями этого класса.
локально в функции:
Переменная декларированная в функции, может быть использована только в этой функции.
локально в цикле:
Область видимости такой переменной ещё меньше, она используется только локально в пределах цикла. using UnityEngine;
using System.Collections;
public class Moving : MonoBehaviour <
//переменная speed может быть использованна любой функцией этого класса
public int speed;
void RandomFunction () <
//переменная isMoving может быть использованна только в пределах RandomFunction () <. >
bool isMoving = true;
//переменная i может быть использованна только в пределах цикла
for ( int i = speed; i 0 ; i—) <
speed = i;
>
isMoving = false;
>
>
6: Арифметические операторы:
7. Математические функции:
8. Условия и логические операторы:
9. Циклы:
Spoiler for:
Этот цикл выполняется определённое количество раз. //для примера, декларация массива на 10 целых элементов
public int [] numbers = new int [ 10 ];
//int i = 0; декларация с инициализацией счетчика цикла
//i
//i++; изменение счетчика цикла
for ( int i = 0 ; i 10 ; i++) <
//исполняемая часть кода при каждом новом цикле
//в данном примере, заполнение массива числами от 0 до 9
numbers [i] = i;
> Хоть это и не обязательно, но советую использовать в счетчиках циклов целые значения, чтобы избежать ошибок от дробных вычислений.
while:
Этот цикл выполняется пока условие истинно. //для примера, декларация массива на 10 целых элементов
public int [] numbers = new int [ 10 ];
//декларация с инициализацией переменной к, которую будем использовать для проверки условия цикла
int k = 9 ;
//проверка условия цикла, выполнить цикл, если условие истинно
while (k >= 0 ) <
//выполняемый фрагмент кода в фигурных скобках
//заполнение массива числами от 9 до 0 в обратном порядке
numbers [k] = k; //уменьшение переменной на 1 (чтобы получить ложное условие)
k—;
> Будьте осторожны с циклами, чтобы не получить «вечный» цикл, когда условие всегда истинно и цикл повторяется вечно.
do. while:
Отличие этого цикла от цикла while только в том, что проверка условия производится после выполнения фрагмента кода. Поэтому этот цикл выполнится всегда как минимум один раз. //декларация публичной текстовой переменной
public string testText;
//декларация и инициализация целой переменной, для условия цикла
int j = 0 ;
10. Функции:
Spoiler стандартные функции от Юнити:
Существует много различных функций в Юнити. Тут я точно не смогу показать и малой части. Поэтому пока ограничимся несколькими примерами. В дальнейшем в туториалах будут попадаться и новые функции.
Введение в программирование C# на Unity
Несмотря на то, что встроенные компоненты Unity могут быть очень разносторонними, вскоре ты обнаружишь, что тебе нужно выйти за пределы их возможностей, чтобы реализовать свои собственные особенности геймплея. Unity позволяет тебе создавать свои компоненты, используя скрипты. Они позволяют активировать игровые события, изменять параметры компонентов, и отвечать на действия Игрока каким тебе угодно способом.
Unity поддерживает следующие языки программирования: C# и Javascript. Языки C# и Javascript считаются одними из самых популярных среди программистов. На C# пишутся программы для компьютера, веб приложения, а Javascript активно используется для создания интернет-страниц. В нашем случае:
Установка среды разработки
Чтобы писать скрипты, необходим редактор кода. В комплекте с Unity идет MonoDevelop, так что его не требуется устанавливать отдельно. Другой вариант — использовать Visual Studio — мы рекомендуем ее. Сменить среду разработки можно в настройках: Edit → Preferences, а затем выбери панель External Tools.
Вывод сообщения в консоль Unity
Когда ты напишешь свой первый код и добавишь его в Unity, Unity проверит код и, если в нем нет ошибок, произойдет компиляция.
Консоль (англ. — Console) – это панель в Unity, которая отображает ошибки в коде (отображаются красным значком), предупреждения (отображается желтым значком) и позволяет выводить справочную информацию (белый значок). По умолчанию эта панель отображается в нижней части программы в закладке Console. Если эта панель не отображается на экране, то в главном меню выбери Window → Console.

Чтобы создать скрипт выбери Assets → Create → C# Script. Имя скрипта должно быть обязательно на английском и начинаться с большой буквы. Открой созданный скрипт и напиши:
Скрипт не будет работать до тех пор, пока экземпляр скрипта не будет присоединен к игровому объекту. Ты можешь прикрепить скрипт перетащив его на игровой объект в окно Иерархия или через окно Инспектор выбранного игрового объекта.
Код, который должен вызываться один раз при старте программы, ты можешь написать внутри функции Start(), как в примере выше.
Код, который должен вызываться каждый кадр, ты можешь написать внутри функции Update().
Переменные
Если ты хочешь сохранить данные (количество жизней игрока, патронов или очков опыта), то для этого используются переменные. Переменные разделяются на типы, которых существует огромное множество.
Переменная — поименованная область памяти, адрес которой можно использовать для осуществления доступа к данным и изменять значение в ходе выполнения программы. Переменные хранят в себе информацию разного типа, эти данные называют значением переменной. Для каждого типа данных есть свой тип переменной. Например:
Инициализация переменной
Все переменные в C# должны быть объявлены (инициализированы) до их применения. Например:
Задать значение переменной можно, в частности, с помощью оператора присваивания — знак «=». Кроме того, при объявлении переменной можно сразу задать ее значение. Например:
Переменные численных типов можно складывать, вычитать, умножать и делить:
+ — операция сложения;
— — операция вычитания;
* — операция умножения;
/ — операция деления.
А вот так сумму чисел можно вывести в консоль:
Счетчик времени с помощью Time.deltaTime
Практически во всех играх требуется знать сколько времени прошло с момента запуска игры (пример: игры на время). Но в Unity мы можем узнать только сколько прошло времени между кадрами (напоминаю, что игра – это набор кадров, которые быстро меняются. В одну секунду количество таких кадров может достигать 60 и больше).
Чтобы узнать сколько времени прошло между кадрами — используется Time.deltaTime.
Чтобы сделать дробное число целым, ставим перед ним (int).
Позиция объекта
Координаты объекта хранятся в компоненте Transform, свойство — position. Каждая координата имеет тип float. Вот так можно выводить координаты объекта в консоль:
Создание простого ИИ на C# в Unity
Почти любой игре необходим взаимодействующий с пользователем искусственный интеллект (AI), чаще всего в виде враждебной игроку силы. В некоторых случаях ИИ должен помогать игроку, в других — бороться с ним, но у всех управляемых компьютером персонажей существует некоторое сходство. В зависимости от требований проекта ИИ может использовать простые или сложные поведения. Такими требованиями могут быть дипломатия с другим игроком или простое блуждание вперёд-назад по платформе. Как бы то ни было, необходимо сделать так, чтобы ИИ качественно выполнял свою работу.
В этом проекте я продемонстрирую очень простой искусственный интеллект. Допустим, мы создаём игру, в которой игрок должен тайком пробраться рядом с вражеским штабом. Когда игрока замечает камера слежения, рядом создаются враги и в течение короткого промежутка времени преследуют игрока. Именно это мы и реализуем в проекте на простейшем уровне. Завершив проект, вы получите управляемый объект игрока, круг, используемый в качестве камеры врага, и объект врага, который будет преследовать игрока, когда о его присутствии сообщит объект камеры.
Подготовка
Для начала нам нужно создать 3D-проект. Нажмите на кнопку New в верхней части окна после запуска Unity, как это показано на рисунке 1.
Рисунок 1: создание нового проекта
Назовите свой проект AI и убедитесь, что он является 3D-проектом. Выбрав место на компьютере для хранения проекта, нажмите на кнопку Create Project внизу, показанную на рисунке 2.
Рисунок 2: экран настройки проекта
После создания проекта нам первым делом нужно настроить папки в окне Assets, чтобы упорядочить свою работу. Нажмите правой кнопкой на окне Assets и выберите Create → Folder для создания новой папки. Назовите эту папку Materials. Затем создайте вторую папку и назовите её Scripts. На рисунке 3 показано, как это должно выглядеть.
Рисунок 3: создание новой папки
После всего этого окно Assets должно выглядеть так, как показано на рисунке 4.
Далее создадим пол, на котором будут стоять все объекты. В окне Hierarchy выберите Create → 3D Object → Plane, чтобы создать объект-плоскость, которая будет использоваться в качестве пола.
Рисунок 5: создание объекта Plane.
Назовите этот объект Floor и измените его значение X Scale на 7, а значение Z Scale — на 3. После этого окно Inspector с выбранным объектом Floor должно выглядеть так, как показано на рисунке 6.
Рисунок 6: задание свойств объекта Floor.
Теперь нам нужно создать новый материал для Floor, чтобы отличать его от остальных объектов, которые будут размещены в сцене. В папке Materials окна Assets создайте новый материал, нажав правой кнопкой на окно Assets и выбрав Create → Material.
Рисунок 7: создание нового материала
После завершения назовите материал Floor.
Рисунок 8: материал Floor.
В верхней части окна Inspector с выбранным материалом Floor выберите color picker.
Рисунок 9: выбор color picker.
Разумеется, вы можете выбрать для пола любой цвет, но в этом примере я выбрал красно-коричневый цвет, как показано на рисунке 10.
Рисунок 10: color picker.
Выберите объект Floor в окне Hierarchy, и в компоненте Mesh Renderer выберите маленькую стрелку рядом с Materials.
Рисунок 11: подготовка к изменению материала.
Перетащите материал Floor из окна Assets в поле Element 0 компонента Mesh Renderer в окне Inspector.
Рисунок 12: задание материала Floor в качестве материала объекта Floor.
Закончив с объектом Floor, мы дожны создать вокруг области стены, чтобы игрок не мог свалиться с края. Снова заходим в Create → 3D Object → Plane для создания новой плоскости. Назовём эту плоскость Wall и выставим ей те же размеры, что и у Floor, то есть X Scale со значением 7 и Z Scale со значением 3. Затем создадим ещё три стены, выбрав объект и трижды нажав Ctrl + D. После этого разместим стены вокруг пола в соответствии с данными из таблицы.
| Название | Position X | Position Y | Position Z | Rotation X | Rotation Z |
| Wall | -35 | 21 | 0 | 0 | -90 |
| Wall (1) | -1 | 11 | -15 | 90 | 0 |
| Wall (2) | -1 | 11 | 13.5 | -90 | 0 |
| Wall (3) | 34 | 21 | 0 | 0 | 90 |
Таблица 1: позиции и повороты всех объектов Wall.
Завершив всё это, нужно изменить положение камеры, чтобы она смотрела на пол сверху. Выберите объект Main Camera и задайте для Y Position значение 30, для Z Position значение 0, а X Rotation — значение 80.
Рисунок 13: настройка объекта камеры.
Сцена подготовлена, поэтому настало время создания персонажа игрока. В окне Hierarchy нажмите на Create → 3D Object → Sphere, чтобы создать объект-сферу. Назовите этот объект Player, а затем нажмите на кнопку Add Component в нижней части окна Inspector.
Рисунок 14: добавление нового компонента.
Теперь найдите Rigidbody. После этого выберите из списка компонент Rigidbody и добавьте Rigidbody к объекту Player.
Рисунок 15: добавление компонента Rigidbody.
Далее нужно присвоить игроку тэг, который позже пригодится нам в коде. Нажмите на раскрывающееся меню Tag в левом верхнем углу окна Inspector и выберите тэг Player.
Рисунок 16: задание нового тэга.
Рисунок 17: размещение игрока.
Чтобы наш будущий код работал правильно, нам, разумеется, нужно прикрепить его к объекту. Снова заходим в окно Hierarchy и на этот раз выбираем Create → 3D Object → Cube. Назовём этот куб Guard, добавим к нему компонент Rigidbody и компонент NavMesh Agent с помощью кнопки Add Component в окне Inspector. Далее поместим его где-нибудь в верхнем левом углу сцены. После этого окно Inspector объекта Guard будет выглядеть следующим образом:
Рисунок 18: объект Guard в окне Inspector.
И этот объект должен быть расположен так:
Рисунок 19: Размещение объекта Guard.
Наконец, нам потребуется объект, используемый в качестве «глаз» объекта Guard, который будет уведомлять Guard о том, что его касается игрок. В последний раз перейдите в окно Hierarchy и выберите Create → 3D Object → Sphere для создания ещё одного объекта-сферы. Назовите этот объект Looker. На этот раз нам не нужно добавлять к нему никаких других компонентов. Однако мы изменим размер объекта. Выбрав Looker, измените следующие переменные компонента Transform в окне Inspector.
Рисунок 20: размещение объекта Looker.
Настало подходящее время для того, чтобы придать Looker уникальный материал, чтобы было заметно, что его стоит избегать. В папке Materials окна Assets нажмите правой клавишей мыши и создайте новый материал. Назовите его Looker и задайте ему ярко-красный цвет. После этого назначьте этот материал в качестве материала объекта Looker, чтобы изменить его цвет. После этого сцена должна выглядеть следующим образом:
Рисунок 21: объект Looker с новым материалом.
Единственное, что нам осталось — создать навигационный меш для Guard, по которому он сможет перемещаться. В верхней части редактора Unity есть меню Window. Выберите Window → Navigation, чтобы открыть окно Navigation, показанное на рисунке 22.
Рисунок 22: окно Navigation.
Выберите объект Floor в Hierarchy, а затем в окне Navigation поставьте флажок Navigation Static.
Рисунок 23: Navigation Static.
Далее выберем опцию Bake в верхней части окна.
Рисунок 24: переключение на меню Bake.
Откроется меню Bake, в котором можно изменять свойства навигационного меша, который мы собираемся создать. В нашем примере ничего изменять не требуется. Достаточно нажать на кнопку Bake в правой нижней части.
Рисунок 25: создание нового навигационного меша.
На этом этапе Unity попросит сохранить сцену. Сохраните её, после чего будет создан навигационный меш. Теперь сцена будет выглядеть так:
Рисунок 26: текущая сцена с добавленным навигационным мешем.
Теперь всё в Unity настроено, поэтому настало время для создания скриптов, необходимых для работы проекта. В окне Assets нажмите правой клавишей мыши и выберите Create → C# Script. Назовите этот скрипт Player. Повторите эту операцию ещё два раза, создав скрипты с названиями Guard и Looker.
Рисунок 27: создание нового скрипта.
После этого папка Scripts в окне Assets будет выглядеть так:
Рисунок 28: папка Scripts.
Первым мы начнём писать код скрипта Player. Дважды щёлкните по скрипту Player в окне Assets, чтобы открыть Visual Studio и приступить к созданию кода.
Скрипт Player достаточно прост, всё что он делает — позволяет пользователю перемещать объект-мяч. Под объявлением класса нам нужно получить ссылку на компонент Rigidbody, который мы ранее создали в проекте.
Сразу после этого в функции Start мы прикажем Unity сделать текущий компонент Rigidbody объекта Player значением rb.
После этого скрипт Player будет выглядеть так:
Рисунок 29: скрипт Player на текущий момент.
Теперь, когда значение rb присвоено, нам нужно позволить объекту Player двигаться при нажатии клавиш со стрелками. Для перемещения объекта мы будем использовать физику, применяя силу к объекту при нажатии пользователем клавиш со стрелками. Для этого достаточно добавить в функцию Update следующий код:
На этом мы завершили скрипт Player. Готовый скрипт будет выглядеть следующим образом:
Рисунок 30: готовый скрипт Player.
Сохраните свою работу и вернитесь в Unity. На этот раз выберите в окне Assets скрипт Guard. Чтобы заставить код для Guard работать, нужно добавить в верхнюю часть скрипта конструкцию using.
Далее объявим следующие переменные сразу после объявления класса.
В качестве значения переменной player объекта Guard используется объект Player. Она пригодится нам позже, когда мы прикажем объекту Guard преследовать игрока. Затем объявляется переменная navmesh для получения компонента NavMeshAgent объекта. Её мы используем позже, когда Guard начнёт преследовать игрока после того, как узнает о том, что игрок касается объекта Looker. В функции Start нам нужно задать в качестве значения переменной navmesh компонент NavMesh Agent объекта:
Затем в функции Update мы добавим единственную строку кода:
Эта строка задаёт точку назначения для объекта Guard. В нашем случае она будет брать текущую позицию объекта Player и перемещаться к этой точке. После срабатывания объект будет постоянно преследовать игрока. Вопрос в том, как выполняется процесс срабатывания? Он будет закодирован не в скрипте Guard, а в скрипте Looker. Прежде чем переходить к скрипту Looker, посмотрите на рисунок 31, чтобы сверить свой код скрипта Guard.
Рисунок 31: готовый скрипт Guard.
Внутри Looker нам снова нужно объявить следующие переменные:
После этого закомментируем функцию Start, которая в этом скрипте нам не нужна. Перейдём к функции Update и добавим следующий код:
Именно здесь происходят основные действия проекта, поэтому давайте проанализируем код. Во-первых, в зависимости от значения булевой переменной movingDown, объект, к которому прикреплён этот скрипт, будет двигаться вверх или вниз. Как только он достигнет определённой точки, то изменит направление. Далее Looker снизит значение сброса на основании реального времени. Как только таймер станет меньше нуля, он возьмём скрипт Guard из объекта Guard и отключит его, после чего объект Guard начнёт перемещаться к последней известной до этого моменрта позиции игрока, а затем остановится. Looker также снова включает его коллайдер, чтобы весь процесс мог начаться заново. Теперь наш скрипт выглядит следующим образом:
Рисунок 32: скрипт Looker.
Кстати о коллайдерах: настало время создать код коллизии, сбрасывающий таймер Looker и включающий скрипт Guard. В функции Update создайте следующий код:
OnCollisionEnter Unity автоматически распознаёт как код коллизии, а поэтому выполняет его при возникновении коллизии с другим объектом. В нашем случае он сначала проверяет, имеет ли столкнувшийся объект тэг Player. Если нет, то он игнорирует остальную часть кода. В противном случае он включает скрипт Guard, задаёт таймеру reset значение 5 (то есть пять секунд), и отключает его коллайдер, чтобы игрок по-прежнему мог двигаться сквозь объект и случайно не застрял в объекте Looker. Функция показана на рисунке 33.
Рисунок 33: код коллизии для Looker.
На этом весь код проекта готов! Можно сделать ещё пару вещей, прежде чем закончить проект. Сохраните всю работу и вернитесь в Unity.
Завершение проекта
Для завершения проекта нам достаточно прикрепить скрипты к соответствующим объектам и задать несколько переменных. Во-первых, перейдите из окна Navigation в окно Inspector:
Рисунок 34: переход в окно Inspector.
После этого начнём с объекта Player. Выберите его в окне Hierarchy, а затем в нижней части окна Inspector нажмите на кнопку Add Component и добавьте скрипт Player. На этом объект Player завершён.
Рисунок 35: компонент скрипта Player.
Далее выберите объект Guard. Как и раньше, прикрепим скрипт Guard к объекту. На этот раз нам понадобится сообщить Guard, кто является игроком. Для этого перетащите объект Player из Hierarchy в поле Player компонента скрипта Guard, как показано на рисунке 36.
Рисунок 36: делаем объект Player значением поля Player.
Также нам нужно отключить скрипт Guard. В нашем проекте Guard будет преследовать игрока после включения его скрипта. Этот скрипт Guard должен включаться только после того, как игрок коснётся объекта Looker. Всё, что нужно сделать — снять флажок рядом с текстом Guard (Script) в компоненте:
Рисунок 37: отключение скрипта Guard.
Наконец, перейдём к объекту Looker и прикрепим к нему скрипт Looker. На этот раз объекту Looker потребуется объект Guard в качестве значения его переменной Guard. Так же, как мы назначали объект Player переменной Player скрипта Guard, мы сделаем то же самое с объектом Guard и скриптом Looker. Перетащите Guard из Hierarchy в поле Guard скрипта Looker. И на этом проект завершён! Нажмите на кнопку Play в верхней части редактора Unity, чтобы проверить свой проект.
Рисунок 38: тестирование проекта.
Попробуйте переместить объект Player в объект Looker (не забывайте, что перемещение выполняется стрелками!). Заметьте, что после этого объект Guard начнёт преследовать игрока. Он будет продолжать преследование примерно 5 секунд, после чего сдастся.
Рисунок 39: полностью готовый проект в действии.
Заключение
Этот ИИ очень прост, но его запросто можно расширить. Допустим, если мы представим, что объект Looker — это камера, а охранник смотрит через неё, чтобы найти вас, то будет логично дать объекту Guard собственную пару глаз. Игрок может проходить рядом с камерами, но они должны учитывать и глаза охранника. Также можно скомбинировать этот проект с концепцией поиска пути: дать охраннику путь, по которому он будет следовать, создав таким образом более интересную для игрока среду.
Подобный простой ИИ можно развить множеством разных способов. Возможно, вы не захотите делать ничего вышеизложенного и решите сделать что-то своё. Советую вам экспериментировать, возможно, у вас появится идея интересного проекта, который стоит довести до конца.















































