Как сделать игру, если ты ниче не умеешь

Дисклеймер:

  • делать будем на Unity

  • частично код взят отсюда — https://www.youtube.com/watch? v=j48LtUkZRjU&list=PLPV2KyIb3jR5QFsefuO2RlAgWEz6EvVi6&index=1
    Изменена логика подсчета score, а также механика смерти и победы, поэтому данную статью нельзя считать полноценным переводом, это все-таки туториал

  • надо знать C# на базовом уровне

  • Unity можно не знать, но надо установить

  • полный исходный код здесь — https://github.com/nomilkinmyhome/cube-runner

  • делать будем 3D-раннер с препятствиями

  • если у вас есть базовые знания Unity, для вас этот туториал бесполезен

  • автор тоже ниче не умеет, поэтому если есть какие-то предложения по улучшению — PR are welcome

Создание проекта и первый запуск

Нужно открыть Unity Hub и тыкнуть «New project». В появившемся окне сделать так:

Создание проекта

Создание проекта

Название проекта, естественно, указывайте любое. У меня это CubeRunner. После этого надо нажать «Create project».

После этого вы увидите нечто похожее:

Пустой базовый проект

Пустой базовый проект

Слева находится «Hierarchy» — в нем хранится иерархия всех объектов на сцене, в нашем случае это будет игрок, дорожка, препятствия и камера. По центру находится сцена, в ней две вкладки — «Scene» и «Game». Scene доступна нам в любой момент, мы можем ее использовать для размещения и редактирования объектов на сцене, а вот на Game мы переключаемся во время запущенной игры. Справа находится «Inspector», он пока что пустой, однако если выбрать любой объект в иерархии (например, «Main Camera»), то в инспекторе мы увидим характеристики выбранного объекта:

Инспектор

Инспектор

Философия Unity такова, что он принуждает разработчика по максимуму использовать редактор. Многие вещи мы будем настраивать через инспектор (такие, как, например, физика объектов). На самом деле в данном туториале кода на C# будет не так много и он будет достаточно простым.

Внизу расположена вкладка «Project», где видно, например, наши скрипты, материалы и другие объекты. Рядом с ней есть «Console» — сюда полезно заглядывать во время отладки, здесь вы найдете логи.

Создание дорожки

Начнем с создания дорожки, по которой будет бежать (а точнее катиться) игрок. Для этого нужно нажать ПКМ по иерархии, выбрать »3D Object»«Cube».

Создание объекта

Создание объекта

В окне сцены выбираем Scale Tool, а потом растягиваем куб по z и x, чтобы сделать его прямой дорожкой. Сам куб в иерархии надо переименовать в Ground для удобства.

Дорожка

Дорожка

Или же можно в инспекторе сразу задать такие значения:

Настройки дорожки

Настройки дорожки

Также давайте заранее создадим тег Ground и назначим его нашему «кубу». Для этого надо в инспекторе выбрать »Tag»«Add Tag…», в появившемся окне написать «Ground», а после этого назначить в том же выпадающем списке наш новый созданный тег. Это нам понадобится тогда, когда мы будем кодить.

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

Создание игрока

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

Настройки позиции игрока

Настройки позиции игрока

После этого вы должны увидеть длинную дорожку и куб на ней.

Давайте теперь покрасим куб, чтобы он отличался от дорожки и будущих объектов. Для этого внизу, в окне «Project», тыкнем ПКМ, выберем «Create»«Material», назовем его PlayerMaterial и зададим ему цвет в инспекторе такой, который нравится. У меня это зеленый.

Материал для игрока

Материал для игрока

А теперь просто зажимаем ЛКМ на созданном материале и перетаскиваем мышкой на Player в иерархии. После этого куб должен стать зеленым.

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

В иерархии у нас есть уже созданный объект Main Camera. Тыкаем на него, в инспекторе нажимаем «Add Component» и пишем «PlayerCamera», после чего Unity ничего не найдет и предложит нам создать новый скрипт с таким названием — нажимаем «New Script»«Create and Add». Таким образом можно создавать скрипты. Также вместо этого вы можете просто в окне «Project» нажать ПКМ и создать скрипт, а потом добавить его как компонент к какому-то объекту, но это более быстрый путь.

Unity создаст скрипт со следующей заготовкой:

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

public class PlayerCamera : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

Как следует из комментариев, функция Start вызывается один раз в самом начале игры, а функция Update вызывается 1 раз при каждом новом фрейме.

В данном случае нам функция Start не нужна, ее можно удалить. Напишите следующий код:

using UnityEngine;

public class PlayerCamera : MonoBehaviour
{
    public Transform player;
    public Vector3 offset;

    void Update()
    {
        transform.position = player.position + offset;
    }
}

Здесь мы создаем объект класса Transform. Он хранит в себе информацию о позиции игрока. Также мы создаем объект класса Vector3 — он будет хранить в себе сдвиг камеры относительно позиции игрока. После этого в функции Update мы просто ставим камеру с учетом заданного смещения.

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

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

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

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

Движение игрока

Теперь сделаем так, чтобы наш куб-игрок двигался. Для этого выберем Player в иерархии и добавим ему скрипт в инспекторе, который мы назовем PlayerControls.cs. Вот его содержимое:

using UnityEngine;

public class PlayerControls : MonoBehaviour
{
    public Rigidbody rb;
    public float forwardForce = 2000f;
    public float sidewaysForce = 500f;

    void Update()
    {
        rb.AddForce(0, 0, forwardForce * Time.deltaTime);

        if (Input.GetKey("d")) {
            rb.AddForce(sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
        } else if (Input.GetKey("a")) {
            rb.AddForce(-sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
        }
    }
}

Здесь мы создаем объект типа Rigidbody — кстати, его нужно добавить в инспекторе игроку как компонент и проставить ему следующие значения:

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

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

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

Следующие две переменные у нас типа float — это forwardForce и sidewaysForce, они хранят в себе силу, с которой будет двигаться игрок. forwardForce хранит силу движения вперед, sidewaysForce — по сторонам. Вы также можете поиграться с их значениями в редакторе и посмотреть как вам будет лучше.

Метод AddForce объекта Rigidbody задает силу движения по трем координатам — x, y, z. На 11 строке мы задаем силу движения вперед, оставляя x и y по нулям, т.к. нас интересует, чтобы наш игрок каждый кадр по дефолту двигался вперед без каких-либо дополнительных нажатий.

Далее на строках 13–17 мы вызываем тот же метод, только в этот раз в зависимости от нажатия на клавиши A или D мы меняем позицию игрока по x — либо увеличиваем ее и сдвигаемся вправо, либо уменьшаем и сдвигаемся влево.

Четвертым аргументом у нас передается ForceMode.VelocityChange. Он нужен для того, чтобы объект двигался с заданной силой и игнорированием массы этого объекта. Попробуйте просто убрать этот 4-й аргумент, запустить игру и посмотреть что из этого получится, чтобы лучше понять разницу.

Также мы везде умножаем силу на Time.deltaTime — это нужно для того, чтобы привязать движение игрока ко времени внутри игры.

Завершение

Теперь можно сохранить все скрипты и нажать Play в Unity. Вы увидите, как камера следует за кубом по белой дорожке, можете также понажимать A и D для смещения влево или вправо. В следующих частях туториала рассмотрим как добавлять препятствия, score, смерть и победу.

© Habrahabr.ru