setup I have a AI agent (turret) that has a set arc that it rotates along (90 degrees), with a given field of view (30 degree cone). I have got the agent to rotate on the arc, but I have a problem with having the turret when the player is inside the FOV to get the agent to track the player, and follow.
I tried to use the following method to have the agent track the player:
void FiringPos(Vector3 target) {
if(angle < 1){
print ("fire");
}else{
transform.forward = Vector3.Slerp(transform.forward, target, Time.deltaTime);
}
}
this tracks the player at the rate that I want, but when this gets within 10-15 degrees it stops tracking, and starts gittering (bouncing between values that are less then 1.0 from each other), and if the player moves to a greater angle within the FOV the agent starts tracking again until it is back within 10-15 degrees and starts gittering again.
so I tried to replace the Slerp()
call with a Lerp()
.
this as soon as the player enters the FOV at any point it jumps to the exact angle of the player.
is there any way that I could meld the 2 of these together, or get rid of the gitter in the Slerp()
.
Here are three ways to look “towards” a target. Note that the target vector is a position in world space coordinates.
// This will rotate with a certain speed
void SmoothLookAt(Vector3 target, float speed)
{
Vector3 dir = target - transform.position;
Quaternion targetRotation = Quaternion.LookRotation(dir);
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, Time.deltaTime * speed);
}
// This will rotate with a decelerated speed (not frame independent)
void SmoothLookAt(Vector3 target, float smooth)
{
Vector3 dir = target - transform.position;
Quaternion targetRotation = Quaternion.LookRotation(dir);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * smooth);
}
// This should be the same as the decelerated version (also not frame independent)
void SmoothLookAt(Vector3 target, float smooth)
{
Vector3 dir = target - transform.position;
transform.forward = Vector3.Slerp(transform.forward, dir, Time.deltaTime * smooth);
}
All those functions haven’t beed tested.
First off, it would be nice to have a bit more context - where is angle defined, what does it mean, what calls FiringPos (is it called every Update()?), etc. Second, depending on how angle is defined, you may want to be using (Mathf.Abs(angle) < 1).
However, those are both minor things. The meat of the problem that I see is that you aren’t using Slerp correctly. Slerp basically figures out a rotation path from a start orientation to an end orientation. You then pass it a number between 0 and 1 telling it where on that path you want to be. So passing in Time.deltaTime doesn’t make sense. What you need is to pick some start time, and then pass it (Time.time - startTime). Thus, in the first frame you’ll be passing it 0 (the start of the path), the next frame some further point along the path, and so on until your reach 1 (the end of the path).
Hope that helps.