Controlador de reproductor RTS y MOBA para Unity
En los videojuegos, el término RTS significa estrategia en tiempo real.
La diferencia entre RTS y los juegos de disparos en primera y tercera persona convencionales es que los personajes se controlan con el puntero del mouse en lugar de los botones habituales W, A, S y D.
El jugador tiene una vista de águila del campo de batalla con la capacidad de dar órdenes a las tropas, sin controlarlas directamente. Ejemplos de juegos RTS son Warcraft, Starcraft, Cossacks, etc.
Por otro lado, MOBA significa Multiplayer Online Battle Arena, es un subgénero algo más nuevo de los juegos de estrategia en tiempo real donde el jugador controla solo un personaje en lugar de muchos.
Ejemplos de este tipo de juegos son League of Legends y Dota 2.
En este tutorial, mostraré cómo crear un controlador estilo RTS/MOBA en Unity.
Paso 1: creemos los scripts necesarios
Este tutorial es bastante simple, ya que sólo requiere un 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);
}
}
}
}
Paso 2
Ahora configuremos un controlador de jugador y un nivel de juego.
- Crea un nuevo GameObject y llámalo 'RTSPlayer'
- Adjunte el script RTSPlayerController.cs (NOTA: al adjuntarlo, agregará automáticamente otro componente llamado NavMeshAgent, este componente será necesario más adelante)
- Agrega un cuerpo de jugador (en mi caso usaré una cápsula simple con un cubo, pero puedes agregar un modelo de jugador si tienes alguno). Reduzca la escala hasta el tamaño deseado.
- Mueva el modelo del jugador dentro del 'RTSPlayer' GameObject (NOTA: antes de la crianza, asegúrese de que 'RTSPlayer' esté colocado en la parte inferior del modelo del jugador)
- Seleccione 'RTSPlayer' y en NavMeshAgent modifique el radio y la altura hasta que coincida con el modelo del reproductor.
- Lo siguiente es crear un indicador objetivo prefabricado. Este no es más que un sencillo GameObject con un Quad que nos indicará dónde hemos pulsado en el mapa.
Puedes usar la textura a continuación:
- Y por último, seleccione 'RTSPlayer' y asigne todas las variables necesarias en el script RTSPlayerController:
Cámara del reproductor: se explica por sí misma, puede ser cualquier cámara
Desplazamiento de la cámara: qué tan lejos debe estar la cámara del reproductor
Prefabricado de indicador de objetivo: el prefabricado que acabamos de crear
Mientras estás en el modo Jugar, notarás que hacer clic en el mapa no hace que el jugador se mueva. Eso es porque tenemos una última cosa que hacer, que es crear una malla de navegación (Navmesh):
- Selecciona todos los objetos que forman parte del mapa y márcalos como estáticos:
- Vaya a Ventana -> AI -> Navegación
- En la pestaña Hornear, cambie los valores de Radio del agente y Altura del agente (deben coincidir con los valores de NavMeshAgent), luego haga clic en Hornear.
- Una vez finalizado el horneado, notará una malla con un contorno azulado, que representa el área transitable.
NOTA: Para evitar que el jugador camine sobre las colinas, regrese a la pestaña Hornear y disminuya el ángulo de pendiente máxima y luego vuelva a hornear la malla de navegación.
¡Mucho mejor!
Finalmente, regrese al modo Jugar y haga clic izquierdo en algún lugar del mapa.
El jugador ahora debería moverse hacia el objetivo evitando los obstáculos:
Consejo: modifique los valores de velocidad, velocidad angular y aceleración en NavMeshagent para adaptarlos a sus necesidades.