Rather than using Vector3.Forward
, pull the .Forward
and .Up
vectors from your rotation matrix:
public void UpdateMatrices()
{
/// assumes Rotation is a Vector3 containing rotation around each axis expressed in radians
Matrix rotationMatrix = Matrix.CreateFromYawPitchRoll(Rotation.Y, Rotation.X, Rotation.Z);
/// View = Matrix.CreateLookAt(Position, Rotation, Vector3.Forward);
View = Matrix.CreateLookAt(Position, Position + rotationMatrix.Forward, rotationMatrix.Up);
Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, nearClip, farClip);
/// World matrix needs to match your translation and rotation used above
/// XNA expects matrices to be concatenated in SRT (scale, rotation, then translate) order:
World = rotationMatrix * Matrix.CreateTranslation(Position);
CamBoundingFrustrum = new BoundingFrustum(View * Projection);
}
Note that you have to add the camera's translation (via a vector you're storing, or from the camera's world matrix .Translation
property) to the RotationMatrix.Forward
to get a real target.
The matrix .Forward
, .Backward
,.Left
,.Right
,.Up
and .Down
properties are the same as the equivalent Vector3
properties transformed by the rotation matrix. so, RotationMatrix.Forward
points in the direction you're looking, .Up
is orthogonal to that, etc.
If you just use Vector3.Forward
, you don't get a transformed vector, and weird things can happen.
Other notes:
- Don't make everything static. Create an instance of your camera class during
Game.Initialize()
and add it as a property.static
should be used with caution - it can cause all sorts of fun threading issues that will drive you insane. - I'd also recommend switching to a quaternion instead of yaw/roll/pitch (if you haven't already) since it avoids gimble lock, but that's a different topic.