I’ve been using a camera set up I found online and it has been working perfectly. But I’m having trouble getting the camera to roll. I don’t think the code I found was set up for this and I’m not familiar enough to get it working.
public class _3DCamera //: GameComponent
{
//Attributes
private Vector3 cameraPosition;
private Vector3 cameraRotation;
private float cameraSpeed;
private Vector3 cameraLookAt; //defines the direction camera is currently looking
private Vector3 mouseRotationBuffer;
private MouseState currentMouseState;
private MouseState prevMouseState;
private bool enableMouse = false;
private Vector3 savedCameraPosition;
private Vector3 savedCameraRotation;
private Vector3 destinationCameraPosition;
private Vector3 destinationCameraRotation;
public float lifeSpan = 0;
public float lifeTimer = 0;
private bool DestinationReachedCameraPosition = true;
private bool DestinationReachedCameraRotation = true;
//Properties
public Matrix Projection
{
get;
protected set;
}
public Vector3 Position
{
get { return cameraPosition; }
set
{
cameraPosition = value;
UpdateLookAt(); //any time the position changes, it calls update look at
}
}
public Vector3 Rotation
{
get { return cameraRotation; }
set
{
cameraRotation = value;
UpdateLookAt(); //any time the rotation changes, it calls update look at
}
}
public Matrix View //Defines entire view of camera. Where it's located, it's target and the up vector. Essentially creating a transform with forward, up, and relative camera position.
{ //view and projection needed for camera's orientation in 3D space.
get
{
return Matrix.CreateLookAt(cameraPosition, cameraLookAt, Vector3.Up);
}
}
//Constructor
public _3DCamera(Game game, Vector3 position, Vector3 rotation, float speed)
// : base(game)
{
cameraSpeed = speed;
//set up projection matrix
//Orthographic project = 2D, Perspective = 3D
Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, game.GraphicsDevice.Viewport.AspectRatio, 0.05f, 1000.0f);
//1000 = draw distance . That's when things are drawn into camera, or "pop in"
//Set camera position and rotation
MoveTo(position, rotation);
prevMouseState = Mouse.GetState();
}
//Method that essentially just moves camera
//Set camera's position and rotation
private void MoveTo(Vector3 pos, Vector3 rot)
{
Position = pos;
Rotation = rot;
}
public void CameraMoveTo(Vector3 DestinationCameraPosition, float TimeToReach)
{
CameraMoveTo(DestinationCameraPosition, Rotation, TimeToReach);
}
public void CameraMoveTo(Vector3 DestinationCameraPosition, Vector3 DestinationCameraRotation, float TimeToReach)
{
savedCameraPosition = Position;
savedCameraRotation = Rotation;
destinationCameraPosition = DestinationCameraPosition;
destinationCameraRotation = DestinationCameraRotation;
DestinationReachedCameraPosition = false;
DestinationReachedCameraRotation = false;
lifeTimer = 0;
lifeSpan = TimeToReach;
}
private void MoveCamera(float elapsedTime)
{
lifeTimer += elapsedTime;
float xTime = lifeTimer / lifeSpan;
//Vector3 moveVector = Vector3.Zero;
Position = new Vector3(
savedCameraPosition.X + ((destinationCameraPosition.X - savedCameraPosition.X) * xTime),
savedCameraPosition.Y + ((destinationCameraPosition.Y - savedCameraPosition.Y) * xTime),
savedCameraPosition.Z + ((destinationCameraPosition.Z - savedCameraPosition.Z) * xTime)
);
Rotation = new Vector3(
savedCameraRotation.X + ((destinationCameraRotation.X - savedCameraRotation.X) * xTime),
savedCameraRotation.Y + ((destinationCameraRotation.Y - savedCameraRotation.Y) * xTime),
savedCameraRotation.Z + ((destinationCameraRotation.Z - savedCameraRotation.Z) * xTime)
);
if (lifeTimer > lifeSpan)
{
DestinationReachedCameraPosition = true;
DestinationReachedCameraRotation = true;
lifeTimer = 0;
Position = destinationCameraPosition;
Rotation = destinationCameraRotation;
}
}
private bool DestinationReached()
{
return DestinationReachedCameraPosition && DestinationReachedCameraRotation;
}
//Method that simulates movement
private Vector3 PreviewMove(Vector3 amount)
{
//Create a rotate matrix
//this will only include the rotation around the y axis, the yaw
Matrix rotate = Matrix.CreateRotationY(cameraRotation.Y);
//Create a movement vector
Vector3 movement = new Vector3(amount.X, amount.Y, amount.Z);
movement = Vector3.Transform(movement, rotate);
//return the value of camera position + movement vector
return cameraPosition + movement;
}
//Method that actually moves the camera, by a scale factor
private void Move(Vector3 scale)
{
MoveTo(PreviewMove(scale), Rotation);
}
//update the look at vector
private void UpdateLookAt()
{
//first build a rotation matrix
Matrix rotationMatrix = Matrix.CreateRotationX(cameraRotation.X) * Matrix.CreateRotationY(cameraRotation.Y) * Matrix.CreateRotationZ(cameraRotation.Z);
//second create a lookat offset. The change in lookat based on change on rotation and the forward vector, unit z
Vector3 lookAtOffset = Vector3.Transform(Vector3.UnitZ, rotationMatrix);
//third, update the camera's look at vector
cameraLookAt = cameraPosition + lookAtOffset;
}
public void Update(GameTime gameTime, Game game)
{
float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
if(!DestinationReached())
MoveCamera(dt);
currentMouseState = Mouse.GetState();
KeyboardState ks = Keyboard.GetState();
//Handle basic key movement
/*
Vector3 moveVector = Vector3.Zero;
if (ks.IsKeyDown(Keys.I) || ks.IsKeyDown(Keys.NumPad5))
moveVector.Z = 1;
if (ks.IsKeyDown(Keys.K) || ks.IsKeyDown(Keys.NumPad1) || ks.IsKeyDown(Keys.NumPad3))
moveVector.Z = -1;
if (ks.IsKeyDown(Keys.J) || ks.IsKeyDown(Keys.NumPad4))
moveVector.X = 1;
if (ks.IsKeyDown(Keys.L) || ks.IsKeyDown(Keys.NumPad6))
moveVector.X = -1;
if (ks.IsKeyDown(Keys.NumPad8))
moveVector.Y = 1;
if (ks.IsKeyDown(Keys.NumPad2))
moveVector.Y = -1;
if (moveVector != Vector3.Zero)
{
//normalize the vector
//so that we don't move faster diagonally
//because what happens is... because the hypotenuse has to be greater than the other two sides of a triangle
//but if we normalize it, we can ensure the same speed
moveVector.Normalize();
//now we add in smooth and speed
moveVector *= dt * cameraSpeed;
//Move camera
Move(moveVector);
}
*/
if (ks.IsKeyDown(Keys.Space))
enableMouse = true;
else
enableMouse = false;
if (enableMouse)
{
float deltaX;
float deltaY;
float deltaZ;
if (currentMouseState != prevMouseState)
{
if (currentMouseState.LeftButton == ButtonState.Pressed)
{
// Do cool stuff here
deltaZ = currentMouseState.X - (game.GraphicsDevice.Viewport.Width / 2);
mouseRotationBuffer.Z -= 0.05f * deltaZ * dt;
Rotation = new Vector3(Rotation.X, Rotation.Y, MathHelper.WrapAngle(mouseRotationBuffer.Z));
}
else
{
//Cache mouse location
deltaX = currentMouseState.X - (game.GraphicsDevice.Viewport.Width / 2);
deltaY = currentMouseState.Y - (game.GraphicsDevice.Viewport.Height / 2);
mouseRotationBuffer.X -= 0.05f * deltaX * dt;
mouseRotationBuffer.Y -= 0.05f * deltaY * dt;
if (mouseRotationBuffer.Y < MathHelper.ToRadians(-75.0f))
mouseRotationBuffer.Y = mouseRotationBuffer.Y - (mouseRotationBuffer.Y - MathHelper.ToRadians(-75.0f));
if (mouseRotationBuffer.Y > MathHelper.ToRadians(75.0f))
mouseRotationBuffer.Y = mouseRotationBuffer.Y - (mouseRotationBuffer.Y - MathHelper.ToRadians(75.0f));
Rotation = new Vector3(-MathHelper.Clamp(mouseRotationBuffer.Y, MathHelper.ToRadians(-75.0f), MathHelper.ToRadians(75.0f)),
MathHelper.WrapAngle(mouseRotationBuffer.X), 0);
deltaX = 0;
deltaY = 0;
}
}
Mouse.SetPosition(game.GraphicsDevice.Viewport.Width / 2, game.GraphicsDevice.Viewport.Height / 2);
}
prevMouseState = currentMouseState;
// base.Update(gameTime);
}
}