Skip to main content

Class SteeringBehaviour

Abstract base for one node in the steering behavior pipeline assembled and driven by SteeringSolver.

[RequireComponent(typeof(SteeringSolver))]
public abstract class SteeringBehaviour : MonoBehaviour, IHandler

Inheritance​

Derived​

Implements​

IHandler

Examples​

// This example shows a custom steering node that nudges the actor toward the centre of its lane.
// It accumulates onto TargetVector so earlier nodes (e.g. SeekBehavior) still contribute their
// goal-directed force.
//
// Add this MonoBehaviour to the same GameObject as SteeringSolver, then drag it into the
// SteeringSolver.behaviours array in the Inspector, after SeekBehavior.
public class LaneKeepBehavior : SteeringBehaviour
{
[SerializeField] private Transform laneCentreMarker;
[SerializeField, Range(0f, 1f)] private float weight = 0.3f;

public override Vector3 GetSteering(Vector3 TargetVector)
{
// Compute a soft pull toward the lane centre — do NOT write to Rigidbody here;
// SteeringSolver applies the final aggregated vector once per fixed-update.
Vector3 toCentre = laneCentreMarker.position - transform.position;
Vector3 laneForce = SeekBehavior.Seek(m_Solver.Rigidbody.velocity,
toCentre.normalized) * weight;
return TargetVector + laneForce;
}
}

Remarks​

Each behaviour is a separate MonoBehaviour component on the same GameObject. Adding a new modifier means adding a new component. Each node receives the vector produced by the node before it, adds its own contribution, and passes the result on. The final vector reflects every modifier that was in the array, in order, without any node needing to know what comes before or after it.

SteeringSolver is responsible for linking all behaviours into the chain at startup and calling into the first node each fixed-update. Once all nodes have accumulated their contributions, the solver reads the final vector and applies it to the actor's Rigidbody — no behaviour should write to the physics body directly.

Fields​

m_Solver​

The SteeringSolver component for solving steering behavior.

protected SteeringSolver m_Solver

Field Value​

SteeringSolver

Methods​

GetSteering(Vector3)​

Abstract method for obtaining the steering behavior vector. Implementations must accumulate their contribution onto TargetVector and return the result — they must NOT apply the vector to the Rigidbody directly.

public abstract Vector3 GetSteering(Vector3 TargetVector)

Parameters​

NameTypeDescription
TargetVectorVector3The target vector to steer towards.

Returns​

Vector3 — A vector representing the accumulated steering force up to this node.

Remarks​

The result must not be applied to the Rigidbody inside an implementation because SteeringSolver owns that responsibility. The solver aggregates the final vector from the whole chain and applies it once per fixed-update, ensuring consistent physics integration and preventing multiple behaviours from independently writing conflicting velocities to the same body in the same frame.

Handle(object)​

Handles a steering request. Processes the request and passes it to the next handler if available.

public object Handle(object request)

Parameters​

NameTypeDescription
requestobjectThe request to handle (should be a Vector3 target). The parameter is typed as object rather than Vector3 because the chain-of-responsibility contract (IHandler) must be type-agnostic — the same interface can be reused by non-steering handlers that pass different payloads.

Returns​

object — The processed request (steering vector) or null if the request is invalid.

Remarks​

The is Vector3 pattern guard exists because the chain can be entered by non-steering callers (e.g. generic event dispatchers) that may pass arbitrary objects. Returning null instead of throwing preserves graceful degradation so a mis-typed call silently drops rather than crashing the simulation.

SetNext(IHandler)​

Sets the next handler in the chain.

public IHandler SetNext(IHandler handler)

Parameters​

NameTypeDescription
handlerIHandlerThe next handler to be set in the chain.

Returns​

IHandler — The next handler, enabling fluent chaining at setup time.

Remarks​

This is a simple field assignment rather than a list-append because chain assembly happens exactly once at startup inside SteeringSolver. A fixed linked list is sufficient — no behaviour needs to be inserted, removed, or reordered at runtime — and it avoids the allocation overhead of a managed collection on every frame.

Start()​

Initializes the SteeringSolver component at the start.

protected virtual void Start()