Controller per lettori RTS e MOBA per Unity

Nei videogiochi, il termine RTS sta per strategia in tempo reale.

La differenza tra RTS e i tradizionali giochi sparatutto in prima/terza persona è che i personaggi vengono controllati utilizzando il puntatore del mouse anziché i soliti pulsanti W, A, S e D.

Al giocatore viene data una visione dall'alto del campo di battaglia con la possibilità di dare ordini alle truppe, senza controllarle direttamente. Esempi di giochi RTS sono Warcraft, Starcraft, Cossacks, ecc.

Schermata di gioco di Warcraft 3

D'altra parte, MOBA sta per Multiplayer Online Battle Arena, è un sottogenere un po' più recente dei giochi RTS in cui il giocatore controlla solo un personaggio invece di molti.

Esempi di tali giochi sono League of Legends e Dota 2.

In questo tutorial mostrerò come creare un controller in stile RTS/MOBA in Unity.

Passaggio 1: creiamo gli script necessari

Questo tutorial è abbastanza semplice, poiché richiede solo uno script.

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

Passo 2

Ora impostiamo un controller del giocatore e un livello di gioco.

  • Crea un nuovo GameObject e chiamalo 'RTSPlayer'
  • Allega lo script RTSPlayerController.cs ad esso (NOTA: dopo averlo collegato, verrà aggiunto automaticamente un altro componente chiamato NavMeshAgent, questo componente sarà necessario in seguito)

  • Aggiungi il corpo di un giocatore (nel mio caso utilizzerò una semplice capsula con un cubo, ma puoi aggiungere un modello di giocatore se ne hai). Ridimensionalo fino alla dimensione desiderata.
  • Sposta il modello del giocatore all'interno del GameObject 'RTSPlayer' (NOTA: prima di diventare genitore, assicurati che 'RTSPlayer' sia posizionato nella parte inferiore del modello del giocatore)

  • Seleziona 'RTSPlayer' e in NavMeshAgent modifica il raggio e l'altezza fino a quando non corrisponde al modello del giocatore

  • Il prossimo è creare un indicatore di destinazione prefabbricato. Questo è solo un semplice GameObject con un Quad che indicherà dove abbiamo cliccato sulla mappa.

Puoi usare la texture qui sotto:

indicatore del target strategico in tempo reale

  • Infine, seleziona 'RTSPlayer' e assegna tutte le variabili necessarie nello script RTSPlayerController:

Player Camera - è autoesplicativo, può essere qualsiasi fotocamera

Offset telecamera: quanto lontano dovrebbe essere la telecamera dal giocatore

Target Indicator Prefab: il prefabbricato che abbiamo appena creato

Mentre sei in modalità Gioca, noterai che fare clic sulla mappa non fa muovere il giocatore. Questo perché abbiamo un'ultima cosa da fare, ovvero creare una navigation mesh (Navmesh):

  • Seleziona tutti gli oggetti che fanno parte della mappa e contrassegnali come statici:

  • Vai a Finestra -> AI -> Navigazione

  • Nella scheda Bake modificare i valori di Agent Radius e Agent Height (che dovrebbero corrispondere ai valori di NavMeshAgent), quindi fare clic su Bake.

  • Al termine della cottura noterai una rete delineata bluastra, che rappresenta l'area calpestabile.

NOTA: per impedire al giocatore di camminare sulle colline, tornare alla scheda Bake e diminuire l'angolo di pendenza massima, quindi rifare la navmesh.

Molto meglio!

Infine, torna alla modalità di riproduzione e fai clic con il pulsante sinistro del mouse in un punto qualsiasi della mappa.

Il giocatore ora dovrebbe muoversi verso il bersaglio evitando gli ostacoli:

Sharp Coder Lettore video

Suggerimento: modificare i valori di velocità, velocità angolare e accelerazione su NavMeshagent per adattarli alle proprie esigenze.