В этой статье я хочу рассказать вам как в игровом движке Unity 5 создать игру Змейка 3d. В игре будет реализована сама змея, которая будет двигаться в определенном направлении, поедать яблоки и расти. За поедание яблок будут начисляться очки, но если змея врежется не в яблоко а в другой предмет (препятствие или стену) игра будет окончена.
Подготовка сцен.
Для начала подготовим сцены, откройте новый проект и создайте три новых сцены, назовем их : MainMenu, Level и GameOver. Начнем со сцены MainMenu, эта сцена будет отвечать за наше игровое меню и за загрузку следующего уровня. Создадим новый С# скрипт MainMenu и перенесем его на камеру, откроем его и напишем такой код:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MainMenu : MonoBehaviour {
public Vector2 menuSize = new Vector2(500, 300);
// минимальная высота кнопки
public float buttonMinHeight = 60f;
// шрифт заголовка
public Font captionFont;
// шрифт кнопок
public Font buttonFont;
// тексты меню
public string mainMenuText = "Menu";
public string startButtonText = "Start Game";
public string exitButtonText = "Exit Game";
public void OnGUI()
{
// рассчитываем прямоугольник по центру экрана с заданным размером
Rect rect = new Rect(
Screen.width / 2f - menuSize.x / 2,
Screen.height / 2f - menuSize.y / 2,
menuSize.x,
menuSize.y);
// область меню
GUILayout.BeginArea(rect, GUI.skin.textArea);
{
// создаем стиль заголовка на основе стиля label стандартного скина
GUIStyle captionStyle = new GUIStyle(GUI.skin.label);
// устанавливаем стилю заголовка шрифт captionFont
captionStyle.font = captionFont;
// Расположение текста по центру
captionStyle.alignment = TextAnchor.MiddleCenter;
// текст заголовка
GUILayout.Label(mainMenuText, captionStyle);
// создаем стиль кнопки на основе стиля button стандартного скина
GUIStyle buttonStyle = new GUIStyle(GUI.skin.button);
// устанавливаем стилю кнопки шрифт buttonFont
buttonStyle.font = buttonFont;
// отступы кнопок от краев
buttonStyle.margin = new RectOffset(20, 20, 3, 3);
// FlexibleSpace - автоматически рассчитанное место, необходимое для
// заполнения пустого пространства между элементами управления
GUILayout.FlexibleSpace(); // динамическое пространство между заголовком и кнопкой старт
// отрисовка кнопки Start и обработка ее нажатия
if (GUILayout.Button(startButtonText, buttonStyle, GUILayout.MinHeight(buttonMinHeight)))
{
// загрузка сцены с именем Level
SceneManager.LoadScene("Level");
}
Видео:Создание игры Snake (Змейка) на Unity3DСкачать
GUILayout.FlexibleSpace(); // динамическое пространство между кнопками
// отрисовка кнопки Exit и обработка ее нажатия
if (GUILayout.Button(exitButtonText, buttonStyle, GUILayout.MinHeight(buttonMinHeight)))
{
// выход
Application.Quit();
}
GUILayout.FlexibleSpace(); // динамическое пространство между кнопкой Exit и низом области меню
}
GUILayout.EndArea();
}
}Этот скрипт будет выводить наше меню на экран и при нажатии на кнопку Start загружать следующий уровень «Level». В редакторе можете изменить размеры меню и добавить свой шрифт в captionFont и buttonFont. В итоге должно получится примерно так…

Сцена Game Over.
Следующая сцена — это сцена Game Over. Эта сцена будет состоять из одно надписи и появляться тогда, когда наша змейка врежется в какой- нибудь предмет. Так же после небольшой паузы загрузится другая сцена с нашем меню.
Откроем созданную сцену и создадим еще один скрипт с названием GameOver. Переместим его так же на камеру и напишем в нем такой код:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class LoadLevel : MonoBehaviour {
// время до загрузки уровня
public float delay = 3;
// имя загружаемого уровня
public string levelName;
public IEnumerator Start()
{
// задержка на заданное число секунд
yield return new WaitForSeconds(delay);
// загрузка уровня с указанным именем
SceneManager.LoadScene("MainMenu");
}
}Скрипт готов, теперь добавим GUItext и настроим так, чтобы надпись Game Over находилась примерно по центру экрана…

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

Добавим на сцену сферу с позицией 0,0,0 ,с размерами 2,2,2 и с поворотом 0,0,90, это будет голова нашей змейки.

К этой сфере добавим компонент character controller, который будет отвечать за движение.
Настроим камеру так, чтобы она следила за нашей змейкой. Поверните камеру по х на 90 градусов и расположите ее в позиции 0,30,0 и создайте новый скрипт LookAt, который будет следить за головой змейки:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LookAt : MonoBehaviour {
// цель, на которую должен смотреть объект
public Transform target;
public void Update()
{
if (target != null)
{
// Смотрим всегда на цель
transform.LookAt(target);
}
}
}Перенесите его на камеру и в строке target выберете нашу сферу.

Добавим еще одну сферу, это будет наша еда. Создадим еще один скрипт и назовем его food:
using System.Collections; using System.Collections.Generic; using UnityEngine;public class Food : MonoBehaviour { // количество очков, которое дает еда при съедании public int points = 10; public void Update() { // вращаем еду со скоростью 60 градусов в секунду transform.Rotate(Vector3.up, 60 * Time.deltaTime); } public void Eat() { // прибавляем очки еды к общему числу очков Game.points += points; // уничтожаем объект еды Destroy(gameObject); GenerateNewFood(); } // функция создания новой еды public static void GenerateNewFood() { // создаем экземпляр еды, предварительно загружая префаб из ресурсов GameObject food = (GameObject)Instantiate(Resources.Load("Prefabs/Food", typeof(GameObject))); // цикл подбора положения еды while (true) { // ставим еду в рандомное место food.transform.position = new Vector3(Random.Range(-40, 41), 0, Random.Range(-40, 41)); // получаем размер ее колайдера в мировых координатах Bounds foodBounds = food.GetComponent().bounds; bool intersects = false; // Проверяем со всеми колайдерами кроме колайдера самой еды. foreach (Collider objectColiider in FindObjectsOfType(typeof(Collider))) { if (objectColiider != food.GetComponent()) { // если пересекается, то завершаем цикл, досрочно if (objectColiider.bounds.Intersects(foodBounds)) { intersects = true; break; } } } // установили в нужное место, останавливаем цикл установки if (!intersects) { break; } } } }Видео:Создаем игру Snake в Unity | уроки для новичковСкачать
Этот скрипт будет размещать префаб еды при старте сцены, давать очки при съедании объекта, удалять объект со сцены и создавать новую еду в рандомном месте. Перемещаем его на модель еды и сохраняем модель в префаб в папку Resources/Prefabs под названием food.

На данном этапе у вас может возникнуть ошибка в строке
Game.points += points;
Здесь подразумевается что есть скрипт под названием Game c переменной points. Давайте его создадим:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Game : MonoBehaviour {
// материал стен
public Material wallMaterial;
// набранные очки
public static int points;
// количество стен в уровне
public int countWals = 10;
private string _pointsString;
private int _lastPonts = -1;
// генерируем уровень при загрузке сцены
public void Awake()
{
// обнуляем очки
points = 0;
Видео:Создание змейки на Unity за 5 минутСкачать
// генерируем уровень
GenerateLevel();
// ставим первую еду
Food.GenerateNewFood();
}
public void Update()
{
// обновление отображаемого текста очков только при их изменении
if (_lastPonts == points) return;
_lastPonts = points;
// форматируем очки в формате четырех цифр, начинающихся с нулей
_pointsString = "Score: " + points.ToString("0000");
}
// отрисовка набранных очков
public void OnGUI()
{
GUI.color = Color.yellow;
GUI.Label(new Rect(20, 20, 200, 20), _pointsString ?? "");
}
// функция генерации уровня
private void GenerateLevel()
{
for (int i = 0; i < countWals; i++)
{
// создаем куб
GameObject wall = GameObject.CreatePrimitive(PrimitiveType.Cube);
// называем его "Wall"
wall.name = "Wall";
// увеличиваем его габариты
wall.transform.localScale = new Vector3(2, 2, 2);
// расставляем его так, чтобы координаты были не в центре игрового поля
var pos = new Vector3(Random.Range(-40, 41), 0, Random.Range(-40, 41));
while (Mathf.Abs(pos.x) < 5 || Mathf.Abs(pos.z) < 5)
{
pos = new Vector3(Random.Range(-40, 41), 0, Random.Range(-40, 41));
}
wall.transform.position = pos;
// и назначаем материал
wall.GetComponent().material = wallMaterial;
}
}
}Этот скрипт будет считать наши набранные очки и выводить их на экран, создавать препятствия в зоне наших ограждений и рандомно генерировать их на плоскости.
Создадим пустышку на сцене и перенесем на нее этот скрипт, так же можно указать материал который будет накладываться на препятствия.

Можете запустить игру и проверить что мы наделали. Как видите препятствия и еда генерируется в свободных местах, но змейка наша пока не двигается, этим мы сейчас и займемся.
Создадим еще один скрипт и назовем его Player:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
[RequireComponent(typeof(CharacterController))]
public class Player : MonoBehaviour
{
// скорость перемещения - 6 единиц в секунду по умолчанию
// в редакторе можно поменять
public float speed = 6;
private bool _testing = false;
public GameObject SnakeBody;
public List BodySnake = new List { };
// аналогично скорость вращения 60 градусов в секунду по умолчанию
public float rotationSpeed = 60;
// локальная переменная для хранения ссылки на компонент CharacterController
private CharacterController _controller;
public void AddTile() {
Vector3 Position = transform.position;
if (BodySnake.Count > 0) {
Position = BodySnake[BodySnake.Count - 1].transform.position;
}
Position.y+=10f;
GameObject Body = Instantiate(SnakeBody, Position, Quaternion.identity) as GameObject;
BodySnake.Add(Body);
}
public void Start()
{
BodySnake.Clear();
for (int i = 0; i < 5; i++) AddTile();
_controller = GetComponent();
}
public void Update()
{
SnakeStap();
// получаем значение горизонтальной оси ввода
float horizontal = Input.GetAxis("Horizontal");
Видео:🐍 Змейка с хвостом [Unity 3D] [Tutorial] (как в Snake VS Block или как в классической змейке)Скачать
// вращаем трансформ вокруг оси Y
transform.Rotate(rotationSpeed * Time.deltaTime * horizontal,0, 0);
// двигаем змею постоянно
_testing = true; // маленкий хинт, для того, чтобы не обрабатывать несколько коллизий за кадр
_controller.Move(transform.forward * speed * Time.deltaTime);
}
void SnakeStap() {
if (BodySnake.Count > 0)
{
BodySnake[0].transform.position = transform.position;
for (int BodyIndex = BodySnake.Count - 1; BodyIndex > 0; BodyIndex--)
BodySnake[BodyIndex].transform.position = BodySnake[BodyIndex - 1].transform.position;
}
}
public void OnControllerColliderHit(ControllerColliderHit hit)
{
if (_testing)
{
Food food = hit.collider.GetComponent();
if (food != null)
{
// врезались в еду, "съедаем" ее
food.Eat();
AddTile();
}
else
{
// врезались не в еду
SceneManager.LoadScene ("GameOver");
}
_testing = false;
}
}
}Этот скрипт будет отвечать за движение нашей змейки, создавать хвост и увеличивать значение хвоста при взятии еды или загружать сцену GameOver при столкновении с препятствием. Переместите его на голову змейки. Добавьте еще один префаб в папку resouces, простую сферу (необходимо удалить sphere collider), это будет наш хвост. В скрипте Player укажите в строке Snake Body этот префаб.

Ну вроде все, запустите проект, но перед этим добавьте сцены в настройки проекта file- build settings


Пишите в комментариях ваши вопросы, постараемся на них ответить. Удачных проектов!
Архив с проектом можно скачать здесь.
Скачать игру можно здесь.
Видео созданной игры после небольшой визуальной доработке и добавления звуков
💥 Видео
Сделал простую игру в Unity 2019 (Змейка/Snake 3D)Скачать

КАК СОЗДАТЬ ПРОСТУЮ 3D ИГРУ НА UNITY? || Unity 3D C# Уроки Создание ИгрСкачать

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

Создание змейки в Unity. АнимацииСкачать

Создаем змейку в юнитиСкачать

Игра Змейка на Unity |1| Hyper-Casual GameСкачать

Научу создать игру на Unity за 5 минут!!! | GamicleСкачать

Сделал одинаковую игру на Unreal/Unity/GodotСкачать

01) Создаем основные элементы игры змейка Unity3dСкачать

Скретч уроки | Создай игру змейка в Скретч 🐍🍎Скачать

Создание 3D гонок на Unity 5 за 30 минут!Скачать





![🐍 Змейка с хвостом [Unity 3D] [Tutorial] (как в Snake VS Block или как в классической змейке)](https://i.ytimg.com/vi/EetWxwCxLOg/0.jpg)








Ссылка на архив, есть ли свежая ?