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.
Desafío
IntermedioHaz que el robot patrulle sus puntos de ruta y persiga al jugador que se acerque.
- Escribe
WalkTo(Vector3 target)y establecerb.linearVelocityhacia ese punto a lo largo del suelo, aspeed, manteniendo su velocidad en y. - En
FixedUpdate(), cuando el jugador esté a menos distancia quechaseRange, ejecutaWalkTo(player.position)yreturn. - De lo contrario, si está a menos de 0.2 de
waypoints[next], establecenext = (next + 1) % waypoints.Length;y después camina haciawaypoints[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
1Cuerpo rígido
Gravedad y masaEmpujar con AddForceSaltar con un impulsoFixedUpdate para físicaVelocidadCuerpos cinemáticosRepaso: plataforma de lanzamiento4Corrutinas
InvocarInvokeRepeating y CancelInvokeTu primera corrutinaBucles en corrutinasDetener corrutinasRepaso: cuenta regresiva10Proyecto: Escape de la arena
La arenaCazadores2Colisiones
OnCollisionEnter¿Qué golpeé?Romper al impactarDe pie sobre el sueloRebote y fricciónFormas de los collidersRepaso: muro destructible5Proyecto: Carrera de Monedas
La pelota rodanteMonedas para recoger3Disparadores
Colisionadores de tipo triggerOnTriggerEnterObjetos coleccionablesLas cajas guardan el restoZonas letalesEntrada y salidaRepaso: llave y puerta6Raycasts
Physics.RaycastRaycastHitComprobación del suelo con un rayoCapas y LayerMaskLínea de visiónOverlapSphere y SphereCastRepaso: cable trampa láser9Enemigos
Perseguir al jugadorPerseguir dentro del rangoPatrullar y perseguirSalud y dañoBalas que impactanRetrocesoRepaso: perro guardiánPractica por tu cuenta: Playground de Unity