Создание пиксельной RPG с помощью Unity 3D

С помощью этого пошагового руководства вы сможете самостоятельно создать игру в жанре RPG в Unity.

План работы:

  1. Создание игрового мира с помощью тайловых карт.
  2. Базовая анимация для игрового персонажа.
  3. Простое взаимодействие объектов.
  4. Создание меню.

Посмотреть демо готовой игры можно здесь.

Начало работы

Создайте проект 2D Unity.

Добавьте образцы пользовательского интерфейса Unity из Asset Store. Этот актив будет использоваться для создания сцены меню.

Создайте в окне проекта следующее дерево папок (на русском или английском языке, в зависимости от вашей версии программы):

      • Animations

    ►Animals
    ►OtherCharacters
    ►Plants
    ►Players

        • Fonts
        • Prefabs
        • Scenes
        • Scripts
        • Sprites

    ►Animals
    ►HouseIndoor
    ►Houses
    ►Items
    ►Players
    ►Roads
    ►Rocks
    ►Tilesets

  • ►Vegetation
  • TilePalettes

Вы можете скачать любые бесплатные шрифты, которые вам нравятся и использовать их при работе с проектом (добавьте их в папку Шрифты/Fonts).
Что касается спрайтов, то вы можете воспользоваться этим сервисом для их создания, если у вас нет готового набора.
Объекты не должны превышать размер 64 на 64 пикселя
Персонаж и его экипировка могут быть созданы с помощью еще одного простого онлайн создателя спрайтов.
Большинство спрайтов размещено на листах спрайтов, которые вам необходимо предварительно нарезать в Unity 3D.

Выберите лист спрайтов в окне проекта, как показано на изображении ниже:

В инспекторе измените параметр Sprite Mode на Multiple и нажмите кнопку Sprite Editor:

Теперь в меню Slice выберите значение Type.

Лучший способ здесь — метод проб и ошибок, особенно, если вы не знаете точный размер ваших спрайтов (в противном случае просто вбейте известные значения).

Нажмите кнопку Slice и проверьте результат. Вы также можете переименовать каждый спрайт, щелкнув по нему мышкой.

После закрытия окна Slice, справа от листа спрайтов в окне проекта появляется небольшая кнопка; это позволяет видеть и получать доступ ко всем нарезанным вами спрайтам:

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

Для быстрой прорисовки базовых карт пиксельных RPG используется специальная палитра.

Откройте меню Window2DTile Palette.

Теперь создайте новую палитру и добавьте спрайты.

При необходимости можно добавить несколько палитр.

Теперь вам нужно выбрать нужные плитки:

И установите тип коллайдера в инспекторе.

Выбранные плитки должны иметь значение None, деревья и стены — Sprite или Grid.

Теги и слои
Создайте недостающие теги:

  • MapBackground
  • AICharacter

Создайте несколько слоев для хранения объектов.

Определите также порядок сортировки слоев в разделе Sorting Layers:

Создание анимации

Добавьте все типы имеющихся анимаций в один и тот же GameObject:

1.выбирайте все спрайты движения в одну сторону (на север)
2.перетаскивайте выбранные спраты в меню их в Hierarchy, чтобы добавить GameObject и сохранить анимационный клип
3. выбирайте оставшиеся спрайты движения и перетащите их на созданный GameObject
4. сделайте то же самое со всеми другими анимациями
5. Проверьте анимационные клипы в окне Animation (меню Window AnimationAnimation).

Добавьте камеру как дочерний элемент персонажа.

Это позволит перемещать камеру во время движения персонажа.

В инспекторе в разделе Sprite Renderer установите для параметра Sorting Layer значение Player.

Добавьте 2D-компонент Rigidbody.

Установите Gravity Scale = 0 и в разделе Constraints заморозьте вращение по Z.

Добавьте 2D-компонент Collider для взаимодействия с другими GameObject, такими как предметы или животные.

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

Откройте меню WindowAnimationAnimator.

Добавьте два  параметра: DirectionX и DirectionY.

Для каждого перехода определите в Инспекторе следующее:

►снимите галочку с Has Exit Time
►в разделе Settings снимите флажок Fixed Duration
►в разделе Settings установите Transition Duration на 0.
►определить условия (например, EastIdle WalkNorthDirectionY ⇒ 0, WalkNorth ⇒ IdleNorthDirectionX = 0 & DirectionY = 0)

Создайте новый скрипт PlayerMovement и прикрепите его к GameObject.

Добавьте этот код:

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

public class PlayerMovement : MonoBehaviour
{

[SerializeField]
private float speed;

[SerializeField]
private Animator animator;

void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");

Vector2 currentVelocity = gameObject.GetComponent<Rigidbody2D>().velocity;

float newVelocityX = 0f;
if (moveHorizontal < 0 && currentVelocity.x <= 0)
{
newVelocityX = -speed;
animator.SetInteger("DirectionX", -1);
}
else if (moveHorizontal > 0 && currentVelocity.x >= 0)
{
newVelocityX = speed;
animator.SetInteger("DirectionX", 1);
}
else
{
animator.SetInteger("DirectionX", 0);
}

float newVelocityY = 0f;
if (moveVertical < 0 && currentVelocity.y <= 0)
{
newVelocityY = -speed;
animator.SetInteger("DirectionY", -1);
}
else if (moveVertical > 0 && currentVelocity.y >= 0)
{
newVelocityY = speed;
animator.SetInteger("DirectionY", 1);
}
else
{
animator.SetInteger("DirectionY", 0);
}

gameObject.GetComponent<Rigidbody2D>().velocity = new Vector2(newVelocityX, newVelocityY);
}
}

Вернувшись в Инспектор, установите значения:

После чего создайте префаб персонажа.

В окне Project удалите Animation Controller, созданный при добавлении клипов анимации.

Создайте новый, используя контекстное меню Create ⇒ Animation Controller, и назовите его.

В окне Animator создайте два новых состояния из Blend Trees.

Переименуйте объекты в окне Inspector, IdleTree и MoveTree, как показано на изображени ниже.

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

Создайте два перехода и установите настройки и условия, как показано на изображениях ниже.

Создайте 4 новых параметра float:

►DirectionX
►НаправлениеY
►LastDirX
►LastDirY

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

Теперь дважды щелкните IdleTree:

установите Blend Type на 2D Simple Directional
установите Parameters в LastDirX и LastDirY
в разделе Motion добавьте 4 элемента.
для каждого движения добавьте параметр idle clip (вверх, вниз, вправо, влево) и установите значения PosX и PosY

Вернитесь к Base Layer и сделайте то же самое с MoveTree.

Вернувшись в окно Scene, проверьте, есть ли у GameObject игрока компонент Animator.

Если он существует, удалите его.

Перетащите вновь созданный контроллер из окна проекта в инспектор.

Создайте новый скрипт PlayerBlendMovement и добавьте его в плеер.

Добавьте этот код:

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

public class PlayerBlendMovement : MonoBehaviour
{
//Movement variables
public float MoveSpeed = 4f;

//Animation variables
Animator thisAnim;
float lastX, lastY;

// Start is called before the first frame update
void Start()
{
thisAnim = GetComponent<Animator>();
}

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

void Move()
{
Vector3 rightMovement = Vector3.right * MoveSpeed * Time.deltaTime * Input.GetAxis("Horizontal");
Vector3 upMovement = Vector3.up * MoveSpeed * Time.deltaTime * Input.GetAxis("Vertical");

Vector3 heading = Vector3.Normalize(rightMovement + upMovement);

transform.position += rightMovement;
transform.position += upMovement;

UpdateAnimation(heading);
}

void UpdateAnimation(Vector3 dir)
{
if((dir.x == 0f) && (dir.y == 0f))
{
//idle animation if no key pressed
thisAnim.SetFloat("LastDirX", lastX);
thisAnim.SetFloat("LastDirY", lastY);
thisAnim.SetBool("Movement", false);
}
else
{
lastX = dir.x;
lastY = dir.y;
thisAnim.SetBool("Movement", true);
}

thisAnim.SetFloat("DirectionX", dir.x);
thisAnim.SetFloat("DirectionY", dir.y);
}
}

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

Для начала рекомендуется создать несколько тайловых карт:

►карта мира
►тайловая карта помещений
►карта растений
►Карта дорог и скал

Т