Follow target script is rotating only clockwise. Something simple?

Hi,

I’ve created a scene where a cube follows the mouse cursor :

http://www.garethelms.org/demo/unity3d/follow/WebPlayer.html

A script rotates the cube towards the target and speeds it up the more it is facing the target. I position a yellow sphere to where the cursor is for clarity.

The problem is that the cube only ever rotates clockwise. If you move the cursor so the cube needs a negative angle to face it, it spins a +360 to face it rather than -1. For example if you circle the cursor slowly around the cube in a clockwise direction the cube will keep up and rotate towards it. If you do the same in an anti-clockwise direction the cube spins the wrong way to try and face it.

How can I rotate the cube clockwise and ant-clockwise?

Here is my follow script :

public class FollowMouse : MonoBehaviour
{
	public GameObject Cursor; // This is the yellow sphere scripted to follow the mouse cursor
	public float RotationSpeed = 3;
	public float Speed = 10;

	void Update()
	{
		var direction = Cursor.transform.position - transform.position;
		var angle = Vector3.Angle( direction, transform.forward);
		transform.Rotate( Vector3.up, angle * (Time.deltaTime * RotationSpeed));
		
		// Divide by angle so that it slows down when facing away from target and speeds up when facing target 
		transform.Translate( Vector3.forward * (Time.deltaTime * (Speed / (angle / 5f))));
	}
}

Sorry if this is a basic question I’m very new to vectors/quaternions/angles but I’m determined to understand it all.

Thanks
Gareth

You might want to use Quaternion.LookRotation to get the rotation that you’ll need to look at the cursor and then use Quaternion.Slerp to interpolate between the object’s current rotation and the desired look at rotation.

But I think the problem you have now is that while Vector3.Angle will give you the smallest angle between two vectors, you still need to specify the direction of the rotation, i.e. whether the angle is positive or negative.

You can do that by testing for the dot product:

if (Vector3.Dot(direction, transform.forward) >= 0)
   transform.Rotate( Vector3.up, angle * (Time.deltaTime * RotationSpeed));
else
   transform.Rotate( Vector3.up, -angle * (Time.deltaTime * RotationSpeed));

You might want need to switch change the comparison from >= to <= if the cube rotates in the wrong directon.

//Finding the Target Vector:

targetpos = target.transform.position;

//This is my Missile’s Direction Forward:

missilevector = transform.forward;

// the direction in which the object (in my case the Ammo/ Rocket) should go:

directionvector = targetpos - transform.position;

// Finding the dot product between the 2 vectors to calculate the angle:

dotproduct = Vector3.Dot(missilevector,directionvector);

// Finding the Angle manually because (Vector3.Angle doesn’t give it in minus… this will give an absolute angle:

theta = Mathf.Acos(Mathf.Clamp(dotproduct/(missilevector.magnitude * directionvector.magnitude),0,1));

// This is the basic rotation, movement and all!

rotation1 = transform.rotation;

transform.LookAt(transform.position + directionvector * Time.deltaTime);

rotation2 = transform.rotation;

deltatheta = turningspeed * Time.deltaTime;//Mathf.Min(turningspeed * Time.deltaTime,theta);

t = deltatheta==0?theta:deltatheta/theta;
rotation3 = Quaternion.Slerp(rotation1,rotation2,t);

transform.rotation = rotation3;

speed +=acceleration*Time.deltaTime;

if(speed>=maxvel)

{

speed = maxvel;

}

transform.Translate(Vector3.forward * Time.deltaTime * speed);

i hope it helps… Main is the angle, you need to describe it well…