Controlador de jogador RTS e MOBA para Unity
Nos videogames, o termo RTS significa estratégia em tempo real.
A diferença entre RTS e jogos convencionais de tiro em primeira/terceira pessoa é que os personagens são controlados usando o ponteiro do mouse em vez dos habituais botões W, A, S e D.
O jogador tem uma visão panorâmica do campo de batalha com a capacidade de dar ordens às tropas, sem controlá-las diretamente. Exemplos de jogos RTS são Warcraft, Starcraft, Cossacks, etc.
Por outro lado, MOBA significa Multiplayer Online Battle Arena, é um subgênero um pouco mais novo de jogos RTS onde o jogador controla apenas um personagem em vez de muitos.
Exemplos de tais jogos são League of Legends e Dota 2.
Neste tutorial, mostrarei como criar um controlador estilo RTS/MOBA em Unity.
Etapa 1: vamos criar os scripts necessários
Este tutorial é bastante simples, pois requer apenas um 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);
}
}
}
}
Passo 2
Agora vamos configurar um controlador de jogador e um nível de jogo.
- Crie um novo GameObject e chame-o 'RTSPlayer'
- Anexe o script RTSPlayerController.cs a ele (NOTA: Ao anexar, ele adicionará automaticamente outro componente chamado NavMeshAgent, este componente será necessário mais tarde)
- Adicione um corpo de jogador (no meu caso usarei uma cápsula simples com um cubo, mas você pode adicionar um modelo de jogador se tiver algum). Reduza até o tamanho desejado.
- Mova o modelo do jogador dentro do GameObject 'RTSPlayer' (NOTA: Antes de criar os pais, certifique-se de que 'RTSPlayer' esteja colocado na parte inferior do modelo do jogador)
- Selecione 'RTSPlayer' e no NavMeshAgent ajuste o Raio e a Altura até que corresponda ao modelo do jogador
- A seguir, crie um indicador de meta pré-fabricado. Este é apenas um GameObject simples com um Quad que indicará onde clicamos no mapa.
Você pode usar a textura abaixo:
- E por último, selecione 'RTSPlayer' e atribua todas as variáveis necessárias no script RTSPlayerController:
Câmera do jogador - é autoexplicativa, pode ser qualquer câmera
Camera Offset - a que distância a câmera deve estar do player
Target Indicator Prefab - o pré-fabricado que acabamos de criar
Enquanto estiver no modo Play, você notará que clicar no mapa não faz o jogador se mover. Isso porque temos uma última coisa a fazer, que é preparar uma Navigation Mesh (Navmesh):
- Selecione todos os objetos que fazem parte do mapa e marque-os como estáticos:
- Vá para Janela -> AI -> Navegação
- Na guia Bake, altere os valores de Agent Radius e Agent Height (esses devem corresponder aos valores de NavMeshAgent) e clique em Bake.
- Depois que o cozimento terminar, você notará uma malha com contorno azulado, que representa a área que pode ser percorrida.
NOTA: Para evitar que o jogador ande pelas colinas, volte para a aba Bake e diminua o ângulo Max Slope e então refaça a malha de navegação.
Muito melhor!
Por fim, volte ao modo Play e clique com o botão esquerdo em algum lugar do mapa.
O jogador deve agora mover-se em direção ao alvo evitando os obstáculos:
Dica: Ajuste a velocidade, a velocidade angular e o valor de aceleração no NavMeshagent para atender às suas necessidades.