RTS och MOBA Player Controller for Unity
I videospel står termen RTS för Real-time strategy.
Skillnaden mellan RTS och konventionella första-/tredjepersonsskjutspel är att karaktärerna styrs med muspekaren snarare än de vanliga W-, A-, S- och D-knapparna.
Spelaren får en örnöga över slagfältet med förmågan att ge order till trupperna utan att direkt kontrollera dem. Exempel på RTS-spel är Warcraft, Starcraft, Cossacks, etc.
Å andra sidan står MOBA för Multiplayer Online Battle Arena, det är en något nyare undergenre av RTS-spel där spelaren bara styr en karaktär istället för många.
Exempel på sådana spel är League of Legends och Dota 2.
I den här handledningen kommer jag att visa hur man skapar en RTS/MOBA-styrenhet i Unity.
Steg 1: Låt oss skapa de nödvändiga skripten
Denna handledning är ganska enkel, eftersom den bara kräver 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
Låt oss nu ställa in en spelarkontroll och spelnivå.
- Skapa ett nytt GameObject och anropa det 'RTSPlayer'
- Bifoga RTSPlayerController.cs-skriptet till det (OBS: När det bifogas kommer det automatiskt att lägga till ytterligare en komponent som heter NavMeshAgent, den här komponenten kommer att behövas senare)
- Lägg till en spelarkropp (i mitt fall kommer jag att använda en enkel kapsel med en kub, men du kan lägga till en spelarmodell om du har någon). Skala ner till önskad storlek.
- Flytta spelarmodellen inuti 'RTSPlayer' GameObject (OBS: Innan du blir förälder, se till att 'RTSPlayer' är placerad längst ner på spelarmodellen)
- Välj 'RTSPlayer' och justera radien och höjden i NavMeshAgent tills de matchar spelarmodellen
- Nästa är att skapa en målindikator prefab. Detta är bara ett enkelt GameObject med en Quad som kommer att indikera var vi har klickat på kartan.
Du kan använda texturen nedan:
- Och slutligen, välj 'RTSPlayer' och tilldela alla nödvändiga variabler i RTSPlayerController-skriptet:
Spelarkamera - är självförklarande, detta kan vara vilken kamera som helst
Kameraförskjutning – hur långt kameran ska vara från spelaren
Target Indicator Prefab - prefab vi just skapat
När du är i uppspelningsläge kommer du att märka att spelaren inte rör sig om du klickar på kartan. Det beror på att vi har en sista sak att göra, som är att baka ett navigeringsnät (Navmesh):
- Välj alla objekt som är en del av kartan och markera dem som statiska:
- Gå till Fönster -> AI -> Navigation
- Under Bake-fliken ändrar du värdena för Agent Radius och Agent Height (de ska matcha värdena från NavMeshAgent), klicka sedan på Bake.
- När bakningen är klar kommer du att märka ett blåaktigt nät som representerar det gångbara området.
OBS: För att förhindra att spelaren går över kullarna, gå tillbaka till Bake-fliken och minska Max Slope-vinkeln och baka sedan om navmesh.
Mycket bättre!
Slutligen, gå tillbaka till uppspelningsläge och vänsterklicka någonstans på kartan.
Spelaren ska nu röra sig mot målet samtidigt som han undviker hindren:
Tips: Justera värden för hastighet, vinkelhastighet och acceleration hos NavMeshagent för att passa dina behov.