RTS og MOBA spillerkontroller for Unity
I videospill står begrepet RTS for sanntidsstrategi.
Forskjellen mellom RTS og konvensjonelle første/tredjepersons skytespill er at karakterene styres med musepekeren i stedet for de vanlige W-, A-, S- og D-knappene.
Spilleren får utsikt over slagmarken med ørneøye med muligheten til å gi ordre til troppene, uten å kontrollere dem direkte. Eksempler på RTS-spill er Warcraft, Starcraft, Cossacks, etc.
På den annen side står MOBA for Multiplayer Online Battle Arena, det er en noe nyere undersjanger av RTS-spill hvor spilleren kun kontrollerer én karakter i stedet for mange.
Eksempler på slike spill er League of Legends og Dota 2.
I denne opplæringen vil jeg vise hvordan du lager en kontroller i RTS/MOBA-stil i Unity.
Trinn 1: La oss lage de nødvendige skriptene
Denne opplæringen er ganske enkel, siden den bare krever ett skript.
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);
}
}
}
}
Steg 2
La oss nå sette opp en spillerkontroller og spillnivå.
- Lag et nytt GameObject og kall det 'RTSPlayer'
- Fest RTSPlayerController.cs-skriptet til det (MERK: Ved vedlegg vil det automatisk legge til en annen komponent kalt NavMeshAgent, denne komponenten vil være nødvendig senere)
- Legg til en spillerkropp (i mitt tilfelle vil jeg bruke en enkel kapsel med en kube, men du kan legge til en spillermodell hvis du har noen). Skaler den ned til ønsket størrelse.
- Flytt spillermodellen inne i 'RTSPlayer' GameObject (MERK: Før du blir foreldre, sørg for at 'RTSPlayer' er plassert nederst på spillermodellen)
- Velg 'RTSPlayer' og juster Radius og Height i NavMeshAgent til det samsvarer med spillermodellen
- Neste er å lage en målindikator prefab. Dette er bare et enkelt GameObject med en Quad som vil indikere hvor vi har klikket på kartet.
Du kan bruke teksturen nedenfor:
- Og til slutt, velg 'RTSPlayer' og tilordne alle nødvendige variabler i RTSPlayerController-skriptet:
Spillerkamera - er selvforklarende, dette kan være hvilket som helst kamera
Kameraforskyvning - hvor langt kameraet skal være fra spilleren
Target Indicator Prefab - prefabrikken vi nettopp har laget
Mens du er i Play-modus, vil du legge merke til at å klikke på kartet ikke får spilleren til å bevege seg. Det er fordi vi har en siste ting å gjøre, som er å bake et navigasjonsnett (Navmesh):
- Velg alle objektene som er en del av kartet og merk dem statiske:
- Gå til Vindu -> AI -> Navigasjon
- Under Bake-fanen endrer du verdiene for Agent Radius og Agent Height (de skal samsvare med verdiene fra NavMeshAgent), og klikk deretter Bake.
- Etter at bakingen er ferdig, vil du legge merke til en blåaktig netting som representerer det gangbare området.
MERK: For å forhindre at spilleren går over åsene, gå tilbake til Bake-fanen og reduser Max Slope-vinkelen og bak deretter navmeshen på nytt.
Mye bedre!
Til slutt, gå tilbake til avspillingsmodus og venstreklikk et sted på kartet.
Spilleren skal nå bevege seg mot målet mens han unngår hindringene:
Tips: Juster hastighet, vinkelhastighet og akselerasjonsverdi hos NavMeshagent for å passe dine behov.