I am a newbie in 3D game development and I am trying to make a real-time strategy game. I am struggling with the camera currently as I am unable to make it look like they do in RTS games.
Here is my Camera.cs class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace BB
{
public class Camera : Microsoft.Xna.Framework.GameComponent
{
public Matrix view;
public Matrix projection;
protected Game game;
KeyboardState currentKeyboardState;
Vector3 cameraPosition = new Vector3(600.0f, 0.0f, 600.0f);
Vector3 cameraForward = new Vector3(0, -0.4472136f, -0.8944272f);
BoundingFrustum cameraFrustum = new BoundingFrustum(Matrix.Identity);
// Light direction
Vector3 lightDir = new Vector3(-0.3333333f, 0.6666667f, 0.6666667f);
public Camera(Game game) : base(game)
{
this.game = game;
}
public override void Initialize()
{
this.view = Matrix.CreateLookAt(this.cameraPosition, this.cameraPosition + this.cameraForward, Vector3.Up);
this.projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, this.game.renderer.aspectRatio, 1, 10000);
base.Initialize();
}
/* Handles the user input
* @ param GameTime gameTime
*/
private void HandleInput(GameTime gameTime)
{
float time = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
currentKeyboardState = Keyboard.GetState();
}
void UpdateCamera(GameTime gameTime)
{
float time = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
// Check for input to rotate the camera.
float pitch = 0.0f;
float turn = 0.0f;
if (currentKeyboardState.IsKeyDown(Keys.Up))
pitch += time * 0.001f;
if (currentKeyboardState.IsKeyDown(Keys.Down))
pitch -= time * 0.001f;
if (currentKeyboardState.IsKeyDown(Keys.Left))
turn += time * 0.001f;
if (currentKeyboardState.IsKeyDown(Keys.Right))
turn -= time * 0.001f;
Vector3 cameraRight = Vector3.Cross(Vector3.Up, cameraForward);
Vector3 flatFront = Vector3.Cross(cameraRight, Vector3.Up);
Matrix pitchMatrix = Matrix.CreateFromAxisAngle(cameraRight, pitch);
Matrix turnMatrix = Matrix.CreateFromAxisAngle(Vector3.Up, turn);
Vector3 tiltedFront = Vector3.TransformNormal(cameraForward, pitchMatrix * turnMatrix);
// Check angle so we cant flip over
if (Vector3.Dot(tiltedFront, flatFront) > 0.001f)
{
cameraForward = Vector3.Normalize(tiltedFront);
}
// Check for input to move the camera around.
if (currentKeyboardState.IsKeyDown(Keys.W))
cameraPosition += cameraForward * time * 0.4f;
if (currentKeyboardState.IsKeyDown(Keys.S))
cameraPosition -= cameraForward * time * 0.4f;
if (currentKeyboardState.IsKeyDown(Keys.A))
cameraPosition += cameraRight * time * 0.4f;
if (currentKeyboardState.IsKeyDown(Keys.D))
cameraPosition -= cameraRight * time * 0.4f;
if (currentKeyboardState.IsKeyDown(Keys.R))
{
cameraPosition = new Vector3(0, 50, 50);
cameraForward = new Vector3(0, 0, -1);
}
cameraForward.Normalize();
// Create the new view matrix
view = Matrix.CreateLookAt(cameraPosition, cameraPosition + cameraForward, Vector3.Up);
// Set the new frustum value
cameraFrustum.Matrix = view * projection;
}
public override void Update(Microsoft.Xna.Framework.GameTime gameTime)
{
HandleInput(gameTime);
UpdateCamera(gameTime);
}
}
}
The problem is that the initial view is looking in a horizontal direction. I would like to have an RTS like top down view (but with a slight pitch). Can you help me out?