# Stopping a rigidbody at target

Hi,

we’re currently developing a dungeon siege style top down game where the player moves his character with mouse clicks. Since physics will have to take full effect on the character we decided to move the avatar by rotating its rigidbody towards the mouse and then use AddForce to move it along it’s forward axis.

``````void Move()
{
Vector3 dir = rigidbody.transform.forward * _fCurrentSpeed;
Vector3 v3TargetPos = new Vector3(v3MouseTarget.x, rigidbody.transform.position.y, v3MouseTarget.z);

if(Vector3.Distance(rigidbody.transform.position, v3TargetPos) <= .5f )
{
_fCurrentSpeed = 0f;
}
else
{
_fCurrentSpeed = fSpeed;
transform.LookAt(v3TargetPos);
}

}
``````

The problem here is that the rigidbody will usually overshoot, turn around, walk back, and then stop. If i try to set the stop condition to transform.position == v3TargetPos the avatar will turn endlessly as the added force will always make it overshoot the target position.

Does anyone have an idea how to effectively stop the character once he’s reached the target position? Alternate methods are also welcome

Thanks

Applying a force to reach some position is hard to control: the distance is a complicated function (integral) of force intensity, time and mass.

A simple solution is to just zero rigidbody.velocity when the target is reached, but this produces a very weird and unnatural result - the rigidbody just stops at the target position.

A better alternative is to use a feedback control algorithm, where the force is applied to reach a target velocity, and this velocity (clamped to some max value) is proportional to the distance to the target point - this way it will fall to zero when the target point is reached, stopping the rigidbody:

``````public float toVel = 2.5f;
public float maxVel = 15.0f;
public float maxForce = 40.0f;
public float gain = 5f;

Rigidbody rbody;

void Start(){
rbody = GetComponent<Rigidbody>();
}

void FixedUpdate(){
Vector3 dist = targetPos - transform.position;
dist.y = 0; // ignore height differences
// calc a target vel proportional to distance (clamped to maxVel)
Vector3 tgtVel = Vector3.ClampMagnitude(toVel * dist, maxVel);
// calculate the velocity error
Vector3 error = tgtVel - rbody.velocity;
// calc a force proportional to the error (clamped to maxForce)
Vector3 force = Vector3.ClampMagnitude(gain * error, maxForce);