Все Гайды Мой Кабинет

Процедурная генерация бесконечного уровня 2D

Автор: Admin 15 дней назад

Приветствую начинающих разработчиков! Довольно часто для формирования уровня необходимо прибегать к её автоматической генерации для сокращения времени разработки игры. И реализовывать процедурную генерацию мы будем на примере 2д проекта.

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

Подготовительная часть

Предлагаю первым делом подготовить наш проект для работы, а потом разберёмся, что и для чего мы создали. Выполним 3 простых действия:

  • С поомщью окна Hierarchy создадим объект 2д, который будет являться нашим игровым персонажем. Назовём его Player. С помощью окна Inspector добавим ему 2 компонента: Rigidbody 2D и Circle Collider 2D. Ну и добавим данному объекту тег Player.
  • Создадим ещё один 2д объект, который будет являться задним фоном(баграундом) в нашей игре. Назовём его Background. Размер баграунда должен полностью покрывать размер камеры, и даже немного выходить за её пределы.
  • Внутри объекта Background, создадим 2д объект, с названием Point. Растянем его на 100% ширины экрана. Для удобства понимания, я этот объект перекрасил в зелёный цвет.(см. рисунок ниже).

В итоге на игровой сцене должно получится примерно так.

А в окне Hierarchy так.

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

Поскольку нам понадобиться бесконечно создавать баграунд, то сделайте из объекта Background префаб. А чтобы наша бесконечная сцена не состояла только из одних баграундов, давайте создадим ещё один какой-нибудь префаб из 2д объекта - у меня это летающая тарелка, назовём данный префаб Enemy. По желанию, можете добавить к нему различных компонентов (необязательно).

В итоге у нас получилось 2 префаба с именами Background и Enemy.

Обратите внимание, что у префаба видна зелёная полоса по центру, поскольку в данном префабе имеется объект Point, который и является данной зелёной полосой.

Работа со скриптами

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

Для начала создадим c# скрипт, который будет создавать новые объекты Background и Enemy на сцене. Назовём данный скрипт BackgroundCreate. Заранее присвойте его любому объекту, например вашей главной камере. Впишем в него следующий код:

using UnityEngine;

public class BackgroundCreate : MonoBehaviour
{
    public GameObject background;
    public GameObject enemy;

    public float minX = -3.5f;
    public float maxX = 3.5f;
    public float minY = -8f;
    public float maxY = 8f;

    public void CreateBackground(Transform parent)
    {
        Vector2 posBackground = new Vector2(parent.position.x, parent.position.y + 19.2f);
        GameObject newBackground = Instantiate(background, posBackground, Quaternion.identity);

        int randCount = Random.Range(1, 5);
        for(int i = 0; i < randCount; i++)
        {
            Vector2 posEnemy = new Vector2(parent.position.x + Random.Range(minX, maxX), parent.position.y + Random.Range(minY, maxY) + 19.2f);
            Instantiate(enemy, posEnemy, Quaternion.identity, newBackground.transform);
        }
    }
}

В строках #5-8 мы создали 2 переменные, в которых будут храниться ссылки на префабы Background и Enemy. Поэтому заранее предлагаю в окне Inspector перетащить в данные поля эти префабы.

В строках #8-11 мы указываем минимальные и максимальные координаты по осям X и Y, для создания объекта летающей тарелки(Enemy). Это делается для того, чтобы наши летающие тарелки создавались в случайных местах.

Мы так же создали метод CreateBackground(), который с помощью метода Instantiate() создаёт объекты Background и Enemy на +19.2f выше, от расположения предыдущего баграунда. Обратите внимание, что высота моего баграунда составляет 1920 пикселей, и чтобы правильно рассчитать, какое значение необходимо прибавить, мы должны 1920 делить на 100, и получаем 19.2. Например, если высота вашего баграунда составляет 1080 пикселей, то необходимо прибавить 10.8f для двух создаваемых объектов.

Хочу обратить ваше внимание, что именно в методе CreateBackground() вы формируете сам уровень. То-есть именно здесь вы определяете, какие, где и сколько объектов должно быть созданы. В качестве примера у меня создаётся один баграунд, и от 1 до 5 летающих тарелок. Но вы можете сделать генерацию под свой вкус.

Теперь необходимо создать скрипт, который будет этот метод вызывать. Создадим c# скрипт с названием Pointer, и заранее присвойте его объекту Point, который находиться внутри ПРЕФАБА Background (это важно). Впишите в него следующий код:

using UnityEngine;

public class Pointer : MonoBehaviour
{
    private BackgroundCreate backgroundCreate;

    private void Awake()
    {
        backgroundCreate = FindObjectOfType<BackgroundCreate>();
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            backgroundCreate.CreateBackground(transform.parent);
            Destroy(gameObject);
        }
    }
}

Здесь мы получаем ссылку на наш скрипт backgroundCreate, который мы создавали ранее, и который присвоен нашей камере. А с помощью метода OnTriggerEnter2D() проверяем, вошёл ли како-либо объект в область данного объекта. И если данный объект имеет тег Player, то запускаем метод CreateBackground(). А так же удаляем данный объект(зелёную горизонтальную линию), во избежании возможных проблем.

На этом всё. Можете запустить данный проект и убедиться, что всё работает отлично! И да, после запуска игры, перетаскивать объект придётся на сцене вручную, поскольку передвижение персонажа мы не затрагивали в данной теме, поскольку это тема для отдельного гайда, с которым Вы так же можете ознакомиться в отдельной статье.

На основе данной процедурной генерации, можно очень быстро и легко создать такую игру как Flappy Bird. Рекомендую так же ознакомится с новым гайдом о том, как создать игру Flappy Bird на юнити, которая на 90-95% создана на основе процедурной генерации уровня. Думаю ознакомление с данным гайдом будет очень полезным.

Ну а на этом всё. Если остались какие-либо вопросы, задавайте их в комментариях.

Вы можете отблагодарить автора донатом. Донат

Комментарии

0
Будьте первым, кто оставит комментарий к этому посту
Гости не могут оставлять комментарии. Войдите на Сайт или Зарегистрируйтесь