Как сделать счетчик очков в unity 2d

Обновлено: 02.07.2024

Продолжаем делать наш Unity for dummies платформер.

Полные версии кода будут находиться в конце поста.

Если вы не в курсе, как работают хуки жизненного цикла в Unity, вы можете ознакомиться с данной статьёй.

Затем выбираем наш объект Player слева, в меню иерархии, и закрепляем инспектор (меню справа), нажав на замок в верхнем правом углу.

Пока закрываем все ненужные компоненты (Box Collider 2D, etc), нажимая на стрелочку у каждого из них.

Теперь перетаскиваем наш скрипт в инспектор, и он прикрепляется к объекту Player (если вы не выполнили предыдщуий пункт с закрепением меню, то вы этого сделать не сможете).

Если зайти в Edit => Project Settings => Input Manager, то мы можём увидеть настройки управления. Например, прыжок (Jump) назначен на пробел, в то время, как движение по горизонтали назначено на a, d, ←,→.

Запомним это для того, чтобы затем использовать в коде (названия инпутов Jump, Horizontal).

Пора покодить. Два раза нажимаем на наш скрипт PlayerBehaviour, и Unity отдаст его в руки Visual Studio.

Честно, данную IDE я не люблю. Потому я открываю его в VScode (а вы хоть в VIMе пишите - это ваш выбор).

Я не буду часто использовать try/catch в этом коде, но вам очень советую - сильно экономит время.

Исправляем код, и страшные красные буквы исчезают. Можно запустить игру, и проверить, как все работает.

Мне не нравится, что персонажа переворачивает. Исправим.

Заходим в инспектор, открываем Rigidbody2D и ставим галочку на Freeze Rotation Z.

Жить можно, но есть проблема - камера не двигается за персонажем.

Есть два основных способа научить камеру двигаться за персонажем.

1. Подвинуть камеру внутри сцены, чтобы она была на персонаже, а затем в привязать камеру к объекту персонажа через меню иерархии.

2. Задать движение камеры за персонажем програмно.

Создаём скрипт CameraBehaviour, и привязываем его к объекту Main Camera (добавляем через инспектор).

Открываем наш новый скрипт, и начинаем кодить (да, мне на работе не хватает, продолжаю и после).

Фиксируем объект камеры на замок в инспекторе, и перетаскиваем наш объект Player в GameObject.

Теперь камера двигается за игроком.

Однако камера постоянно вылезает за пределы уровня, показывая синий фон.

Я не уверен, что моё решение правильное. Буду рад, если кто-нибудь поделится своими соображениями на данный счёт.

Если у камеры пропала рамка (у меня, внезапно, случилась такая оказия - потратил аж 2 минуты на решение проблемы), надо зайти в Gizmos и отметить чекбокс на камере.

Добавляем в наш скрипт CameraBehaviour следующий код:

[Header("Camera position restrictions")] public float minY; public float maxY; public float minX; public float maxX;

Двигаем камеру, и снимаем наши измерения ее положений.

На скрине ниже камера стоит в левом нижнем углу сцены.

Исходя из поля Position, я выбираю минимум по Х = -12, по Y = -0.5 (числа округлены их -12.09 и -0.84) соответсвенно.

Проставляем снятые позиции для камеры (мои и ваши позиции будут отличаться).

Теперь обновим метод UpdateCameraPosition в скрипте CameraBehaviour

Mathf.Clamp принимает первым аргументом позицию объекта, за которым следует игрок, вторым и третим аргументами минимум и максимум - этими значениями метод будет ограничивать число, которые по итогу получит камера в качестве своей координаты.

Отлично, камера перестала "гулять". Работаем дальше.

Всё бы хорошо, но наш персонаж может летать - надо всего лишь жать кнопку прыжка. Добавим проверку на нахождение на земле.

Выбираем наш Foreground, и создаём новый слой 'Ground' в инспекторе.

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

Переходим к коду.

Добавим в PlayerBehaviour такую строчку.

Теперь в объекте Player мы можем выбрать наш свежесозданный слой.

Обновляем наш PlayerBehaviour. Добавим коллайдер (rigidBody мы создавали ранее).

Теперь мы можем обновить обработку перемещения персонажа в методе updatePlayerPosition

Тут я вспомнил, что забыл глянуть, как "наделся" Box Collider на персонажа. Кажется, все ок - линии идут ровно по персонажу (жёлтая рамка). Если что, всегда можно ткнуть на Edit Collider и подтянуть его.

Летать мы разучились, а по платформе больше не скользим. Победа!

  • Из-за слоя Ground персонаж может прыгать от стенок. Не знаю, как это можно решить.
  • Является ли ограничение движения камеры, которое я написал, отимальным.
  • Иногда персонаж застревает на месте. Такое ощущение, что коллайдер видит какой то микропиксель, и персонаж застревает на нём.

Я не уверен, что моё решение правильное. Буду рад, если кто-нибудь поделится своими соображениями на данный счёт

Привет.
Я, конечно, дохуя вовремя, когда у тебя уже пять статей и рефакторинг, но вот щас иду за тобой пока вот на этом месте.
Короче, в ассет-сторе есть проект 2D Game Kit от разрабов движка. Там движение камеры сделано буквально следующим образом, если помню (давно открывал). Уровень завёрнут в коллайдер, ещё один коллайдер на камере. Соответственно, когда она о него стукается, то расслабляется и не двигается. И ещё там угарный камера-лаг стоит, чтоб камера не жёстко следовала за персонажем, а как бы за верёвочку.

Привет.
Да, я изначально так и пробовал.
Но персонаж, почему-то, попросту исчезает при старте игры.
Попробую ради эксперимента новый проект создать.

Надо разобраться куда исчезает. Самое простое, поставить на паузу, перейти из окна Game в Scene, и просто посмотреть. А потом уже делать выводы.

Это вторая часть туториала о 2Д игре платформере. Вам понадобятся некоторые игровые рессурсы для этого туториала. Скачайте .zip архив здесь. Также вы можете скачать первую часть туториала здесь. Запустите юнити проект с первой частью туториала и загрузите сцену scenePlatformer.

Как сделать стену:

Как собирать и подсчитывать монеты:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CoinController : MonoBehaviour

//звук сбора монеты
public AudioClip CoinSound;
//переменная количества собранных монет
public int coin;

//запустится если collider2D попал в триггер
void OnTriggerEnter2D ( Collider2D other) //проверка, имеет ли попавший объект тэг Coin
if (other.tag == "Coin" ) //увеличить счетчик монет
coin = coin + 1 ;
//проиграть звук поднятия монеты на позиции крысы
AudioSource .PlayClipAtPoint (CoinSound, transform.position);
//удалить монету из сцены
Destroy (other.gameObject);
>
>
>

Добавьте этот скрипт к крысе. Импортируйте звук CoinSound в проект. Выберите крысу в иерархии и поместите CoinSound в поле Coin Sound (чейчас мы используем 3Д позиционирование звука и он будет относительно тихим, так как восприятие звука находится на камере. Мы потом переделаем Audio Listener для более правильного звука).

Теперь сделаем простой интерфейс для отображения количества монет. Добавьте новый UI - Text. Будет созданно три новых объекта: Canvas, Text, EventSystem.

Выделите Canvas в иерархии. Измените UI Scale Mode на Scale With Screen Size и Screen Match Mode на Expand. С этими параметрами будет неплохое скалирование размера интерфейса на разных экранах.

Сцена и интерфейс теперь находятся в одном экране. Сделайте двойной клик на Canvas в иерархии. Камера сфокусируется на белом прямоугольнике. Этот прямоугольние представляет как будет выглядеть экран в игре.

Выберите Text в иерархии. Сделайте его больше и перетащите на то место, где он должен отображаться. Измените привязку на право-вверх. Измените Text на 0. Alignment на середину. Включите Best Fit (заполнение пространства). Измените Max Size на что-то около 100. Настройте Color по желанию.

Нам нужен скрипт для управления текстом. Откройте снова скрипт CoinController.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//эта библиотека нужна для работы с интерфейсом
using UnityEngine.UI;

public class CoinController : MonoBehaviour

//ссылка на объект с текстом
public GameObject TextObject;
//ссылка на текстовый компонент
Text textComponent;
//звук поднятия монеты
public AudioClip CoinSound;
//переменная подсчета монет
public int coin;

//запустится один раз при запуске скрипта
void Start () //делаем линк на текстовый компонент, который находится на текстовом объекте
textComponent = TextObject.GetComponent Text > ();
>

//запустится если collider2D попал в триггер
void OnTriggerEnter2D ( Collider2D other) //проверка, имеет-ли объект тэг Coin
if (other.tag == "Coin" ) //увеличить переменную подсчета монет
coin = coin + 1 ;
//записать в текст результат счета монет, преобразованный в текстовую переменную
textComponent.text = coin.ToString();
//проиграть звук поднятия монеты на позиции крысы
AudioSource .PlayClipAtPoint (CoinSound, transform.position);
//удалить монету из сцены
Destroy (other.gameObject);
>
>
>

Сфокусируйте камеру назад в сцену (сделайте двойной клик по крысе в иерархии). Выберите Rat в иерархии. У скрипта CoinController пояаилось новое поле Text Object. Поместите объект Text в это поле. Интерфейс теперь должен отображать значение переменной сбора монет. Запустите игру и проверьте это.

Как сделать яму:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//это библиотека для работы со сценами
using UnityEngine.SceneManagement;

public class DeadEndController : MonoBehaviour

//запустится если 2D collider попал в триггер
void OnTriggerEnter2D ( Collider2D other) //проверка, имеет ли объект тэг Player
if (other.tag == "Player" ) //ппосмотреть название текущей сцены и загрузить её (reload)
SceneManager .LoadScene ( SceneManager .GetActiveScene().name);
>
>
>

Выберите DeadEnd в иерархии и добавьте этот скрипт. Создайте префаб DeadEnd (перетащите DeadEnd из иерархии в Assets.)

Как сделать простого врага:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//библиотека для управления сценами
using UnityEngine.SceneManagement;

public class MushroomController : MonoBehaviour

//как далеко гриб может отойти от начальной точки
public float distanceToRun;
//скорость движения
public float speed;
//направление взгляда гриба
public bool isLookingLeft = true ;
//стартовая позиция
Vector3 startPos;
//линк на компонент Rigidbody2D
Rigidbody2D rb;

//выполнится 1 раз при старте игры
void Start () //делаем линк на Rigidbody2D компонент
rb = GetComponent Rigidbody2D > ();
//запоминаем стартовую точку гриба
startPos = transform.position;
//будем сравнивать квадрат вектора расстояния с квадратом расстояния
//так как извлечение корня медленный процесс
distanceToRun = distanceToRun * distanceToRun;
>

//выполняется на каждом фиксированном интервале
void FixedUpdate () //проверить, смотрит-ли гриб влево
if (isLookingLeft) //посчитать вектор направления от стартовой точки к грибу
Vector2 dist = transform.position - startPos;
//проверить, что гриб слева от стартовой точки
//и расстояние между грибом и стартовой точкой больше разрешенного удаления
if (transform.position.x distanceToRun) //вызвать функцию поворота гриба
TurnTheMushroom ();
//начать движение направо
rb.velocity = new Vector2 (speed, rb.velocity.y);
//если проверка была негативной
> else //продолжить движение влево
rb.velocity = new Vector2 (-speed, rb.velocity.y);
>
>
//проверить, что гриб смотрит вправо
if (!isLookingLeft) //посчитать вектор направления от стартовой точки к грибу
Vector2 dist = transform.position - startPos;
//проверить, что гриб справа от стартовой точки
///и расстояние между грибом и стартовой точкой больше разрешенного удаления
if (transform.position.x > startPos.x && dist.sqrMagnitude > distanceToRun) //вызвать функцию поворота гриба
TurnTheMushroom ();
//начать движение налево
rb.velocity = new Vector2 (-speed, rb.velocity.y);
//если проверка была негативной
> else //продолжить движение направо
rb.velocity = new Vector2 (speed, rb.velocity.y);
>
>
>
//функция поворота гриба
void TurnTheMushroom ()
//инвертировать (изменить на противоположный) указатель направления взгляда
isLookingLeft = !isLookingLeft;
//повернуть гриб
transform.localScale = new Vector3 (transform.localScale.x * -1 , transform.localScale.y, transform.localScale.z);
>

//запустится, если коллайдер коснулся другого коллайдера
void OnCollisionEnter2D ( Collision2D other) //проверить, что у коллайдера тэг Player
if (other.collider.gameObject.tag == "Player" ) //посмотреть имя загруженной сцены и загрузить такую сцену (reload)
SceneManager .LoadScene ( SceneManager .GetActiveScene().name);
>
>

//запустится, если другой коллайдер попал в триггер
void OnTriggerEnter2D ( Collider2D other) //проверить, что у коллайдера тэг Player
if (other.tag == "Player" ) //удалить гриб
Destroy (gameObject);
>
>
>

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ExplosionsDestroyer : MonoBehaviour

//как долго взрыв будет в сцене
public float timeToDestroy;

//выполнится один раз при старте скрипта
void Start () //удалить взрыв из сцены
Destroy (gameObject, timeToDestroy);
>
>

Выберите Explosion в иерархии. Добавьте этот скрипт к Explosion. Измените Time To Destroy на 1. Создайте префаб Explosion. После создания префаба удалите взрыв из сцены (правый клик на Explosion в иерархии и нажать Delete).

Теперь добавим взрыв и его звук к скрипту гриба. Откройте скрипт MushroomController.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//библиотека для управления сценами
using UnityEngine.SceneManagement;

public class MushroomController : MonoBehaviour

//префаб взрыва
public GameObject Explosion;
//звук взрыва
public AudioClip Boom;
//как далеко гриб может отойти от начальной точки
public float distanceToRun;
//скорость движения гриба
public float speed;
//направление взгляда гриба
public bool isLookingLeft = true ;
//стартовая позиция гриба
Vector3 startPos;
//линк на компонент Rigidbody2D
Rigidbody2D rb;

//выполнится один раз при старте гриба
void Start () //делаем линк на компонент Rigidbody2D
rb = GetComponent Rigidbody2D > ();
//запоминаем стартовую позицию гриба
startPos = transform.position;
//будем сравнивать квадрат вектора расстояния с квадратом расстояния
//так как извлечение корня медленный процесс
distanceToRun = distanceToRun * distanceToRun;
>

//выполняется на каждом фиксированном интервале
void FixedUpdate () //проверить, что гриб смотрит налево
if (isLookingLeft) //посчитать вектор направления от стартовой точки к грибу
Vector2 dist = transform.position - startPos;
//проверить, что гриб слева от стартовой точки
//и расстояние между грибом и стартовой точкой больше разрешенного удаления
if (transform.position.x distanceToRun) //вызвать функцию поворота
TurnTheMushroom ();
//начать движение направо
rb.velocity = new Vector2 (speed, rb.velocity.y);
//если проверка была отрицательной
> else //продолжить движение налево
rb.velocity = new Vector2 (-speed, rb.velocity.y);
>
>
//проверить, что гриб смотрит направо
if (!isLookingLeft) //посчитать вектор направления от стартовой точки к грибу
Vector2 dist = transform.position - startPos;
//проверить, что гриб справа от стартовой точки
//и расстояние между грибом и стартовой точкой больше разрешенного удаления
if (transform.position.x > startPos.x && dist.sqrMagnitude > distanceToRun) //вызвать функцию поворота
TurnTheMushroom ();
//начать движение налево
rb.velocity = new Vector2 (-speed, rb.velocity.y);
//если проверка была отрицательной
> else //продолжить движение направо
rb.velocity = new Vector2 (speed, rb.velocity.y);
>
>
>
//функция поворота гриба
void TurnTheMushroom ()
//изменить указатель направления взгляда на противоположный
isLookingLeft = !isLookingLeft;
//повернуть гриб
transform.localScale = new Vector3 (transform.localScale.x * -1 , transform.localScale.y, transform.localScale.z);
>

///запустится, если коллайдер коснулся другого коллайдера
void OnCollisionEnter2D ( Collision2D other) //проверить, что у коллайдера тэг Player
if (other.collider.gameObject.tag == "Player" ) //посмотреть имя загруженной сцены и загрузить такую сцену (reload)
SceneManager .LoadScene ( SceneManager .GetActiveScene().name);
>
>

//запустится, если другой коллайдер попал в триггер
void OnTriggerEnter2D ( Collider2D other) //проверить, что у коллайдера тэг Player
if (other.tag == "Player" ) //спавн взрыва
Instantiate (Explosion, transform.position, Quaternion .identity);
//проиграть звук взрыва
AudioSource .PlayClipAtPoint (Boom, transform.position);
//удалить гриб
Destroy (gameObject);
>
>
>

Импортируйте звуковой файл Boom в Assets. Выберите Enemy в иерархии. У Mushroom Controller появилось два новых поля в скрипте. Поместите префаб Explosion в Explosion поле. Поместите аудиофайл Boom в поле Boom. Сделайт префаб Enemy. проверьте сцену.

Восприятие звука:

По стандарту, Audio Listener (компонент отвественный за восприятие звука) прикреплен к Main Camera. Audio Listener можно представить как виртуальные уши. Смотрите Unity Documentation для подробностей. Надо передвинуть этот компонент к крысе. Выберите Main Camera (дочерний объект крысы) ит отключите Audio Listener в Inspector (нам нужен только один такой компонент в сцене).

Выьерите Rat в иерархии и добавьте Audio Listener к ней.

Проверьте сцену.

Как сделать движущуюся платформу:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlatformMoving : MonoBehaviour

//скорость движения платформы
public float speed;
//позиция, где платформа должна повернуть назад
public Transform endPoint;
//позиция начала движения
Vector3 startPoint;
//ссылочная переменная для компонента Rigidbody2D
Rigidbody2D rb;
//скорость платформы в текущий момент
float currentSpeed;

//выполнится при запуске скрипта
void Start () //запомнит стартовую точку платформы
startPoint = transform.position;
//сделать ссыдку на Rigidbody2D
rb = GetComponent Rigidbody2D > ();
//начальное направление движения
currentSpeed = speed;
>

Создайте новый пустой объект (empty).
Назовите его endPoint. Добавьте к нему иконку для лучшего вида. Поместите endPoint над Platform (испольуйте инструмент движения).

Выберите Platform в иерархии. Добавьте скрипт PlatformMoving. Измените Speed на 1. Поместите endPoint в поле End Point.

Запустите игру и проверьте (можете переключить на сцену, пока игра запущена).

Поместите wall в сцену справа от платформы. Выьерите эту стену в иерархии и добавьте Box Collider 2D.

Поместите следующий Dead End префаб в сцену под двигающейся платформой. Нажмите на Edit Collider и настройте размер.

Как добавить физические объекты:

Импортируйте картинку Box из скачанного архива. Поместите спрайт Box в сцену (на движущуюся платформу). Выьерите Box в иерархии. Измените Tag и Layer на Ground. Смените Z-позицию на 0. Добавьте Rigidbody 2D. Измените Interpolate на Interpolate. Добавьте Box Collider 2D.

Теперь сможете взаимодействовать с этим объектом.

Конец уровня:

Добавьте Ground префаб в сцену, где платформа перестаёт двигаться наверх (смотрите скриншот). Добавьте последнбб стену (поместите спрайт wall в сцену и добавьте Box Collider 2D ).

Импортируйте картинку Exit в Assets. Добавьте спрайт Exit в сцену возле последней стены. Крыса не должна допрыгивать до Exit, если она просто прыгает с пола. Boxпонадобится как подставка. Выберите Exit в иерархии. Добавьте Box Collider 2D. Включите Is Trigger. Добавьте Dead End Controller. У нас сейчас нет следуюшего уровня, поэтому просто перезагрузим сцену.

Как сделать движущийся фон с эффектом параллакс:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Parallax : MonoBehaviour

//ссылочная переменная на игрока
GameObject player;
//позиция игрока в предыдущем кадре
//и разница в позиции между кадрами
Vector3 lastPos, offset;
//скорость движения фона
public float speed;

//выполнится один раз при запуске скрипта
void Start () //делаем линк на игрока
player = GameObject .FindWithTag ( "Player" );
//запоминаем его позицию
lastPos = player.transform.position;
>

//выполняется каждый кадр
void Update () //посчитать разницу в позициях между кадрами
offset = player.transform.position - lastPos;
//пересчитать разницу в зависимости от скорости и передвинуть фон по полученному вектору
//Time.deltaTime корректировка для разного фпс
transform.Translate (offset * speed * Time .deltaTime);
//перезаписать позицию в текущем кадре
lastPos = player.transform.position;
>
>

Импортируйте BackGround в Assets. Поместите BackGround в сцену. Измените X и Y Scale на 4. Передвиньте на позицию крысы (смотрите скриншот). Измените Order in Layer на -100. Добавьте Parallaxскрипт. Измените Speed на 60 (потестите разные настройки).

Как добавить фоновую музыку:

Теперь простое. Импортируйте звуковой файл Music. Выберите Rat в иерархии. Перетащите Music на Rat ы иерархии (или добавьте Audio Source и поместите Music в поле AudioClip field). Включите Loop.

Проверьте сцену.

Создание префаба монеты легко и похоже на создание лазера, так что вы должны попробовать сделать это самостоятельно. Просто используйте спрайт с монетой и следуйте за нашими советами:

  • Не создавайте скрипты для монеты.
  • используйте Circle Collider 2D вместо Box Collider 2D.
  • Включите Trigger option для коллайдера, так как мы не хотим, чтобы монеты останавливали движение мыши.

Если вам все еще непонятно, читайте далее.

  1. Откройте папку Sprites во вкладке Project.
  2. Перетащите спрайт coin на сцену и выберите его в Иерархии.
  3. В инспекторе установите его Sorting Layer в Objects.
  4. Добавьте компонент Circle Collider 2D
  5. Включите свойство Is Trigger в коллайдере
  6. Установите Radius коллайдера 0.23

Вот изображение, показывающее все необходимые шаги:

Этапы создания префаба монеты

После создания игрового объекта с монетой (coin), перетащите его из Иерархии в папку Prefabs, что во вкладке Project, для создания префаба.

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

Теперь добавьте несколько монет на сцену с помощью перетаскивания префаба coin на вкладку Scene. Сделайте нечто вроде этого:

Горсть монет на сцене

rocket_mouse_unity_p3_67

Подождите секунду - почему мышь умирает сразу же, как только касается монеты? Неужели они ядовитые?

Нет, с монетами все в порядке. Мышь умирает из-за кода в скрипте MouseController, который обрабатывает любое столкновение.

Использование тегов, чтобы отличать монеты от лазеров

Чтобы отличить монеты от лазеров вы будете использовать теги, которые сделаны именно для этой цели.

Выберите coin Prefab прямо в папке Prefabs во вкладке Project. Это откроет свойства префаба в Инспекторе. Найдите выпадающий список Tag прямо под полем name, откройте его и выберите Add Tag. (Добавить тег).

Добавление тега в Unity

Это откроет уже знакомый редактор Tags & Layers в Инспекторе. В секции Tags добавьте тег по имени Coins.

Это автоматически увеличит Size до 2 и добавит Element 1, но это нормально.

Теперь выберите coin Prefab во вкладке Project еще раз, и установите его Tag в Coins в Инспекторе.

rocket_mouse_unity_p3_71

Обновление скрипта MouseController

Откройте скрипт MouseController и добавьте переменную счетчика coins:

Здесь вы будете хранить число собранных монет. Теперь добавьте метод CollectCoin:

Этот метод увеличивает количество монет и удаляет монету со сцены, чтобы вы не столкнулись с ней во второй раз. Теперь внесите следующие изменения в OnTriggerEnter2D:

С этими изменениями вы вызываете CollectCoin при сборе монет и HitByLaser во всех остальных случаях.

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

rocket_mouse_unity_p3_72

В настоящее время у вас есть префаб, который состоит только из одной монеты, так что, если вы пишете код генерации монет, вы просто создать только одину монету на уровне. Это очень скучно! Как насчет создания различных фигур из монет и генерации нескольких монет сразу?

Создание префаба из кучи монет

Откройте папку Prefabs во вкладке Project и создайте 9 монеток на сцене, используя префаб coin. Это должно выглядеть примерно так:

9 монеток на сцене

Выберите любую монету и установить ее Position в (0, 0, 0). Это будет центральная монета. Вы добавите все монеты в пустой игровой объект, поэтому вам надо будет добавлять их рядом с началом координат.

После размещения центральной монеты, , создайте вокруг монеты фигуру в виде перевернутого треугольника. Помните, что вы можете воспользоваться Vertex Snapping, если зажмете клавишу V.

Центральная монета в треугольнике

Теперь создайте пустой игровой объект выбрав GameObject\Create Empty. Выберите его в Иерархии и переименуйте в coins_v.

Установите его Position в (0, 0, 0), так что у него будет тоже положение, что и у центральной монеты. После этого выберите все монеты в Иерархии и добавьте их в coins_v. Вы должны получить что-то вроде этого в Иерархии:

Игровой объект coins_v

Выберите coins_v в Иерархиии и перетащите ее в папку Prefabs во вкладке Project для создания префаба.

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

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

Дело сделано. Теперь удалите все монеты и лазеры со сцены, так как теперь они будут генерироваться скриптом.

Добавление новых параметров в GeneratorScript

Откройте GeneratorScript и добавьте следующие переменные экземпляра:

Массив availableObjects, будет содержать все объекты, которые могут генерироваться скриптом (т.е. различные группы монет и лазеров). Список objects будет хранить созданные объекты, так, чтобы вы могли проверить, нужно ли добавлять что-то перед игроком, либо удалять их, если они за пределами экрана.

Так же, как участки комнаты, вы можете создать несколько лазеров, или монет в начале уровня, уровня там, где вы не хотите полагаться на генератор случайных чисел. Только не забудьте добавить их в список объектов.

Переменные objectsMinDistance и objectsMaxDistance используются для определения случайного расстояния между последним объектом и добавляемым, так что объекты не появляются с постоянным интервалом.

Используя objectsMinY и objectsMaxY вы можете настроить максимальную и минимальную высоту, на которой размещены объекты, а с помощью objectsMinRotation и objectsMaxRotation вы можете настроить диапазон поворота.

Добавление метода для добавления нового объекта

Новые объекты добавляются в AddObject подобно тому, как добавляются участки комнаты. Добавьте следующее:

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

Вот описание каждого блока кода:

  1. Генерирует случайный индекс для генерируемого объекта. Это может быть лазер, или кучка монет.
  2. Создает экземпляр объекта, который выбирается случайно.
  3. Установка позиции объекта с использованием случайного интервала и случайной высоты. Это контролируется с помощью параметров скрипта.
  4. Добавление случайного вращения для вновь размещенных объектов.
  5. Добавляет только что созданный объект в список объектов для отслеживания и, в конечном счете, удаления (когда объект покидает экран).

Генерирование и удаление объектов в случае необходимости

Добавьте следующее в GeneratorScript:

Этот метод проверяет, нужно ли добавить или удалить объект где-то в пределах класса GeneratorScript Вот последовательность его действий:

    Расчет ключевых точек впереди и позади игрока.

Если лазер, или монеты находятся левее removeObjectsX, то они уже вне экрана и их придется удалить.

Если нет объекта после AddObject точка, то вам нужно добавить больше объектов, так как последний из созданных объектов скоро появится на экране.

Переменная farthestObjectX используется, чтобы найти позицию последнего (крайнего справа) объекта для сравнения ее с addObjectX.

Для того, чтобы этот метод работал, добавьте вызов GenerateObjectsIfRequired в конце FixedUpdate:

Этот метод вызывается каждый раз, гарантируя, что всегда будут существовать объекты впереди игрока.

Настройка параметров скрипта

Для того, чтобы GeneratorScript работал, вам нужно установить несколько параметров. Вернитесь обратно в Unity и выберите Игровой объект mouse в Иерархии.

найдите компонент Generator Script в Инспекторе и убедитесь, что папка Prefabs открыта во вкладке Project.

Перетащите префаб coins_v из вкладки Project в список Available Objects компонента GeneratorScript. Проделайте те же действия с префабом laser.

Перетаскивание coins_v и laser

Это оно! Запустите сцену.

В приведенном выше анимированном GIF лазеры не вращаются, потому что я установил rotationSpeed параметра LaserScript в 0 (с вращающимися лазерами довольно трудно записать хорошее видео игрового процесса).

Теперь, то, что мы видим, выглядит как почти законченная игра! В следующем уроке мы поработаем с GUI, чтобы добавить счетчик очков.

🏓 Создаем 2D-игру на Unity: инструкция для новичка

Недавно мы рассказали о том, как научиться разработке игр на Unity . Продолжим тему на практике и покажем, как новичку создать на этой платформе первую 2D-игру.

Если вы хотите получить более систематическое образование в области разработки игр, мы рекомендуем рассмотреть факультет разработки игр онлайн-университета GeekBrains.

Двумерные игры сравнительно просты: для них не требуется сложных 3D-моделей, программный код по сравнению с 3D-проектами выглядит понятнее. Такие игры популярны как на десктопах, так и на мобильных устройствах. Unity также позволяет разрабатывать игры и для браузеров.

За последние годы вышло много популярных двумерных игр:

Программная реализация 2D-игр проще не только из-за отсутствия третьего измерения: на самой сцене меньше объектов, вместо трехмерных моделей плоские спрайты, вместо скелетной анимации – покадровая. А еще 2D-игры проще портировать на другие платформы – легче найти новую аудиторию.

Давайте создадим простую игру в жанре пинг-понг 🏓 . Перед тем как приступить к созданию игры, продумайте, какой именно результат хотите получить. На первых этапах рекомендуется использовать схематические шаблоны, чтобы быстрее получить работающий результат. В этой инструкции мы так и поступим. Графических ресурсов использовать не будем: и ракетки, и отбиваемый мяч будем пока отображать простыми белыми спрайтами.

Предварительно рассмотрим основные понятия Unity, без понимания которых будет проблематично создать игру:

Предполагаем, что вы уже установили редактор и создали аккаунт на портале Unity.

В первую очередь создадим новый проект и откроем его настройки (Edit → Project Settings). Во вкладке Editor установим параметр Default Behaviour Mode в значение 2D

Настройка проекта Детальная настройка проекта

Следующим шагом сохраним текущую активную сцену, назвав ее, например, Scene1. Теперь создадим основные игровые объекты: ракетку, мяч и менеджер игры, в котором будет храниться основная логика игры.

1. Создаем пустой объект, переименовываем в GameManager.

Создаем пустой объект

Создаем пустой объект

3. Создаем квадратный спрайт, называем его Pad (Assets → Create → Sprites → Square). Аналогично создаем круглый спрайт Ball (Assets → Create → Sprites → Circle). Масштабируем спрайт Pad со следующими параметрами – x:0.5, y:2.5, z:1.

Создаем спрайты

Создаем спрайты

4. Создаем префабы для Pad и Ball, после чего добавляем к ним компонент Box Collider 2D (включаем параметр Is Trigger) и компонент Rigidbody 2D (выставляем параметр Body Type в значение Kinematic).

Добавляем .компонент Box Collider 2D Настраиваем.компонент Box Collider 2D Добавляем компонент Rigidbody 2D Масштабируем спрайты

6. Заполняем скрипты следующим кодом.

GameManager.cs Ball.cs Pad.cs

6. Добавляем к префабу Ball и Pad теги с аналогичными именами. Выделив префабы, в инспекторе мы можем видеть выпадающий список тегов. Там же расположены и кнопки для добавления и редактирования тегов.

7. В настройках камеры выставляем параметр Projection в значение Orthographic, а параметр Clear Flag – в значение Solid Color.

Настройка камеры

Настройка камеры

8. Настраиваем кнопки, как показано на следующих скриншотах (Edit → Project Settings → Input Manager).

Настройка ввода, основное Настройка ввода, первый игрок Настройка ввода, второй игрок

Вот и всё, игра готова!

Пинг-понг, итоговый результат

Пинг-понг, итоговый результат

Билд для платформы Windows

1. Официальный туториал от Unity, где детально рассмотрен процесс создания roguelike RPG.

2. Youtube-канал Brackeys , где можно найти серию видеоуроков по созданию 2D-платформера.

3. Youtube-канал N3K EN содержит множество уроков как по отдельным компонентам Unity, так и полноценные серии уроков по созданию игр с нуля.

Если у вас мало опыта в разработке игр на Unity, мы рекомендуем обратить внимание на факультет разработки игр GeekBrains . Материал хорошо структурирован и содержит все необходимое для того, чтобы стать профессиональным Unity-разработчиком.

В числе прочего вы разработаете 2D-платформер с физическими загадками и динамическим освещением, научитесь портировать его на мобильные устройства. Кроме того, разработаете полноценную браузерную стратегию, а также игру в жанре двухмерных гонок.

По окончании обучения вы будете иметь портфолио из 4 игр, которое можно показать на собеседовании. Если же какая-то часть материала будет непонятна, вы всегда можете обратиться к персональному преподавателю.

Читайте также: