I am working in a 3D spaceship game and I am in the enemy class. For now I am working on XNA and if I manage to do a cool project then I will port it to unity. OK. The thing is that I am stuck with the following.
I want to create an enemy that will turn towards the player position at any of the X, Y and Z axis. I already have somewhat working code, but for some reason it only works in one axis only.
This is what I have so far.
private float TurntoFace(Vector3 position, Vector3 faceThis, float currentAngle, float turnSpeed)
{
float x = faceThis.X - position.X;
float z = faceThis.Z - position.Z;
float retval;
float desiredAngle = (float)Math.Atan2(-z, x);
float difference = desiredAngle - currentAngle;//WrapAngle(desiredAngle - currentAngle);
if (difference > TURN_RATE)
{
look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(up_, TURN_RATE));
retval = currentAngle + TURN_RATE;
}
else if (difference < -TURN_RATE)
{
look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(up_, -TURN_RATE));
retval = currentAngle - TURN_RATE;
}
else
{
look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(up_, difference));
retval = currentAngle + difference;
}
right_ = Vector3.Cross(look_, up_);
return retval;
}
As I said, this code makes the enemy turns towards the player on one axis only. But it won't make it roll or pitch towards it. I tried many other ways to achieve my desired results, but nothing seems to work. I modified the code in the follosing way.
private float TurntoFace(Vector3 position, Vector3 faceThis, float currentAngle, float turnSpeed)
{
float x = faceThis.X - position.X;
float z = faceThis.Z - position.Z;
float y = faceThis.Y - position.Y;
float retval;
float desiredAngle = (float)Math.Atan2(-z, x);
float otherAngle = (float)Math.Atan2(-z, y);
float difference = desiredAngle - currentAngle;//WrapAngle(desiredAngle - currentAngle);
float otherDifference = otherAngle - currentAngle;
if (difference > TURN_RATE)
{
look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(up_, TURN_RATE));
retval = currentAngle + TURN_RATE;
}
else if (difference < -TURN_RATE)
{
look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(up_, -TURN_RATE));
retval = currentAngle - TURN_RATE;
}
else
{
look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(up_, difference));
retval = currentAngle + difference;
}
if (otherDifference > TURN_RATE)
{
look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(right_, TURN_RATE));
retval = currentAngle + TURN_RATE;
}
else if (otherDifference < -TURN_RATE)
{
look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(right_, -TURN_RATE));
retval = currentAngle - TURN_RATE;
}
else
{
look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(right_, otherDifference));
retval = currentAngle + otherDifference;
}
right_ = Vector3.Cross(look_, up_);
return retval;
}
This stops the enemy from rotating towards the player and instead makes it rotate constantly, but still it won't pitch or roll. Any help will be appreciated.
Thanks