Добро пожаловать в новую серию попыток воссоздать некоторые механики популярной игры Cult of The Lamb. В этой серии будет использоваться шаблон конечного автомата, который я написал на днях. Я надеюсь, что в этой серии вы сможете увидеть силу шаблонов программирования и то, насколько полезными они могут быть. Если вы хотите продолжить серию, вот что мы делали до сих пор:

  • Ground Zero: автомат начальных состояний в 2D-платформере
  • Часть 1: Движение в 3D и сопровождение камеры
  • Часть 2: Прокачка персонажа
  • Часть 3: Анимируем как программист
  • Часть 4: Состояние комбо атаки часть 1

Первые шаги

Первое, что нам нужно изменить из этой серии, — превратить наш 2D-проект в 3D. Unity работает с обоими очень похоже, поэтому изменение будет плавным. Здесь есть отличная ссылка.

Мой подход заключается в использовании 3D-мира с 2D-спрайтами.

Не забудьте также изменить вид в редакторе. Также добавьте 3D-плоскость в качестве пола.

В этом кратком уроке мы воссоздадим движение и камеру очень простыми шагами.

Камера

Импортируйте пакеты Cinemachine с помощью диспетчера пакетов.

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

Затем измените свойство Follow на ваш Player.

Движение

Для движения нам нужно изменить некоторые компоненты на плеере. Измените Rigidbody2D на Rigidbody и установите для него эти свойства. Также теперь мы используем SphereCollider и размещаем его вокруг ног.

В классе PlayerStateMachine измените ссылку Rigidbody2D на Rigidbody и измените сигнатуру функции Move с получения Vector2 на Vector3:

...

[SerializeField] private Rigidbody _rigidbody;

...

public void Move(Vector3 velocity)
{
    _rigidbody.velocity = velocity;
}

В папке с вашими состояниями создайте новый скрипт C# и назовите его PlayerMove3DState. Теперь добавьте этот код:

using BerserkPixel.StateMachine;
using UnityEngine;

namespace Player.States
{
    [CreateAssetMenu(menuName = "States/Player/Move 3D")]
    public class PlayerMove3DState : State<PlayerStateMachine>
    {
        [SerializeField, Range(250f, 500f)] private float _speed = 300f;

        private Vector3 _playerInput;

        public override void Tick(float deltaTime)
        {
            _playerInput = new Vector3(_runner.Movement.x, 0, _runner.Movement.y);
        }

        public override void FixedTick(float fixedDeltaTime)
        {
            _runner.Move(_playerInput * (_speed * fixedDeltaTime));
        }

        public override void ChangeState()
        {
            if (_playerInput == Vector3.zero)
            {
                _runner.SetState(typeof(PlayerIdleState));
            }
        }
    }
}

Этот код идентичен PlayerMoveState, который мы сделали в предыдущем уроке, но мы изменили переменную _playerInput на Vector3 и установили ее на оси «x» и «z». в зависимости от ввода пользователей. Это оси вправо и вперед соответственно, и в 3D они обычно используются для перемещения объектов.

Наконец, вернитесь в редактор, щелкните правой кнопкой мыши на панели «Проект» и создайте новый объект PlayerMove3DState Scriptable.

В Инспекторе игрового объекта Player назначьте Rigidbody и замените старое состояние Move на новое 3D-состояние Move.

и альт! Нажимай play и начинай двигаться!

Если поворот неправильный, измените функцию CheckFlipSprite внутри PlayerStateMachine на поворот с отрицательным значением:

_spriteTransform.Rotate(_spriteTransform.rotation.x, -180f, _spriteTransform.rotation.z);

Авеста: Генератор процедурных тайлмап

Прата: Диалоги за секунды

Pointo: RTS Blueprints

Первоначально опубликовано на https://itch.io.