Contrôleur de lecteur RTS et MOBA pour Unity

Dans les jeux vidéo, le terme RTS signifie Real-time stratégie.

La différence entre RTS et les jeux de tir conventionnels à la première/à la troisième personne est que les personnages sont contrôlés à l'aide du pointeur de la souris plutôt que des boutons W, A, S et D habituels.

Le joueur a une vue d'ensemble du champ de bataille avec la possibilité de donner des ordres aux troupes, sans les contrôler directement. Des exemples de jeux RTS sont Warcraft, Starcraft, Cossacks, etc.

Capture d'écran du gameplay de Warcraft 3

D'un autre côté, MOBA signifie Multiplayer Online Battle Arena, il s'agit d'un sous-genre un peu plus récent de jeux RTS dans lequel le joueur contrôle un seul personnage au lieu de plusieurs.

Des exemples de tels jeux sont League of Legends et Dota 2.

Dans ce didacticiel, je vais montrer comment créer un contrôleur de style RTS/MOBA dans Unity.

Étape 1: Créons le(s) script(s) nécessaire(s)

Ce tutoriel est assez simple, car il ne nécessite qu'un seul 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);
            }
        }
    }
}

Étape 2

Configurons maintenant un contrôleur de joueur et un niveau de jeu.

  • Créez un nouveau GameObject et appelez-le 'RTSPlayer'
  • Attachez-y le script RTSPlayerController.cs (REMARQUE: lors de l'attachement, il ajoutera automatiquement un autre composant appelé NavMeshAgent, ce composant sera nécessaire plus tard)

  • Ajoutez un corps de joueur (dans mon cas, j'utiliserai une simple capsule avec un cube, mais vous pouvez ajouter un modèle de joueur si vous en avez). Réduisez-le jusqu’à la taille souhaitée.
  • Déplacez le modèle de joueur à l'intérieur du 'RTSPlayer' GameObject (REMARQUE: avant d'être parent, assurez-vous que 'RTSPlayer' est placé au bas du modèle de joueur)

  • Sélectionnez 'RTSPlayer' et dans NavMeshAgent modifiez le rayon et la hauteur jusqu'à ce qu'ils correspondent au modèle du joueur.

  • Ensuite, il faut créer un indicateur cible préfabriqué. Il s'agit simplement d'un simple GameObject avec un Quad qui indiquera où nous avons cliqué sur la carte.

Vous pouvez utiliser la texture ci-dessous:

indicateur d'objectif de stratégie en temps réel

  • Et enfin, sélectionnez 'RTSPlayer' et attribuez toutes les variables nécessaires dans le script RTSPlayerController:

Caméra du joueur – est explicite, il peut s'agir de n'importe quelle caméra.

Décalage de la caméra: à quelle distance la caméra doit être du joueur

Target Indicator Prefab - le préfabriqué que nous venons de créer

En mode Lecture, vous remarquerez que cliquer sur la carte ne fait pas bouger le joueur. C'est parce que nous avons une dernière chose à faire, qui est de créer un Maillage de navigation (Navmesh):

  • Sélectionnez tous les objets qui font partie de la carte et marquez-les comme statiques:

  • Allez dans Fenêtre -> IA -> Navigation

  • Sous l'onglet Bake, modifiez les valeurs de Rayon de l'agent et de Hauteur de l'agent (celles-ci doivent correspondre aux valeurs de NavMeshAgent), puis cliquez sur Bake.

  • Une fois la cuisson terminée, vous remarquerez un maillage au contour bleuâtre, qui représente la zone accessible à pied.

REMARQUE: pour empêcher le joueur de marcher sur les collines, revenez à l'onglet Bake et diminuez l'angle Max Slope, puis refaites le navmesh.

Beaucoup mieux !

Enfin, revenez en mode Lecture et faites un clic gauche quelque part sur la carte.

Le joueur doit maintenant se diriger vers la cible tout en évitant les obstacles:

Sharp Coder Lecteur vidéo

Astuce: Ajustez la valeur de la vitesse, de la vitesse angulaire et de l'accélération sur NavMeshagent pour répondre à vos besoins.

Articles suggérés
Tutoriel de contrôleur de lecteur descendant pour Unity
Contrôleur de lecteur planétaire basé sur Rigidbody pour Unity
Contrôleur d'avion pour Unity
Tutoriel sur le contrôleur de ver 3D pour Unity
Contrôleur de personnages 2D pour Unity
Contrôleur d'hélicoptère pour Unity
Ajout de la prise en charge du double saut à un contrôleur de personnage de plateforme 2D dans Unity