RTS- en MOBA-spelercontroller voor Unity
In videogames staat de term RTS voor Real-time strategie.
Het verschil tussen RTS en conventionele First / Third Person shooter-spellen is dat de personages worden bestuurd met behulp van de muisaanwijzer in plaats van met de gebruikelijke W-, A-, S- en D-knoppen.
De speler krijgt een arendsoog van het slagveld met de mogelijkheid om bevelen te geven aan de troepen, zonder ze rechtstreeks te controleren. Voorbeelden van RTS spellen zijn Warcraft, Starcraft, Cossacks, etc.
Aan de andere kant staat MOBA voor Multiplayer Online Battle Arena, het is een wat nieuwer subgenre van RTS-games waarbij de speler slechts één personage bestuurt in plaats van veel.
Voorbeelden van dergelijke spellen zijn League of Legends en Dota 2.
In deze tutorial laat ik zien hoe je een RTS/MOBA-stijl controller maakt in Unity.
Stap 1: Laten we de benodigde script(s) maken
Deze tutorial is vrij eenvoudig, omdat er maar één script voor nodig is.
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);
}
}
}
}
Stap 2
Laten we nu een spelercontroller en spelniveau instellen.
- Maak een nieuw GameObject en roep het aan 'RTSPlayer'
- Voeg het RTSPlayerController.cs-script eraan toe (LET OP: bij het koppelen wordt automatisch een andere component toegevoegd met de naam NavMeshAgent, deze component zal later nodig zijn)
- Voeg een spelerslichaam toe (in mijn geval gebruik ik een eenvoudige capsule met een kubus, maar je kunt een spelersmodel toevoegen als je die hebt). Verklein het tot de gewenste grootte.
- Verplaats het spelermodel binnen het 'RTSPlayer' GameObject (LET OP: zorg ervoor dat vóór het ouderschap 'RTSPlayer' onderaan het spelermodel wordt geplaatst)
- Selecteer 'RTSPlayer' en pas in NavMeshAgent de straal en hoogte aan totdat deze overeenkomen met het spelersmodel
- Vervolgens moet u een doelindicator prefab maken. Dit is slechts een eenvoudig GameObject met een Quad die aangeeft waar we op de kaart hebben geklikt.
Je kunt de onderstaande textuur gebruiken:
- En ten slotte selecteert u 'RTSPlayer' en wijst u alle benodigde variabelen toe in het RTSPlayerController-script:
Spelercamera - spreekt voor zich, dit kan elke camera zijn
Camera-offset - hoe ver de camera van de speler verwijderd moet zijn
Doelindicator Prefab - de prefab die we zojuist hebben gemaakt
In de afspeelmodus zul je merken dat klikken op de kaart de speler niet laat bewegen. Dat komt omdat we nog één laatste ding te doen hebben, namelijk een navigatienetwerk bakken (Navmesh):
- Selecteer alle objecten die deel uitmaken van de kaart en markeer ze statisch:
- Ga naar Venster -> AI -> Navigatie
- Wijzig op het tabblad Bakken de waarden van Agent Radius en Agenthoogte (deze moeten overeenkomen met de waarden van NavMeshAgent) en klik vervolgens op Bakken.
- Nadat het bakken is voltooid, ziet u een blauwachtig omlijnd gaas, dat het beloopbare gebied vertegenwoordigt.
OPMERKING: Om te voorkomen dat de speler over de heuvels loopt, gaat u terug naar het tabblad Bakken en verkleint u de maximale hellingshoek. Bak vervolgens de navmesh opnieuw.
Veel beter!
Ga ten slotte terug naar de afspeelmodus en klik met de linkermuisknop ergens op de kaart.
De speler moet nu richting het doel bewegen terwijl hij de obstakels ontwijkt:
Tip: Pas de snelheid, hoeksnelheid en acceleratiewaarde bij NavMeshaagent aan uw behoeften aan.