Arrive steering behavior
        Posted  
        
            by 
                dbostream
            
        on Game Development
        
        See other posts from Game Development
        
            or by dbostream
        
        
        
        Published on 2012-11-25T11:13:47Z
        Indexed on 
            2012/11/25
            11:24 UTC
        
        
        Read the original article
        Hit count: 436
        
c#
|steering-behaviors
I bought a book called Programming game AI by example and I am trying to implement the arrive steering behavior. The problem I am having is that my objects oscillate around the target position; after oscillating less and less for awhile they finally come to a stop at the target position. Does anyone have any idea why this oscillating behavior occur? Since the examples accompanying the book are written in C++ I had to rewrite the code into C#. Below is the relevant parts of the steering behavior:
private enum Deceleration
{
    Fast = 1,
    Normal = 2,
    Slow = 3
}
public MovingEntity Entity { get; private set; }
public Vector2 SteeringForce { get; private set; }
public Vector2 Target { get; set; }
public Vector2 Calculate()
{
    SteeringForce.Zero();
    SteeringForce = SumForces();
    SteeringForce.Truncate(Entity.MaxForce);
    return SteeringForce;
}
private Vector2 SumForces()
{
    Vector2 force = new Vector2();
    if (Activated(BehaviorTypes.Arrive))
    {
        force += Arrive(Target, Deceleration.Slow);
        if (!AccumulateForce(force))
            return SteeringForce;
    }
    return SteeringForce;
}
private Vector2 Arrive(Vector2 target, Deceleration deceleration)
{
    Vector2 toTarget = target - Entity.Position;
    double distance = toTarget.Length();
    if (distance > 0)
    {
        //because Deceleration is enumerated as an int, this value is required
        //to provide fine tweaking of the deceleration..
        double decelerationTweaker = 0.3;
        double speed = distance / ((double)deceleration * decelerationTweaker);
        speed = Math.Min(speed, Entity.MaxSpeed);
        Vector2 desiredVelocity = toTarget * speed / distance;
        return desiredVelocity - Entity.Velocity;
    }
    return new Vector2();
}
private bool AccumulateForce(Vector2 forceToAdd)
{
    double magnitudeRemaining = Entity.MaxForce - SteeringForce.Length();
    if (magnitudeRemaining <= 0)
        return false;
    double magnitudeToAdd = forceToAdd.Length();
    if (magnitudeToAdd > magnitudeRemaining)
        magnitudeToAdd = magnitudeRemaining;
    SteeringForce += Vector2.NormalizeRet(forceToAdd) * magnitudeToAdd;
    return true;
}
This is the update method of my objects:
public void Update(double deltaTime)
{
    Vector2 steeringForce = Steering.Calculate();
    Vector2 acceleration = steeringForce / Mass;
    Velocity = Velocity + acceleration * deltaTime;
    Velocity.Truncate(MaxSpeed);
    Position = Position + Velocity * deltaTime;
}
If you want to see the problem with your own eyes you can download a minimal example here.
Thanks in advance.
© Game Development or respective owner