I am writing the enemy class of a 3d game I am making and am working on making the enemy follow the player. I want the enemy to basically rotate itself in the direction of the player a little bit every frame and move forward a bit every frame. I tried to use Lerping to accomplish this as seen in the code below, but I can't seem to get it to work. When playing, the enemies don't even appear in my field of view or chase me at all. Here is my code from my enemy class below.
Note: p is a reference to a player object that I am chasing, world is the enemy object's world matrix, quaternion is this enemy object's quaternion.
My current strategy is finding the direction vector in between the forward vector of my enemy and the location vector3 of the player and then lerping that by an amount determined by the velocity variable. Then, I try to find the perpendicular vector to the plane determined by the enemy's forward vector and that new lerped vector I call midVector.Then, I update my quaternion for the player to be rotated about that perpendicular vector. Here is the code below:
//here I get the direction vector in between where my enemy is pointing and where the player is located at
Vector3 midVector = Vector3.Lerp(Vector3.Normalize(world.Forward), Vector3.Normalize(Vector3.Subtract(p.position,this.position)), velocity);
//here I get the vector perpendicular to this middle vector and my forward vector
Vector3 perp=Vector3.Normalize(Vector3.Cross(midVector, Vector3.Normalize(world.Forward)));
//here I am looking at the enemy's quaternion and I am trying to rotate it about the axis (my perp vector) with an angle that I determine which is in between where the enemy object is facing and the midVector
quaternion = Quaternion.CreateFromAxisAngle(perp, (float)Math.Acos(Vector3.Dot(world.Forward,midVector)));
//here I am simply scaling the enemy's world matrix, implementing the enemy's quaternion, and translating it to the enemy's position
world = Matrix.CreateScale(scale) * Matrix.CreateFromQuaternion(quaternion) * Matrix.CreateTranslation(position);
//here i move the enemy forward in the direciton that it is facing
MoveForward(ref position, quaternion, velocity);
}
private void MoveForward(ref Vector3 position, Quaternion rotationQuat, float speed)
{
Vector3 addVector = Vector3.Transform(new Vector3(0, 0, -1), rotationQuat);
position += addVector * speed;
}
My question is both, what is wrong with my current strategy/implementation and is there an easier way for me to accomplish this (the first part is more important)?
You aren't storing your object's orientation from frame to frame. I think you are thinking that the quaternion you are creating is oriented in the objects new direction. But actually, it's just a quaternion that only represents the rotational difference between last frame and the current frame, not the overall orientation.
So what needs to happen is your new quat has to be applied to last frame's orientation quaternion to get a current frame orientation.
In other words, you are creating an inter-frame update quaternion, not the final orientation quaternion.
You need to do something like this:
enemyCurrentOrientation = Quaternion.Concatenate(lastFrameQuat, thisNewQuat);
There's probably is an easier way but if this way's working for you, no need to change it.