OK, you set your rotation thorugh a slerp of a lookrotation at a speed. Then you check to see if the distance is greater than a “max” distance and move it forward at speed.
Though confusing, the premise works. It needs to be cleaned up.
So I tinkered with it some and came up with a working solution. I added a bit to the solution as well.
Changes:
I added a ground checker. This will allow the unit to move up and down inclines and such. I added in gravity, so that he can fall. Physics check omit the current object. This may have to be redone to specify a ground or floor if multiple mobs interfere with each other.
I added a Dot check to see if the target was in front of or behind the unit. I also added in a 0.4 rotational amount so that the unit has to be in the front 60% of the view before the unit moves.
I changed “Max” distance to “Min” distance and added in the corrected “Max” distance to handle if things are too far away. I also added in the code that makes him not move if these events happen.
I changed the way the Slerp and look at rotations are done to make more sense.
I set the rotation of the euler.x to zero so that the unit does not face up or down, always level.
I changed the position reorientation to Translate. (easier to develop and understand)
I tested it, to verify that the gravity and movement features work. In testing I increased and decreased the rotation speed to see if I could always stay behind the target.
var target : Transform;
var moveSpeed : float = 5.0;
var rotationSpeed : float = 2.0;
var minDistance : float = 2.0;
var maxDistance : float = 30.0;
function Start () {
var go : GameObject = GameObject.FindGameObjectWithTag("Player");
target = go.transform;
minDistance = 2;
}
function Update () {
CheckGround();
// check to see if we are out of bounds to move
if((target.position - transform.position).magnitude < minDistance) return;
if((target.position - transform.position).magnitude > maxDistance) return;
// hold current rotation
var rotation = transform.rotation;
// set the look rotation
transform.LookAt(target);
// make sure that the X value in the euler is set to zero.
transform.localEulerAngles.x = 0; // so we dont end up looking up or down
// Slerp from the old rotation to the new rotation
transform.rotation = Quaternion.Slerp(rotation, transform.rotation, rotationSpeed * Time.deltaTime);
// get the direction to target
var direction = target.position - transform.position;
// check the direction to see if it is forward of the ai
var checkForward = Vector3.Dot(transform.forward, direction.normalized);
// if we are close to facing in the right direction move forward
if(checkForward > 0.4) transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
}
function CheckGround(){
//check our grounding
var ray = new Ray(transform.position + Vector3.up * 2.0, -Vector3.up);
var hits : RaycastHit[];
hits = Physics.RaycastAll(ray, 2.1);
var didHit = false;
for(var hit : RaycastHit in hits){
if(hit.transform.root != transform.root){
didHit = true;
transform.position = hit.point;
}
}
// if we did not hit, we need to fall
if(! didHit){
transform.position += Physics.gravity * Time.deltaTime;
}
}
Hope it helps u out.