Menu
CoddyTech

Patrouiller et poursuivre

Fait partie de la section Physique et gameplay du Journey Unity de Coddy. Leçon 54 sur 71.

Un garde en patrouille suit un itinéraire jusqu’à ce qu’il voie le joueur, le poursuive, puis retourne à son itinéraire une fois le joueur parti. Les deux comportements dirigent le garde de la même manière, vers un point : une seule méthode peut donc effectuer les déplacements dans les deux cas. Cette sentinelle fait des allers-retours entre deux postes et poursuit le joueur s’il se trouve dans un rayon de chaseRange :

[SerializeField] private Transform pointA;
[SerializeField] private Transform pointB;
[SerializeField] private Transform player;
[SerializeField] private float speed = 2f;
[SerializeField] private float chaseRange = 5f;
private Rigidbody rb;
private Transform goal;

void Start()
{
    rb = GetComponent<Rigidbody>();
    goal = pointA;
}

void FixedUpdate()
{
    if (Flat(player.position - rb.position).magnitude < chaseRange)
    {
        WalkTo(player.position);
        return;
    }
    if (Flat(goal.position - rb.position).magnitude < 0.2f)
    {
        goal = goal == pointA ? pointB : pointA;
    }
    WalkTo(goal.position);
}

void WalkTo(Vector3 target)
{
    Vector3 dir = Flat(target - rb.position).normalized;
    rb.linearVelocity = new Vector3(dir.x * speed, rb.linearVelocity.y, dir.z * speed);
}

Vector3 Flat(Vector3 v)
{
    return new Vector3(v.x, 0f, v.z);
}

Le test de poursuite est effectué en premier, et son return permet d’ignorer le code de patrouille : la poursuite est donc prioritaire dès que le joueur est proche. goal est un champ, donc la sentinelle garde sa valeur en mémoire pendant la poursuite : une fois le joueur parti, elle continue jusqu’au poste qu’elle visait.

Le test d’arrivée mesure la distance au sol. Les postes sont des repères au sol et le centre de la sentinelle se trouve à 1 unité au-dessus d’eux : une distance qui tient compte de la hauteur ne descend donc jamais en dessous de 1, et la sentinelle ne ferait jamais demi-tour. Le test vérifie que la distance est inférieure à 0.2, et non exactement égale à 0 : à 2 unités par seconde, la sentinelle avance de 0.04 unité par étape et n’atteint presque jamais exactement le poste.

challenge icon

Défi

Moyen

Fais patrouiller le robot entre ses points de passage et poursuivre le joueur qui s'approche.

  1. Écris WalkTo(Vector3 target), en orientant rb.linearVelocity vers lui sur le sol à speed, tout en conservant sa vitesse en y.
  2. Dans FixedUpdate(), lorsque le joueur est à moins de chaseRange, appelle WalkTo(player.position) et return.
  3. Sinon, si le robot est à moins de 0.2 de waypoints[next], définis next = (next + 1) % waypoints.Length;, puis dirige-le vers waypoints[next].

Appuie sur « Jouer » et croise son chemin. Puis clique sur « Vérifier ».

Essayez vous-même

using UnityEngine;

public class Robot : MonoBehaviour
{
    [SerializeField] private Transform[] waypoints;
    [SerializeField] private Transform player;
    [SerializeField] private float speed = 4f;
    [SerializeField] private float chaseRange = 4f;
    private Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        // poursuivre le joueur lorsqu’il est proche, sinon suivre l’itinéraire de patrouille
    }
}

Toutes les leçons de Physique et gameplay

Entraînez-vous par vous-même : Playground Unity