Advice on keeping distance using AddForce

Hi,

I have 2 objects which both move in 3D space. I was using transform position, but I am now converting to Physix for a more realistic movement and collisions.

I have all the Vector3 positions working, and the detection of distance etc to trigger the movements. So for example if not in range, trigger code to move closer to the object until it is. The same goes if an object is too close. If it is move away until the min distance value is met.

What I am investigating before I jump into the conversion, is the best way to implement the Physics based movement.

  1. Is there a way to AddForce in the
    direction of a Vector3? Most
    examples that I find are more
    focused on player control. Would it
    be best to have the rigidbody
    transform rotate in the direction of
    the object I want to move closer to
    then AddForce until in range?
  2. The other question is how would I go
    about about moving in the opposite
    direction to move away. If the
    rigidbody transform is pointing at
    the object I want to move away from
    (as theorised above) can I apply a
    negative force to move to move in
    the opposite direction? Or would it just be best to invert the transform while the object is too close?

Everything is written in UnityScript.

I hope this makes sense :wink:

Thanks

Paul

I made some changes to the code. I doesn’t involve physics anymore, but it’d be quite easy to implement.

#pragma strict

var enemyTransform : Transform;
var playerTransform : Transform;
var distance : float = 3;//distance the enemy's going to try keep
var deadZone : float = 1;//this is some kind of offset, in this dead zone, the enemy won't move. It's used to eliminate weird behaviour. Try to set it to 0 and see what happens.
var speed : float = 5;
/*var prev : Vector3;*/

function FixedUpdate () {
   var pPos : Vector3 = playerTransform.position;//position of the player
   var ePos : Vector3 = enemyTransform.position;//position of the enemy

   var curDist : float = Vector3.Distance(ePos,pPos);//distance between p and e

   var direction : Vector3 = (curDist > distance+deadZone?pPos-ePos:((curDist < distance-deadZone)?ePos-pPos:Vector3.zero)).normalized;//the direction between p and e. Note the use of ternary operators to determine if the direction should be towards the player, from the player or 0.

   /*enemyTransform.rigidbody.AddForce(-prev*speed, ForceMode.Force);*/
   enemyTransform.rigidbody.AddForce(direction*speed, ForceMode.Force);//you can change the force mode, if you want different behaviour.

   /*prev = direction;*/

}

–David

So you want to move an object towards a direction.

Vector3 direction = target.position - transform.position;
rigidbody.AddForce(direction*speed);

This will get your object in the direction. No need for angle compared to x-axis, teh vector indicates all that.

For the opposite direction simply revert the vector:

Vector3 direction = target.position - transform.position;
rigidbody.AddForce(-direction*speed);

See the minus sign?

Now this is goign to add force constantly so they will add up to reach warp speed.
You could then cance the previous force to get a smoother effect:

Vector3 previous = new Vector3(0f,0f,0f);
void Update(){
   rigidbody.AddForce(-previous*speed);   //Cancel previous
   Vector3 direction = target.position - transform.position;
   rigidbody.AddForce(direction*speed);  //Give new force
   previous = direction;                 //Store for next round
}

In the end, you are adding F0 then next frame you add -F0 and add F1 and so on.

There might be better solution though…