Pursuing and evading are great behaviors to start with because they rely on the most basic behaviors and extend their functionality by predicting the target's next step.
We need a couple of basic behaviors called Seek
and Flee
; place them right after the Agent
class in the scripts' execution order.
The following is the code for the Seek
behaviour:
using UnityEngine; using System.Collections; public class Seek : AgentBehaviour { public override Steering GetSteering() { Steering steering = new Steering(); steering.linear = target.transform.position - transform.position; steering.linear.Normalize(); steering.linear = steering.linear * agent.maxAccel; return steering; } }
Also, we need to implement the Flee
behavior:
using UnityEngine; using System.Collections; public class Flee : AgentBehaviour { public override Steering GetSteering() { Steering steering = new Steering(); steering.linear = transform.position - target.transform.position; steering.linear.Normalize(); steering.linear = steering.linear * agent.maxAccel; return steering; } }
Pursue
and Evade
are essentially the same algorithm but differ in terms of the base class they derive from:
Pursue
class, derived from Seek
, and add the attributes for the prediction:using UnityEngine;
using System.Collections;
public class Pursue : Seek
{
public float maxPrediction;
private GameObject targetAux;
private Agent targetAgent;
}
Awake
function in order to set up everything according to the real target:public override void Awake() { base.Awake(); targetAgent = target.GetComponent<Agent>(); targetAux = target; target = new GameObject(); }
OnDestroy
function, to properly handle the internal object:void OnDestroy () { Destroy(targetAux); }
GetSteering
function:public override Steering GetSteering() { Vector3 direction = targetAux.transform.position - transform.position; float distance = direction.magnitude; float speed = agent.velocity.magnitude; float prediction; if (speed <= distance / maxPrediction) prediction = maxPrediction; else prediction = distance / speed; target.transform.position = targetAux.transform.position; target.transform.position += targetAgent.velocity * prediction; return base.GetSteering(); }
Evade
behavior, the procedure is just the same, but it takes into account that Flee
is the parent class:public class Evade : Flee
{
// everything stays the same
}