Menu
CoddyTech

Patrullar y perseguir

Parte de la sección Física y jugabilidad del Journey de Unity de Coddy. Lección 54 de 71.

Un guardia de patrulla recorre una ruta hasta que ve al jugador, lo persigue y vuelve a su ruta cuando el jugador ya no está. Ambos comportamientos se dirigen de la misma manera, hacia un punto, así que un método puede encargarse del desplazamiento en ambos casos. Este centinela va y viene entre dos puestos y persigue al jugador dentro 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);
}

La comprobación de persecución se realiza primero, y su return omite el código de patrulla, así que la persecución tiene prioridad cuando el jugador está cerca. goal es un campo, por lo que el centinela lo recuerda durante la persecución: cuando el jugador ya no está, sigue caminando hacia el puesto al que se dirigía.

La comprobación de llegada mide la distancia sobre el suelo. Los puestos son marcadores en el suelo y el centro del centinela está 1 unidad por encima de ellos, así que una distancia que incluya la altura nunca baja de 1 y el centinela nunca daría la vuelta. La comprobación pide menos de 0.2, no exactamente 0: a 2 unidades por segundo, el centinela se mueve 0.04 unidades por paso y casi nunca llega exactamente al puesto.

challenge icon

Desafío

Intermedio

Haz que el robot patrulle sus puntos de ruta y persiga al jugador que se acerque.

  1. Escribe WalkTo(Vector3 target) y establece rb.linearVelocity hacia ese punto a lo largo del suelo, a speed, manteniendo su velocidad en y.
  2. En FixedUpdate(), cuando el jugador esté a menos distancia que chaseRange, ejecuta WalkTo(player.position) y return.
  3. De lo contrario, si está a menos de 0.2 de waypoints[next], establece next = (next + 1) % waypoints.Length; y después camina hacia waypoints[next].

Pulsa «Jugar» y cruza su camino. Después, pulsa «Comprobar».

Pruébalo tú mismo

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()
    {
        // persigue al jugador cuando esté cerca o recorre la ruta de patrulla
    }
}

Todas las lecciones de Física y jugabilidad

Practica por tu cuenta: Playground de Unity