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.

Captura de pantalla del juego de Warcraft 3

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:

indicador de objetivo de estrategia en tiempo real

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

Sharp Coder Reproductor de video

Consejo: modifique los valores de velocidad, velocidad angular y aceleración en NavMeshagent para adaptarlos a sus necesidades.

Artículos sugeridos
Tutorial del controlador de jugador de arriba hacia abajo para Unity
Controlador de helicóptero para Unity
Agregar soporte de doble salto a un controlador de personajes de plataformas 2D en Unity
Controlador de coche para Unity
Controlador de avión para Unity
Agregar agacharse al reproductor FPS en Unity
Tutorial de salto de pared 3D y 2D de Player para Unity