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.
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:
- 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:
Suggerimento: modificare i valori di velocità, velocità angolare e accelerazione su NavMeshagent per adattarli alle proprie esigenze.