Kontroler odtwarzacza RTS i MOBA dla Unity
W grach wideo termin RTS oznacza strategię czasu rzeczywistego.
Różnica między RTS a konwencjonalnymi strzelankami z perspektywy pierwszej/trzeciej osoby polega na tym, że postaciami steruje się za pomocą wskaźnika myszy, a nie zwykłych przycisków W, A, S i D.
Gracz otrzymuje widok na pole bitwy z lotu ptaka i może wydawać rozkazy żołnierzom, bez bezpośredniego ich kontrolowania. Przykładami gier RTS są Warcraft, Starcraft, Cossacks itp.
Z kolei MOBA to skrót od Multiplayer Online Battle Arena, czyli nieco nowszy podgatunek gier RTS, w których gracz steruje tylko jedną postacią, a nie wieloma.
Przykładami takich gier są League of Legends i Dota 2.
W tym samouczku pokażę, jak utworzyć kontroler w stylu RTS/MOBA w Unity.
Krok 1: Stwórzmy niezbędne skrypty
Ten samouczek jest dość prosty, ponieważ wymaga tylko jednego skryptu.
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);
}
}
}
}
Krok 2
Teraz skonfigurujmy kontroler gracza i poziom gry.
- Utwórz nowy obiekt GameObject i wywołaj go 'RTSPlayer'
- Dołącz do niego skrypt RTSPlayerController.cs (UWAGA: po dołączeniu automatycznie doda kolejny komponent o nazwie NavMeshAgent, ten komponent będzie potrzebny później)
- Dodaj ciało gracza (w moim przypadku użyję prostej kapsuły z kostką, ale możesz dodać model gracza, jeśli taki posiadasz). Zmniejsz go do żądanego rozmiaru.
- Przenieś model gracza do obiektu GameObject 'RTSPlayer' (UWAGA: przed objęciem funkcji rodzicielskich upewnij się, że 'RTSPlayer' znajduje się na dole modelu gracza)
- Wybierz 'RTSPlayer' i w NavMeshAgent dostosuj Promień i Wysokość, aż będą zgodne z modelem odtwarzacza
- Następnym krokiem jest utworzenie wskaźnika celu prefab. To po prostu prosty GameObject z Quadem, który wskaże, gdzie kliknęliśmy na mapie.
Możesz użyć poniższej tekstury:
- Na koniec wybierz 'RTSPlayer' i przypisz wszystkie niezbędne zmienne w skrypcie RTSPlayerController:
Kamera gracza – to oczywiste, może to być dowolna kamera
Camera Offset - jak daleko kamera powinna znajdować się od gracza
Prefabrykat wskaźnika celu - prefabrykat, który właśnie stworzyliśmy
Będąc w trybie gry, zauważysz, że kliknięcie na mapę nie powoduje ruchu gracza. To dlatego, że mamy jeszcze jedną rzecz do zrobienia, czyli upiecz siatkę nawigacyjną (Navmesh):
- Wybierz wszystkie obiekty będące częścią mapy i oznacz je jako statyczne:
- Przejdź do Okno -> AI -> Nawigacja
- Na karcie Pieczenie zmień wartości Promień agenta i Wysokość agenta (powinny one odpowiadać wartościom z NavMeshAgent), a następnie kliknij Piecz.
- Po zakończeniu pieczenia zauważysz niebieskawą siatkę, która reprezentuje obszar, po którym można chodzić.
UWAGA: Aby uniemożliwić graczowi chodzenie po wzgórzach, wróć do zakładki Pieczenie i zmniejsz maksymalny kąt nachylenia, a następnie ponownie wypal siatkę nawigacyjną.
Dużo lepiej!
Na koniec wróć do trybu odtwarzania i kliknij lewym przyciskiem myszy gdzieś na mapie.
Gracz powinien teraz ruszyć w stronę celu, omijając przeszkody:
Wskazówka: dostosuj prędkość, prędkość kątową i wartość przyspieszenia w NavMeshagent, aby dopasować je do swoich potrzeb.