В преддверии старта курса Unity Game Developer. Basic делимся с вами интересной статьёй, которую подготовил один из наших друзей, который выступил в роли автора.


Предисловие

В этом руководстве мы узнаем, как создать Doom в Unity. Как обычно, все будет максимально просто.

Мы сосредоточимся на следующих элементах шутера от первого лица:

  • WSAD-Движение и прыжки

  • Осматриваясь с помощью мыши

  • Прилично выглядящее оружие

  • Пули, взрывающиеся при ударе

  • Прилично выглядящий уровень

  • Во что стрелять

Теперь части «движение» и «осмотр с помощью мыши» звучат как сумасшедшая математика. Но, как обычно, Unity позаботится об этом за нас. У нас останется всего 50 строк кода для игры (что ... безумие) .

Предварительный просмотр видео

Вот видео финальной игры:

Требования

Знания

Это руководство требует некоторого понимания основ Unity. Если вы никогда раньше не использовали Unity, ознакомьтесь с нашими более простыми учебниками по Unity, такими как Unity 2D Pong Game .
Если вы уже знакомы с основами Unity, пора нам начать. Помните: это просто!

Версия Unity

Мы создали эту игру с помощью Unity 4.5.1f3, но любая более новая версия тоже подойдет.
Мы не будем использовать какие-либо дополнительные функции, поэтому бесплатная версия Unity - это все, что нужно.

Художественный стиль

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

Настройка проекта и сцены

Мы начнем с создания нового проекта Unity через File -> New Project .. в каталоге типа C: / unity_fps. Мы также импортируем пакеты Character Controller и Particles, как показано ниже:

Примечание: пакет Character Controller будет использоваться для движения и просмотра мышью, пакет Particles будет использоваться для взрывов.

После этого мы сохраняем его один раз через File -> Save Scene с именем «scene_main» (без «»).

Примечание: сохраненная сцена просто содержит все, что есть в Иерархии.

Уровень

Хорошая игра FPS требует красивого уровня.
Мы решили создать красивую 3D-модель для нашего уровня:

Хотя мы предоставляем уровень как загрузку для членов Premium, мы по-прежнему рекомендуем вам создать его самостоятельно с примитивами Unity (см. Верхнее меню: GameObject -> Create Other -> Cube / Sphere / Capsule / Cylinder / Plane ).

Просто начните с плоскости (в качестве земли), добавьте несколько кубиков (в качестве стен) и наложите на них текстуры. Если вы не торопитесь, вы можете очень легко создать прилично выглядящий уровень.

Камера движения от первого лица

Добавление контроллера

Теперь давайте перейдем к самой сложной части каждого шутера от первого лица: реализации WSAD-движения в сочетании с правильной камерой от первого лица.

Те, кто когда-либо пытался сделать это самостоятельно, поймут, насколько важным является достижение Unity's First Person Controller . Он заботится обо всей математике и позволяет нам добавлять WSAD-движение с камерой от первого лица всего за несколько щелчков мыши.

Контроллер от первого лица Unity можно найти в области наших проектов в разделе «Стандартные активы»:

Перетащим его в Иерархию:

И разместите его так, чтобы он соответствовал нашему уровню:

Это будет плохая позиция, потому что она находится за пределами уровня:

Небольшие корректировки

Нам нужно внести три небольших изменения в наш контроллер от первого лица.

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

Нам не нужен тот, который был там по умолчанию, поэтому давайте удалим его (тот, который НЕ является частью контроллера от первого лица, который является нижней основной камерой на нашем рисунке).

Давайте выберем основную камеру, которая все еще находится в иерархии, и посмотрим на Инспектор. Здесь мы изменим цвет фона на черный (выберите все, что вам нравится) и отключим скрипт Mouse Look :

Примечание: есть один сценарий Mouse Look, прикрепленный к «Контроллеру от первого лица», и еще один, прикрепленный к «Основной камере» (тот, который мы только что отключили).
Первый отвечает за горизонтальный вид мыши, второй - за вертикальный.
Мы отключили вертикальное отображение мыши, потому что это изящное решение игрового дизайна. Это требует от игрока прыжка, если он хочет стрелять по более высоким целям.

Если мы нажмем кнопку Play, мы уже можем перемещаться с помощью клавиш W, S, A и D, прыгать с ПРОБЕЛОМ и использовать мышь, чтобы осматриваться.

Это было действительно просто, учитывая, сколько сумасшедшей математики потребуется, чтобы сделать это вручную.

Оружие

План

Хорошо, давайте дадим игроку оружие. Как обычно, мы могли создать причудливую 3D-модель, что довольно сложно. Или мы можем использовать примитивы Unity с несколькими текстурами на них.

Вот как будет выглядеть финальное оружие:

Шутер от первого лица делает нашу жизнь намного проще. Игрок видит только верхнюю левую часть оружия, поэтому мы можем полностью оставить все остальные стороны подальше.

Оружие GameObject

Давайте создадим пустой GameObject через GameObject -> Create Empty и назовем его оружием . Это будет родитель (или другими словами: контейнер) для частей модели оружия.

Мы хотим, чтобы оружие было прикреплено к игроку, чтобы оно меняло свое положение при изменении положения игрока. Это очень просто благодаря Иерархии Unity. Все, что нам нужно сделать, это сделать оружие дочерним по отношению к основной камере , перетащив его на основную камеру:

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

Примитивы

Создадим модель оружия. Мы создаем три куба через GameObject -> Create Other -> Cube, а затем перемещаем их в GameObject оружия в Иерархии:

Теперь все, что нам нужно сделать, это расположить , повернуть , масштабировать и наложить на них текстуру, чтобы они выглядели как верхняя левая часть оружия:

Правильное расположение

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

Куб 1 GameObject :

Куб 2 GameObject :

Куб 3 GameObject :

Это прозрачная текстура, которая использовалась: 

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

После наложения текстуры на кубики мы можем выбрать шейдер Unlit / Transparent, чтобы увидеть прозрачность в Unity:

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

Ракетная стрельба

Модель

И снова мы будем использовать примитивы Unity для создания модели Rocket:

На этот раз мы не хотим, чтобы Ракета постоянно находилась в Иерархии. Вместо этого мы перетаскиваем его из Иерархии в область проекта, что создает префаб :

После этого мы удаляем Ракету из Иерархии. Тем не менее, мы по-прежнему хотим, чтобы он находился в области «Проект».

О физике

Мы хотим, чтобы ракета была «физическим предметом». Он должен иметь возможность сталкиваться со стенами (или игроками), и нам нужен способ заставить его лететь вперед, как только игрок выстрелит в него.

Мы можем добиться обоих эффектов, просто добавив к ракете Rigidbody через Component -> Physics -> Rigidbody . Придадим ему следующие свойства:

Примечание: мы замораживаем вращение, потому что ракета должна просто лететь вперед, не вращаясь в воздухе или что-то еще. Остальные параметры более-менее точны.

Взрыв от удара

Давайте создадим сценарий, чтобы мы могли узнать, когда Ракета во что-то попала. Щелкните правой кнопкой мыши в области Project, выберите Create -> C # Script и назовите его Rocket . Нашему скрипту нужны только две общедоступные переменные и одна функция:

using UnityEngine;
using System.Collections;

public class Rocket : MonoBehaviour {
    // The fly speed (used by the weapon later)
    public float speed = 2000.0f;

    // explosion prefab (particles)
    public GameObject explosionPrefab;

    // find out when it hit something
    void OnCollisionEnter(Collision c) {
        // show an explosion
        // - transform.position because it should be
        //   where the rocket is
        // - Quaternion.identity because it should
        //   have the default rotation
        Instantiate(explosionPrefab,
                    transform.position,
                    Quaternion.identity);

        // destroy the rocket
        // note:
        //  Destroy(this) would just destroy the rocket
        //                script attached to it
        //  Destroy(gameObject) destroys the whole thing
        Destroy(gameObject);
    }
}

Функция OnCollisionEnter будет вызываться Unity всякий раз, когда Rocket с чем-то сталкивается. Все, что нам осталось сделать, это спровоцировать взрыв, а затем уничтожить саму ракету.

Вот как наша сборная ракета выглядит в инспекторе после добавления к ней скрипта (перетаскивая его туда):

Пришло время взрыва. И снова Unity нам помогает. Мы уже импортировали частицы Unity при создании проекта, и они уже содержат эффект взрыва, который нам подходит.

Итак, давайте заглянем в область Project в разделе Standard Assets -> Particles -> Legacy Particles и перетащим небольшой префаб взрыва в слот Explosion Prefab нашего скрипта Rocket, чтобы он выглядел так:

И еще кое-что: по умолчанию Взрыв взрывается снова и снова, поэтому давайте выберем префаб Small Explosion в области Project и включим опцию One Shot :

Мы только что закончили Ракету. Скоро мы сможем увидеть его в действии!

Сценарий стрельбы

Хорошо, давайте снова создадим новый сценарий C # , на этот раз мы назовем его Shoot . Предполагается, что этот скрипт будет порождать новую ракету всякий раз, когда игрок щелкает мышью. Затем он использует метод AddForce Rigidbody, чтобы заставить его лететь вперед:

using UnityEngine;
using System.Collections;

public class Shoot : MonoBehaviour {
    // Rocket Prefab
    public GameObject rocketPrefab;

    // Update is called once per frame
    void Update () {
        // left mouse clicked?
        if (Input.GetMouseButtonDown(0)) {
            // spawn rocket
            // - Instantiate means 'throw the prefab into the game world'
            // - (GameObject) cast is required because unity is stupid
            // - transform.position because we want to instantiate it exactly
            //   where the weapon is
            // - transform.parent.rotation because the rocket should face the
            //   same direction that the player faces (which is the weapon's
            //   parent.
            //   we can't just use the weapon's rotation because the weapon is
            //   always rotated like 45° which would make the bullet fly really
            //   weird
            GameObject g = (GameObject)Instantiate(rocketPrefab,
                                                   transform.position,
                                                   transform.parent.rotation);

            // make the rocket fly forward by simply calling the rigidbody's
            // AddForce method
            // (requires the rocket to have a rigidbody attached to it)
            float force = g.GetComponent<Rocket>().speed;
            g.rigidbody.AddForce(g.transform.forward * force);
        }
    }
}

Как объясняется в комментариях к коду, единственная интересная часть здесь - это функция transform.parent.rotation . Он нужен для того, чтобы Ракета летела точно вперед (точно в направлении игрока). Если бы мы использовали transform.position, это заставило бы Ракету лететь точно вперед в направлении оружия, но оружие поворачивается немного влево, что заставит Ракету лететь немного влево.

Теперь мы сохраняем скрипт, добавляем его к оружию и перетаскиваем Rocket Prefab из области Project в слот Rocket Prefab, чтобы он выглядел так:

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

Мы можем легко предотвратить это, отключив (или удалив) все компоненты Collider, которые находятся на нашем оружии или на его дочерних элементах (кубиках).

Если мы нажмем Play, теперь мы можем бегать и стрелять ракетами по вещам:

Мы только что закончили основную механику нашего шутера от первого лица на Unity!

Бычьи глаза

Давайте сделаем игру немного веселее, добавив несколько Bull's Eyes, которые можно использовать для практики стрельбы.

Как обычно, мы начнем с создания модели с примитивами Unity:

Вот используемая нами текстура Bull's Eye:

Теперь мы добавляем два пустых GameObject к Scene, которые определяют левую и правую точки (предполагается, что Bull's Eye перемещается между ними вперед и назад):

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

using UnityEngine;
using System.Collections;

public class BullsEye : MonoBehaviour {
    // left and right marks
    public Transform left;
    public Transform right;

    // speed
    public float speed = 1.0f;

    // current direction (false means to the left, true means to the right)
    bool dir = false;
   
    // Update is called once per frame
    void Update () {
        if (dir) {
            // go closer to the right one
            transform.position = Vector3.MoveTowards(transform.position,
                                                     right.position,
                                                     Time.deltaTime * speed);

            // reached it?
            if (transform.position == right.position)
                dir = !dir; // go to opposite direction next time
        } else {
            // go closer to the left one
            transform.position = Vector3.MoveTowards(transform.position,
                                                     left.position,
                                                     Time.deltaTime * speed);

            // reached it?
            if (transform.position == left.position)
                dir = !dir; // go to opposite direction next time
        }
    }
}

Интересная часть здесь - это переменная dir . Если dir истинно, то «Бычий глаз» перемещается в нужную точку. Если dir ложно, он перемещается в левую точку. Он инвертирует значение dir всякий раз, когда достигает точки.

Теперь мы просто добавляем скрипт к модели Bull's Eye, перетаскиваем левую и правую точки в левый и правый слоты и все.

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

Резюме

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

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

Комментарии (6)


  1. Quiensabe
    27.12.2021 02:47
    +9

    Мы создали эту игру с помощью Unity 4.5.1f3

    Зачем? Unity 4.5.1 вышла в 2014 году...

    "Покупайте наш курс по современным технологиям в строительстве, а в качестве примера нашего подхода - "как выкопать траншею ломом".


  1. OptimumOption
    27.12.2021 07:57

    Стилизация под Майнкрафт не понравилась...


  1. HexGrimm
    27.12.2021 08:39
    +3

    Статья сработает как анти-реклама :) "Вы выбрали устаревший и вредный в текущих реалиях материал для перевода" хотел я написать, но не увидел тега перевод. Это оригинал?


  1. MadDAD
    27.12.2021 10:05

    Doom на Unity

    и прыжки

    После этого дочитал "по-диагонали" до создания уровня вручную и на этом чтение закончил...


  1. Wolf4D
    27.12.2021 10:06

    Unity 4.5.1f3 вызывает реакцию "где ж вы его достали, болезные?". Его же чтобы скачать - надо лезть в глубокие дебри. Статья не просто древняя, а относится ко временам ранней античности. Плюс, многие вещи (типа Legacy Particles) уже во времена ветки 4.x были, эм... замшелым легаси. Уже после 5.x они сгинули, если я верно помню. Способы импорта стандартных ассетов изменились... ну и так далее.

    Перевод (и да, я по скринам узнал источник) ужасен. Кто называет ассеты активами, что это за мрак? "Бычьи глаза" - что, простите?! Вы вообще проверяли текст после гуглотранслейта?

    И да, причём тут Doom? Вам не стыдно, люди?


    1. Wolf4D
      27.12.2021 10:10