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.

Warcraft 3 skärmdump av spelet

Å 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:

målindikator för strategi i realtid

  • 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:

Sharp Coder Videospelare

Tips: Justera värden för hastighet, vinkelhastighet och acceleration hos NavMeshagent för att passa dina behov.