I always have yaw, pitch, and roll variables, then every frame I update them with the controller or whatever, then I create a quaternion using those variables, then I transform the "backward" vector with that quaternion. Make the camera position that vector (multiply it by whatever distance you want it to be from the player), add the player position to that vector, then set the target to the character position.
It's really not hard to do, and I would provide some sample code, but I'm a little lazy right now 
Aww, hell, here's some pseudo-code:
float yaw, pitch, roll;//Some variables that will be in your camera class or wherever you want them
//You could also just use a quaternion rather than those variables, then just multiply the quaternions.
//I feel it's a little better to use yaw, pitch, and roll since you can keep track of your camera's rotations a little better (doesn't really matter if it's a free camera anyway)
//I really don't know which is which with yaw pitch roll, but only two are important (I think yaw and pitch, yaw being up/down, pitch being rotation?)
//Anyway, doesn't matter. Just find out which is which, add to them using input from a controller/keyboard, then create your quaternion
Quaternion rotator = Quaternion.FromYawPitchRoll(yaw,pitch,roll);
float camDistance = 5.0f;
vector3 back = Vector3.Backward;
back = Vector3.Transform(back, rotator);//Rotate our vector
rotator *= distance;//Push it out a distance from the player)
rotator += playerPosition;//Add the position
View = Matrix.CreateLookAt(back, playerPosition, upVector);
Thanks for this, really helpful. I have managed to create an orbit and FPS camera, but there is room for improvement, I will factor in this concept.
I solved my problems however, and I created my FPS camera with head bobbing. This is the final code:
bool dxCamera::keyHeldA;
bool dxCamera::keyHeldS;
bool dxCamera::keyHeldW;
bool dxCamera::keyHeldD;
void dxCamera::perspectiveCamera(D3DXMATRIX &in_projectionMatrix, D3D10_VIEWPORT &in_viewPort, D3DXMATRIX &in_worldMatrix,
D3DXMATRIX &in_viewMatrix)
{
float yaw, pitch, roll;
D3DXMATRIX yawMatrix;
D3DXMATRIX pitchMatrix;
D3DXMATRIX rollMatrix;
D3DXMATRIX upLocal;
D3DXVECTOR3 Direction;
D3DXMATRIX directionMatrix;
// Set the yaw (Y axis), pitch (X axis), and roll (Z axis) rotations in radians.
rotation.x = m_rotationX * 0.0174532925f;
rotation.y = m_rotationY * 0.0174532925f;
rotation.z = m_rotationZ * 0.0174532925f;
//rotation.x = pitch;
//rotation.y = yaw;
//rotation.z = roll;
up = D3DXVECTOR3(0.0f, 1.0f, 0.0f);//Create the up vector
right = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
lookat = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
//D3DXVECTOR3 inputMoveVec[2] = {position, rotation};
// Setup matrices to rotate around axes
D3DXMatrixRotationAxis(&yawMatrix, &up, rotation.y);
D3DXMatrixRotationAxis(&pitchMatrix, &right, rotation.x);
//move lookat vector
D3DXVec3TransformCoord(&lookat, &lookat, &pitchMatrix);
D3DXVec3TransformCoord(&lookat, &lookat, &yawMatrix);
D3DXVec3Normalize(&lookat, &lookat);
//Get the direction vector from camera to target, normalise it.
//D3DXVec3Normalize(&Direction, &(lookat - right));
//Get the UP vector (in the world) and determine the cross product, to give us our right (left) hand vector.
D3DXVec3Cross(&right, &up, &lookat);
D3DXVec3Normalize(&right, &right);
//Cross product the right vector and direction vector, to determine up relative to the camera.
D3DXVec3Cross(&up, &lookat, &right);
//Useful for generation of direction looking at for future cameras
direction = atan2((double)lookat.z, (double)lookat.x);
velocity.x = (sin(direction));
velocity.y = 30.0f;
velocity.z = (cos(direction ));
D3DXMatrixIdentity(&in_viewMatrix);
in_viewMatrix._11 = right.x;
in_viewMatrix._21 = right.y;
in_viewMatrix._31 = right.z;
in_viewMatrix._12 = up.x;
in_viewMatrix._22 = up.y;
in_viewMatrix._32 = up.z;
in_viewMatrix._13 = lookat.x;
in_viewMatrix._23 = lookat.y;
in_viewMatrix._33 = lookat.z;
in_viewMatrix._41 = -D3DXVec3Dot(&(position), &right);
in_viewMatrix._42 = -D3DXVec3Dot(&(position), &up);
in_viewMatrix._43 = -D3DXVec3Dot(&(position), &lookat);
D3DXMatrixPerspectiveFovLH(&in_projectionMatrix, (float)D3DX_PI * 0.5f,
(float)in_viewPort.Width/(float)in_viewPort.Height, 0.1f, 5000.0f);
}
void dxCamera::initialiseFPSCamera(float in_headHeight, float in_bobPeriod, float in_bobScale)
{
bobPeriod = in_bobPeriod;
bobScale = in_bobScale;
headHeight = in_headHeight;
}
void dxCamera::walk(float speed, float sin)
{
bob = headHeight + sinf(sin * bobPeriod) * bobScale;
if(keyHeldW == true)
{
position.x += lookat.x * speed;
position.y = bob;
position.z += lookat.z * speed;
}
if(keyHeldS == true)
{
position.x -= lookat.x * speed;
position.y = bob;
position.z -= lookat.z * speed;
}
keyHeldW = false;
keyHeldS = false;
}
void dxCamera::strafe(float speed)
{
if(keyHeldA == true)
{
position -= right * speed;
}
if(keyHeldD == true)
{
position += right * speed;
}
keyHeldA = false;
keyHeldD = false;
}
void dxCamera::translateCamera(float &in_CameraX, float in_CameraY, float in_CameraZ)
{
position.x = in_CameraX;
position.y = in_CameraY;
position.z = in_CameraZ;
}
void dxCamera::rotateCamera(float &in_rotationX, float & in_rotationY, float &in_rotationZ)
{
m_rotationX = in_rotationX;
m_rotationY = in_rotationY;
m_rotationZ = in_rotationZ;
}
Edited by dxCUDA, 20 May 2012 - 04:42 PM.