Kontroler odtwarzacza RTS i MOBA dla Unity

W grach wideo termin RTS oznacza strategię czasu rzeczywistego.

Różnica między RTS a konwencjonalnymi strzelankami z perspektywy pierwszej/trzeciej osoby polega na tym, że postaciami steruje się za pomocą wskaźnika myszy, a nie zwykłych przycisków W, A, S i D.

Gracz otrzymuje widok na pole bitwy z lotu ptaka i może wydawać rozkazy żołnierzom, bez bezpośredniego ich kontrolowania. Przykładami gier RTS są Warcraft, Starcraft, Cossacks itp.

Zrzut ekranu z gry Warcraft 3

Z kolei MOBA to skrót od Multiplayer Online Battle Arena, czyli nieco nowszy podgatunek gier RTS, w których gracz steruje tylko jedną postacią, a nie wieloma.

Przykładami takich gier są League of Legends i Dota 2.

W tym samouczku pokażę, jak utworzyć kontroler w stylu RTS/MOBA w Unity.

Krok 1: Stwórzmy niezbędne skrypty

Ten samouczek jest dość prosty, ponieważ wymaga tylko jednego skryptu.

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);
            }
        }
    }
}

Krok 2

Teraz skonfigurujmy kontroler gracza i poziom gry.

  • Utwórz nowy obiekt GameObject i wywołaj go 'RTSPlayer'
  • Dołącz do niego skrypt RTSPlayerController.cs (UWAGA: po dołączeniu automatycznie doda kolejny komponent o nazwie NavMeshAgent, ten komponent będzie potrzebny później)

  • Dodaj ciało gracza (w moim przypadku użyję prostej kapsuły z kostką, ale możesz dodać model gracza, jeśli taki posiadasz). Zmniejsz go do żądanego rozmiaru.
  • Przenieś model gracza do obiektu GameObject 'RTSPlayer' (UWAGA: przed objęciem funkcji rodzicielskich upewnij się, że 'RTSPlayer' znajduje się na dole modelu gracza)

  • Wybierz 'RTSPlayer' i w NavMeshAgent dostosuj Promień i Wysokość, aż będą zgodne z modelem odtwarzacza

  • Następnym krokiem jest utworzenie wskaźnika celu prefab. To po prostu prosty GameObject z Quadem, który wskaże, gdzie kliknęliśmy na mapie.

Możesz użyć poniższej tekstury:

wskaźnik celu strategii czasu rzeczywistego

  • Na koniec wybierz 'RTSPlayer' i przypisz wszystkie niezbędne zmienne w skrypcie RTSPlayerController:

Kamera gracza – to oczywiste, może to być dowolna kamera

Camera Offset - jak daleko kamera powinna znajdować się od gracza

Prefabrykat wskaźnika celu - prefabrykat, który właśnie stworzyliśmy

Będąc w trybie gry, zauważysz, że kliknięcie na mapę nie powoduje ruchu gracza. To dlatego, że mamy jeszcze jedną rzecz do zrobienia, czyli upiecz siatkę nawigacyjną (Navmesh):

  • Wybierz wszystkie obiekty będące częścią mapy i oznacz je jako statyczne:

  • Przejdź do Okno -> AI -> Nawigacja

  • Na karcie Pieczenie zmień wartości Promień agenta i Wysokość agenta (powinny one odpowiadać wartościom z NavMeshAgent), a następnie kliknij Piecz.

  • Po zakończeniu pieczenia zauważysz niebieskawą siatkę, która reprezentuje obszar, po którym można chodzić.

UWAGA: Aby uniemożliwić graczowi chodzenie po wzgórzach, wróć do zakładki Pieczenie i zmniejsz maksymalny kąt nachylenia, a następnie ponownie wypal siatkę nawigacyjną.

Dużo lepiej!

Na koniec wróć do trybu odtwarzania i kliknij lewym przyciskiem myszy gdzieś na mapie.

Gracz powinien teraz ruszyć w stronę celu, omijając przeszkody:

Sharp Coder Odtwarzacz wideo

Wskazówka: dostosuj prędkość, prędkość kątową i wartość przyspieszenia w NavMeshagent, aby dopasować je do swoich potrzeb.

Źródło
📁RTSMOBAController.unitypackage5.05 MB
Sugerowane artykuły
Samouczek dotyczący kontrolera odtwarzacza z góry na dół dla Unity
Samouczek skakania po ścianie w 3D i 2D dla odtwarzacza Unity
Planetarny kontroler odtwarzacza oparty na Rigidbody dla Unity
Kontroler helikoptera dla Unity
Kontroler samochodowy dla Unity
Samouczek dotyczący kontrolera robaków 3D dla Unity
Dodanie obsługi podwójnego skoku do kontrolera postaci platformówki 2D w Unity