Простая 2D-игра на Unity 5. Часть 1

Суть игры состоит в том, что вы управляете летающей тарелкой, которая собирает кристаллы. После того как вы соберете все кристаллы вы выигрываете. Очень простая игра, но для понимания основ самое оно.

Для начала открываем Юнити, создаем новый 2D-проект. После чего нам нужно открыть Asset Store. Найти его можно в строке меню: Window – Asset Store. На сайте магазина в правом боковом меню находим пункт Unity Essentials – Sample Projects. Открываем проект 2D UFO Tutorial. Жмем синюю кнопку Import. Появится диалоговое окно с предупреждением, о том, что настройки импортируемого проекта перепишут настройки текущего проекта, это нормально, жмем Import. Далее откроется следующее окно:Тут также жмем Import. После чего вкладку Asset Store можно закрыть. В результате чего во вкладке Project в папке Assets должно появиться две папки: Completed и Sprites. В папке Completed сохранен готовый проект, на случай, если у вас что-то не будет получаться. Для начала открываем папку Sprites и переносим на вкладку Hierarchy два спрайта: Background и UFO. В месте с объектом камеры получается так:В результате, во вкладке Scene мы должны видеть оба добавленных объекта. Теперь настроим каждый объект из вкладки Hierarchy. Нажимая по каждому объекту, мы должны видеть его настройки во вкладке Inspector. Для Main Camera изменим поле Size (Размер), до 17, чтобы во время игры видеть все игровое пространство. Также изменим поле Background на какой-нибудь темный цвет, по вашему усмотрению.Для Background изменим поле Sorting Layer. Значение Default заменим на Background. И добавим четыре компонента Box Collider 2D. Добавляются они нажатием кнопки Add Component – Physics 2D – Box Collider 2D. По умолчанию Box Collider 2D создается по размерам нашего игрового поля. Но нам нужно изменить размеры, чтобы четыре Box Collider 2D ограничивали наше игровое пространство таким образом:Для этого изменим размеры и смещение (Size и Offset) первого коллайдера. Размер по иксу сделаем примерно 3.3, по игреку оставим текущий. Смещение по иксу примерно 14.23.В результате рамка коллайдера сместится на правую границу нашего игрового поля. Для 3-х других коллайдеров размеры и смещения следующие:Далее, для UFO изменим поле Sorting Layer. Значение Default заменим на Player. Поле Gravity Scale сделаем со значением 0. Если вы этого не сделаете и запустите игру, то тарелка упадет вниз под действием гравитации. Также добавим компонент Rigidbody 2D (оставим настройки по умолчанию) и компонент Circle Collider 2D, поле Radius (Радиус) сделаем по размерам летающей тарелки:Далее, добавим на вкладку Hierarchy спрайт Pickup. Нужно изменить его Sorting Layer на Pickups. Но во вкладке Scene он все равно будет скрыт тарелкой. Нужно просто мышкой сдвинуть его в сторону. Изменим также значение поля Tag на PickUp. Для этого объекта добавим компонент Rigidbody 2D. Отметим поле Is Kinematic, чтобы кристалл тоже не падал вниз, под действием гравитации. Также добавим компонент Circle Collider 2D, поле Radius (Радиус) сделаем по размерам кристалла. Примерно 0.94. Отметим поле Is Trigger. Это нужно для того чтобы отслеживать событие соприкосновения игрока и кристалла.Теперь можно создать папку Prefabs и перенести в нее наш объект Pickup. Из этой папки мы можем переносить объекты в игровое пространство и изменять свойства сразу для них всех. Перенесем кристаллы на карту вокруг тарелки примерно таким образом:На вкладке Hierarchy создадим новый пустой объект, щелкнув правой кнопкой мыши по рабочему пространству вкладки и выбрав Create Empty. Переименуем его в Pickups. Перенесем все созданные объекты в него. Теперь вкладка Hierarchy будет выглядеть следующим образом:На рисунке я не добавил первый Pickup в группу Pickups, но для поддержания порядка это следует сделать. Следующим шагом будет создание двух текстовых меток для отображения количества собранных кристаллов и показа сообщения об окончании игры, после сбора всех кристаллов. Для создания меток нужно щелкнуть правой кнопкой мыши по рабочему пространству вкладки Hierarchy, выбрать UI – Text:В результате, в пространстве вкладки Hierarchy получим следующую структуру:Нам нужно выбрать объект Text. Дадим ему название CountText. Далее, в настройках (во вкладке Inspector) нажмем левой кнопкой мыши на квадрат с красным перекрестьем и с нажатыми клавишами Alt + Shift выберем левый верхний квадрат как показано на рисунке:Таким образом, мы сделаем так, чтобы текстовая метка отображалась в левом верхнем углу экрана. Зададим еще отступы от верхнего левого угла:Также изменим настройки в разделе Text, это будет сам текст, размер и цвет. У меня получилось следующее:В результате, во вкладке Game мы получим примерно следующее:Теперь, осталось добавить текстовое сообщение об окончании игры. Все делаем таким же образом, разница состоит только в том, что сообщение об окончании игры нужно расположить по центру. Для этого меняем настройки примерно следующим образом:Также, дадим название для метки WinText. В результате, во вкладке Game мы получим примерно следующее:С созданием и размещением объектов игры мы закончили. Остался один скриптинг. Нам нужно добавить код для 3-х объектов игры: камеры, тарелки и кристаллов. Чтобы добавить новый скрипт для объекта нужно нажать на кнопку Add Component (также как мы добавляли Rigidbody 2D и Collider 2D) и выбрать New script (внизу списка). Но новые скрипты можно не создавать, так как они уже есть в папке Completed – Scripts. Мы просто подключим уже готовые скрипты. Выберем объект UFO во вкладке Hierarchy. Нажмем на кнопку Add Component – Scripts. Выберем скрипт CompletePlayerController. Теперь нам нужно заполнить 3 свойства скрипта:Speed зададим 10-15… можете поэкспериментировать. Count Text и Win Text – это две текстовые метки, которые мы создали ранее. Перенесем их из вкладки Hierarchy прямо на текст None (Text) во вкладке Inspector (см. рисунок выше), в результате получим следующее:Для объекта Main Camera выберем скрипт CompleteCameraController. В свойство скрипта камеры Player из вкладки Hierarchy перенесем объект Player (это переименованный объект UFO, который можно и не переименовывать), получим следующее:Далее, добавим скрипт для кристаллов, но чтобы добавить его сразу для всех экземпляров откроем папку Prefabs и выберем кристалл там. Добавим скрипт CompleteRotator. Таким образом, ко всем кристаллам в игре будет привязан нужный скрипт. Вот и все. Запускаем и пробуем. Должно работать. Если что-то не будет получаться, то можно открыть сцену Main (Completed) из папки Completed – Scenes, посмотреть, как сделано там. Чтобы сохранить проект в виде отдельной программы, нужно в строке меню выбрать: File – Build Settings… В открывшемся окне убедиться, что выбрана платформа PC, Mac & Linux Standalone:Нажать кнопку Build And Run. Далее привожу тексты скриптов с комментариями на русском.

/*
 * CompleteCameraController.cs - для того чтобы камера следила за движением игрока
 */
using UnityEngine;
using System.Collections;
public class CompleteCameraController : MonoBehaviour {
	//Переменнная для хранения ссылки на объект игрока
	public GameObject player;
	//Переменнная для хранения расстояния между камерой и игроком
	//Нужна при слежении за движениями игрока
	private Vector3 offset;
	//Метод для инициализации
	void Start ()
	{
		//Присваиваем переменной offset значение расстояния между позицией камеры
		//и позицией игрока
		offset = transform.position - player.transform.position;
	}
	// LateUpdate вызывается после Update() каждый кадр
	void LateUpdate ()
	{
		//Устанавливаем позицию камеры на расстоянии offset,
		//но при этом движемся за игроком
		transform.position = player.transform.position + offset;
	}
}
/*
 * CompletePlayerController.cs - основной скрипт игры
 */
using UnityEngine;
using System.Collections;
//Добавляем пространство имен для UI, с помощью которого мы можем работать с текстом
using UnityEngine.UI;
public class CompletePlayerController : MonoBehaviour {
	//Переменная для хранения скорости игрока
	public float speed;
	//Переменнная для хранения ссылки на компонент Text, который будет выводить
	//количество собранных кристаллов
	public Text countText;
	//Переменнная для хранения ссылки на компонент Text, который будет выводить
	//сообщениие о завершении игры
	public Text winText;
	//Переменная для хранения ссылки на компонент Rigidbody2D,
	//для использования 2D физики
	private Rigidbody2D rb2d;
	//Переменная для хранения количества собранных кристаллов
	private int count;
	//Метод для инициализации
	void Start()
	{
		//Получаем и присваиваем переменной значение ссылки на компонент Rigidbody2D,
		//для последующего его использования
		rb2d = GetComponent ();
		count = 0;
		//Переменной winText присваиваем пустое значение,
		//чтобы текст этой переменной не выводился до сбора всех кристаллов 
		winText.text = "";
		//Вызываем функцию SetCountText () для показа количества собранных кристаллов
		SetCountText ();
	}
	//FixedUpdate() вызывается фиксированно по времени. Добавляйте код для работы с физикой
	//в этот метод
	void FixedUpdate()
	{
		//Получаем значение горизонтальной оси ввода
		//Ось может иметь значение от –1 до 1. На нейтральное положение указывает 0
		float moveHorizontal = Input.GetAxis ("Horizontal");
		//Получаем значение вертикальной оси ввода
		//Ось может иметь значение от –1 до 1. На нейтральное положение указывает 0
		float moveVertical = Input.GetAxis ("Vertical");
		//Сохраняем положение точки в сторону которой нужно двигать тарелку
		Vector2 movement = new Vector2 (moveHorizontal, moveVertical);
		//Вызов функции AddForce() для придания движения тарелке
		rb2d.AddForce (movement * speed);
	}
	//OnTriggerEnter2D вызывается, в данном случае, при соприкосновении с кристаллом,
	//у которого для коллайдера выбрано значение Is Trigger
	void OnTriggerEnter2D(Collider2D other)
	{
		//Проверяем действительно ли с кристаллом мы столкнулись...
		if (other.gameObject.CompareTag ("PickUp"))
		{
			//... если да, то деактивируем кристалл, скрываем его 
			other.gameObject.SetActive(false);
			//Прибавляем еще один собранный кристалл к нашей копилке
			count = count + 1;
			//Заново выводим количество собранных кристаллов на экран
			SetCountText ();
		}
	}
	//Эта функция выводит количество собранных кристаллов на экран
	//а также выводит сообщениие об окончании игры, если все кристаллы были собраны
	void SetCountText()
	{
		//Сообщение о количестве собранных кристаллов
		countText.text = "Всего собрано: " + count.ToString ();
		//Проверяем были ли собраны все кристаллы, если да, то выводим сообщение
		//об окончании игры
		if (count >= 12)
			winText.text = "Вы выиграли!";
	}
}
/*
 * CompleteRotator.cs - вращает кристаллы
 */
using UnityEngine;
using System.Collections;
public class CompleteRotator : MonoBehaviour {
	//Update вызывается каждый кадр
	void Update ()
	{
		//Плавно вращаем кристалл
		//Функция Time.deltaTime возвращает время каждого кадра
		//Это очень маленькое значение, таким образом кристалл каждый раз поворачивается
		//на небольшой угол, поэтому вращение очень плавное
		transform.Rotate (new Vector3 (0, 0, 45) * Time.deltaTime);
	}
}