Контролер RTS і MOBA Player для Unity

У відеоіграх термін RTS означає стратегію в реальному часі.

Різниця між RTS і звичайними шутерами від першої та третьої особи полягає в тому, що персонажами керують за допомогою вказівника миші, а не звичайних кнопок W, A, S і D.

Гравцеві надається орлиний огляд поля бою з можливістю віддавати накази військам, не керуючи ними безпосередньо. Прикладами ігор RTS є Warcraft, Starcraft, Cossacks тощо.

Скріншот гри Warcraft 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 із Quad, який вказуватиме, де ми клацнули на карті.

Ви можете використовувати текстуру нижче:

цільовий індикатор стратегії в реальному часі

  • І, нарешті, виберіть 'RTSPlayer' і призначте всі необхідні змінні в сценарії RTSPlayerController:

Камера плеєра - не пояснює, це може бути будь-яка камера

Camera Offset - на якій відстані має бути камера від гравця

Target Indicator Prefab - префаб, який ми щойно створили

Перебуваючи в режимі гри, ви помітите, що клацання на карті не змушує гравця рухатися. Це тому, що нам залишилося зробити останнє, а саме запекти Navigation Mesh (Navmesh):

  • Виділіть усі об’єкти, які є частиною карти, і позначте їх статичними:

  • Перейдіть до «Вікно» -> AI -> «Навігація».

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

  • Після завершення випікання ви помітите синювату окреслену сітку, яка представляє зону, по якій можна пройти.

ПРИМІТКА. Щоб запобігти переходу гравця через пагорби, поверніться на вкладку «Випікання» та зменшіть максимальний кут нахилу, а потім повторно обсмажте навігаційну сітку.

Значно краще!

Нарешті, поверніться в режим відтворення та клацніть лівою кнопкою миші десь на карті.

Тепер гравець повинен рухатися до цілі, уникаючи перешкод:

Sharp Coder Відеоплеєр

Порада: налаштуйте значення швидкості, кутової швидкості та прискорення в NavMeshagent відповідно до ваших потреб.

Джерело
📁RTSMOBAController.unitypackage5.05 MB
Рекомендовані статті
Посібник з контролера програвача згори вниз для Unity
Планетарний контролер гравця для Unity на основі жорсткого корпусу
Контролер 2D символів для Unity
Контролер вертольота для Unity
Автомобільний контролер для Unity
Контролер літака для Unity
Впровадження системи паркур в Unity