I want to make my own very simple version of the LookAt() method, just because LookAt is a bit too perfect and I want my NPCs to turn a bit more slowly.
I know I need to have a variable for angular speed which increments/decrements based on the angle of the GameObject and the target in the Update() method. But how would I get that angle? I tried using Vector3.Angle(transform.position,target.position) but it didn’t work as I expected.
Can anyone help, or direct me an appropriate resource?
Here is a script that implements an adjustable version of LookAt(). There are four main things that take place in this script. First, the vector to the target is calculated. Second, the angle between the forward direction and the vector to the target is calculated. Third, if the angle is outside the range determined by the look threshold, the rotational direction to the target is calculated. Fourth, the rotation of the correct direction is applied.
There are three public variables:
target is the GameObject to look at
lookSpeed determines the speed at
which the object rotates towards the
target
lookThreshold determines how close
the object will rotate towards the
target (measured in degrees)
lookSensitivity determines how
closely the object will align itself
to the attempted rotation.
Good starting values are:
lookSpeed = 0.5
lookThreshold = 1
lookSensitivity = 0.1
By adjusting these values you can achieve behaviour that is less than perfect. Note that at extreme values the behaviour may become erratic.
The script should be attached to the NPC.
AdjustableLookAt.js
#pragma strict
public var target : GameObject;
public var lookSpeed : float;
public var lookThreshold : float;
public var lookSensitivity : float;
function Update()
{
AdjustableLookAt(target.transform);
}
function AdjustableLookAt(targetTransform : Transform)
{
//Calculate the vector to the target
var toTarget = targetTransform.position - transform.position;
//Rotate if the angle to the target is outside the threshold
if (Mathf.Abs(Vector3.Angle(transform.forward, toTarget)) > lookThreshold || Mathf.Abs(Vector3.Angle(transform.forward, toTarget)) < -lookThreshold)
{
//Check whether we should rotate CW or CCW to the target
if (Vector3.Dot(Vector3.Cross(toTarget, transform.forward), transform.up) > lookSensitivity)
{
//We should rotate CCW
transform.Rotate(transform.up * lookSpeed);
}
else if (Vector3.Dot(Vector3.Cross(toTarget, transform.forward), transform.up) < -lookSensitivity)
{
//We should rotate CW
transform.Rotate(transform.up * -lookSpeed);
}
}
}