RTS og MOBA Player Controller til Unity
I videospil står udtrykket RTS for Real-time strategy.
Forskellen mellem RTS og konventionelle First/Third Person shooter-spil er, at figurerne styres ved hjælp af musemarkøren frem for de sædvanlige W, A, S og D knapper.
Spilleren får et ørneøjebillede af slagmarken med evnen til at give ordrer til tropperne uden direkte at kontrollere dem. Eksempler på RTS spil er Warcraft, Starcraft, Cossacks osv.
På den anden side står MOBA for Multiplayer Online Battle Arena, det er en noget nyere undergenre af RTS-spil, hvor spilleren kun kontrollerer én karakter i stedet for mange.
Eksempler på sådanne spil er League of Legends og Dota 2.
I denne tutorial vil jeg vise, hvordan man opretter en controller i RTS/MOBA-stil i Unity.
Trin 1: Lad os oprette det eller de nødvendige scripts
Denne tutorial er ret enkel, da den kun kræver et 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);
}
}
}
}
Trin 2
Lad os nu opsætte en spillercontroller og spilniveau.
- Opret et nyt GameObject og kald det 'RTSPlayer'
- Vedhæft RTSPlayerController.cs-scriptet til det (BEMÆRK: Når det vedhæftes, tilføjes det automatisk en anden komponent kaldet NavMeshAgent, denne komponent bliver nødvendig senere)
- Tilføj en spillerkrop (i mit tilfælde vil jeg bruge en simpel kapsel med en cube, men du kan tilføje en spillermodel, hvis du har nogen). Skaler det ned indtil den ønskede størrelse.
- Flyt afspillermodellen inde i 'RTSPlayer' GameObject (BEMÆRK: Før du bliver forældre, skal du sørge for, at 'RTSPlayer' er placeret i bunden af afspillermodellen)
- Vælg 'RTSPlayer' og juster Radius og Højde i NavMeshAgent, indtil det matcher afspillermodellen
- Det næste er at oprette en målindikator prefab. Dette er blot et simpelt GameObject med en Quad, der vil indikere, hvor vi har klikket på kortet.
Du kan bruge teksturen nedenfor:
- Og til sidst, vælg 'RTSPlayer' og tildel alle de nødvendige variabler i RTSPlayerController-scriptet:
Player Camera - er selvforklarende, dette kan være et hvilket som helst kamera
Kameraforskydning - hvor langt kameraet skal være fra afspilleren
Target Indicator Prefab - det præfabrikat, vi lige har oprettet
Mens du er i Play-tilstand, vil du bemærke, at et klik på kortet ikke får spilleren til at bevæge sig. Det er fordi vi har en sidste ting at gøre, som er at bage et navigationsnet (Navmesh):
- Vælg alle de objekter, der er en del af kortet, og marker dem statiske:
- Gå til Vindue -> AI -> Navigation
- Under fanebladet Bag skal du ændre værdierne for Agent Radius og Agent Højde (de skal svare til værdierne fra NavMeshAgent), og klik derefter på Bag.
- Når bagningen er færdig, vil du bemærke en blålig kontur maske, som repræsenterer det gangbare område.
BEMÆRK: For at forhindre spilleren i at gå over bakkerne, skal du gå tilbage til fanen Bag og mindske Max Slope-vinklen og derefter bage navmesh igen.
Meget bedre!
Til sidst skal du gå tilbage til afspilningstilstand og venstreklikke et sted på kortet.
Spilleren skal nu bevæge sig mod målet, mens han undgår forhindringerne:
Tip: Tweak Speed, Angular Speed og Acceleration værdi hos NavMeshagent, så den passer til dine behov.