Контроллер игрока в жанрах RTS и MOBA для Unity

В видеоиграх термин RTS означает стратегию в реальном времени.

Отличие RTS от обычных шутеров от первого/третьего лица заключается в том, что управление персонажами осуществляется с помощью указателя мыши, а не обычных кнопок W, A, S и D.

Игроку предоставляется обзор поля боя с возможностью отдавать приказы войскам, не управляя ими напрямую. Примерами игр RTS являются Warcraft, Starcraft, Cossacks и т. д.

Скриншот геймплея Варкрафт 3

С другой стороны, MOBA означает Multiplayer Online Battle Arena, это несколько новый поджанр игр RTS, в которых игрок управляет только одним персонажем вместо многих.

Примерами таких игр являются League of Legends и Dota 2.

В этом уроке я покажу, как создать контроллер в стиле RTS/MOBA в Unity.

Шаг 1: Давайте создадим необходимые скрипты.

Это руководство довольно простое, так как для него требуется только один скрипт.

RTSPlayerController.cs

//You are free to use this script in Free or Commercial projects
//sharpcoderblog.com @2018

using UnityEngine;
using UnityEngine.AI;

[RequireComponent(typeof(NavMeshAgent))]

public class RTSPlayerController : MonoBehaviour
{
    public Camera playerCamera;
    public Vector3 cameraOffset;
    public GameObject targetIndicatorPrefab;
    NavMeshAgent agent;
    GameObject targetObject;

    // Use this for initialization
    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
        //Instantiate click target prefab
        if (targetIndicatorPrefab)
        {
            targetObject = Instantiate(targetIndicatorPrefab, Vector3.zero, Quaternion.identity) as GameObject;
            targetObject.SetActive(false);
        }
    }

    // Update is called once per frame
    void Update()
    {
#if (UNITY_ANDROID || UNITY_IOS || UNITY_WP8 || UNITY_WP8_1) && !UNITY_EDITOR
            //Handle mobile touch input
            for (var i = 0; i < Input.touchCount; ++i)
            {
                Touch touch = Input.GetTouch(i);

                if (touch.phase == TouchPhase.Began)
                {
                    MoveToTarget(touch.position);
                }
            }
#else
        //Handle mouse input
        if (Input.GetKeyDown(KeyCode.Mouse0))
        {
            MoveToTarget(Input.mousePosition);
        }
#endif

        //Camera follow
        playerCamera.transform.position = Vector3.Lerp(playerCamera.transform.position, transform.position + cameraOffset, Time.deltaTime * 7.4f);
        playerCamera.transform.LookAt(transform);
    }

    void MoveToTarget(Vector2 posOnScreen)
    {
        //print("Move To: " + new Vector2(posOnScreen.x, Screen.height - posOnScreen.y));

        Ray screenRay = playerCamera.ScreenPointToRay(posOnScreen);

        RaycastHit hit;
        if (Physics.Raycast(screenRay, out hit, 75))
        {
            agent.destination = hit.point;

            //Show marker where we clicked
            if (targetObject)
            {
                targetObject.transform.position = agent.destination;
                targetObject.SetActive(true);
            }
        }
    }
}

Шаг 2

Теперь давайте настроим контроллер игрока и игровой уровень.

  • Создайте новый GameObject и назовите его 'RTSPlayer'
  • Прикрепите к нему скрипт RTSPlayerController.cs (ПРИМЕЧАНИЕ. После присоединения он автоматически добавит еще один компонент с именем NavMeshAgent, этот компонент понадобится позже)

  • Добавьте тело игрока (в моем случае я буду использовать простую капсулу с кубом, но вы можете добавить модель игрока, если она у вас есть). Уменьшите его до нужного размера.
  • Переместите модель игрока внутри игрового объекта 'RTSPlayer' (ПРИМЕЧАНИЕ. Перед созданием родительского объекта убедитесь, что 'RTSPlayer' расположен внизу модели игрока)

  • Выберите 'RTSPlayer' и в NavMeshAgent настройте радиус и высоту, пока они не будут соответствовать модели игрока.

  • Далее нужно создать целевой индикатор prefab. Это простой GameObject с квадратом, который будет указывать, где мы нажали на карте.

Вы можете использовать текстуру ниже:

Целевой индикатор стратегии в реальном времени

  • И наконец, выберите 'RTSPlayer' и назначьте все необходимые переменные в скрипте RTSPlayerController:

Камера игрока — понятно, это может быть любая камера.

Camera Offset - насколько далеко должна находиться камера от игрока

Target Indicator Prefab — только что созданный префаб.

В режиме игры вы заметите, что нажатие на карту не заставляет игрока двигаться. Это потому, что нам осталось сделать последнее: запечь Навигационную сетку (Navmesh):

  • Выделите все объекты, являющиеся частью карты, и отметьте их как статичные:

  • Перейдите в Окно -> AI -> Навигация.

  • На вкладке «Выпечка» измените значения «Радиус агента» и «Высота агента» (они должны соответствовать значениям из NavMeshAgent), затем нажмите «Выпечка».

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

ПРИМЕЧАНИЕ. Чтобы игрок не мог ходить по холмам, вернитесь на вкладку «Запекание» и уменьшите угол максимального уклона, а затем повторно запекайте навигационную сетку.

Намного лучше!

Наконец, вернитесь в режим игры и щелкните левой кнопкой мыши где-нибудь на карте.

Теперь игрок должен двигаться к цели, избегая препятствий:

Sharp Coder Видео проигрыватель

Совет: настройте значение скорости, угловой скорости и ускорения в NavMeshagent в соответствии с вашими потребностями.

Источник
📁RTSMOBAController.unitypackage5.05 MB
Рекомендуемые статьи
Планетарный контроллер игрока на основе твердого тела для Unity
Учебное пособие по контроллеру проигрывателя сверху вниз для Unity
Учебное пособие по прыжкам через стену Player 3D и 2D для Unity
Контроллер вертолета для Unity
Добавление поддержки двойного прыжка в контроллер персонажей 2D-платформера в Unity
Автомобильный контроллер для Unity
Контроллер самолета для Unity