В этой статье я хочу рассказать вам как в игровом движке 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"); }GUILayout.FlexibleSpace(); // динамическое пространство между кнопками // отрисовка кнопки Exit и обработка ее нажатия if (GUILayout.Button(exitButtonText, buttonStyle, GUILayout.MinHeight(buttonMinHeight))) { // выход Application.Quit(); } GUILayout.FlexibleSpace(); // динамическое пространство между кнопкой Exit и низом области меню } GUILayout.EndArea(); } }Видео:Создаем игру Snake в Unity | уроки для новичковСкачать
Этот скрипт будет выводить наше меню на экран и при нажатии на кнопку 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; } } } }Видео:Создание змейки на Unity за 5 минутСкачать
Этот скрипт будет размещать префаб еды при старте сцены, давать очки при съедании объекта, удалять объект со сцены и создавать новую еду в рандомном месте. Перемещаем его на модель еды и сохраняем модель в префаб в папку 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;// генерируем уровень 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; } } }Видео:Создание игры Snake (Змейка) на Unity3DСкачать
Этот скрипт будет считать наши набранные очки и выводить их на экран, создавать препятствия в зоне наших ограждений и рандомно генерировать их на плоскости.
Создадим пустышку на сцене и перенесем на нее этот скрипт, так же можно указать материал который будет накладываться на препятствия.
Можете запустить игру и проверить что мы наделали. Как видите препятствия и еда генерируется в свободных местах, но змейка наша пока не двигается, этим мы сейчас и займемся.
Создадим еще один скрипт и назовем его 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");// вращаем трансформ вокруг оси 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; } } }Видео:🐍 Змейка с хвостом [Unity 3D] [Tutorial] (как в Snake VS Block или как в классической змейке)Скачать
Этот скрипт будет отвечать за движение нашей змейки, создавать хвост и увеличивать значение хвоста при взятии еды или загружать сцену GameOver при столкновении с препятствием. Переместите его на голову змейки. Добавьте еще один префаб в папку resouces, простую сферу (необходимо удалить sphere collider), это будет наш хвост. В скрипте Player укажите в строке Snake Body этот префаб.
Ну вроде все, запустите проект, но перед этим добавьте сцены в настройки проекта file- build settings
Пишите в комментариях ваши вопросы, постараемся на них ответить. Удачных проектов!
Архив с проектом можно скачать здесь.
Скачать игру можно здесь.
Видео созданной игры после небольшой визуальной доработке и добавления звуков
📹 Видео
Сделал простую игру в Unity 2019 (Змейка/Snake 3D)Скачать
Создание змейки в Unity. Скрипт контроллер и сбор едыСкачать
Создание змейки в Unity. АнимацииСкачать
КАК СОЗДАТЬ ПРОСТУЮ 3D ИГРУ НА UNITY? || Unity 3D C# Уроки Создание ИгрСкачать
Научу создать игру на Unity за 5 минут!!! | GamicleСкачать
Создаем змейку в юнитиСкачать
01) Создаем основные элементы игры змейка Unity3dСкачать
Игра Змейка на Unity |1| Hyper-Casual GameСкачать
Сделал одинаковую игру на Unreal/Unity/GodotСкачать
Создание 3D гонок на Unity 5 за 30 минут!Скачать
Скретч уроки | Создай игру змейка в Скретч 🐍🍎Скачать
Ссылка на архив, есть ли свежая ?