2
\$\begingroup\$

There are loads of questions (all of which I have looked at) on here about cameras following objects. Using them, I have successfully got my camera to follow my car when driving, but I am unable to make the camera swing right when the car turns left (so it stays directly behind it) and vice-versa.

So far, this is how I've got my camera following my object:

    camOrigin.x  = (0   +globalPos.x+velocity.x); //Camera Position
    camOrigin.y  = (0   +globalPos.y+velocity.y);
    camOrigin.z  = (100 +globalPos.z+velocity.z);
    camLookingAt.x = (0 +globalPos.x+velocity.x); //Camera Looking at Object
    camLookingAt.y = (0 +globalPos.y+velocity.y);
    camLookingAt.z = (0 +globalPos.z+velocity.z);
    camNormalXYZ.x = (0);                         //Camera Normal = Y
    camNormalXYZ.y = (1);
    camNormalXYZ.z = (0);

I have tried to use the same algebra I've used to calculate the cars direction and velocity because I figured the angle the camera moves would be the inverted angle the camera needs to move, but it didn't work.

    camOrigin.x  = (0   +globalPos.x+velocity.x-sin(rotX_rad)); //Camera Position
    camOrigin.y  = (0   +globalPos.y+velocity.y);
    camOrigin.z  = (100 +globalPos.z+velocity.z-cos(rotX_rad));

I'm unsure how to take this further.

Edit: Little drawing to help describe the movement. I'm looking to move the camera from c to d when the car turns in the left direction (and vice-versa when turning right).

enter image description here

Update:

    rotX_rad = rotX*PI/180;     //convert to radians
    velocity.x = sin(rotX_rad); //calculate X coord
    velocity.z = cos(rotX_rad); //calculate Z coord

    //globalPos + velocity;
    globalPos.x + velocity.x*delta;
    globalPos.z + velocity.z*delta;

    ModelViewMatrix = glm::translate(viewMatrixMovingCube,globalPos);           //move/update car

    ModelViewMatrix = glm::translate(ModelViewMatrix,  glm::vec3(0,-48,0));     //position low on screen
    ModelViewMatrix = glm::rotate(ModelViewMatrix, rotX, glm::vec3(0,1,0));     //manually turn/control rotation of car
\$\endgroup\$
  • \$\begingroup\$ can you explain what is not working in your current approach \$\endgroup\$ – concept3d Dec 8 '13 at 8:10
  • \$\begingroup\$ @concept3d, The camera isn't moving like the car is; when the car turns right, the camera stays there and watches the right side of the car, I would like it to stay behind it while it's driving. \$\endgroup\$ – Reanimation Dec 9 '13 at 6:47
3
\$\begingroup\$

A common base approach is to model the camera as though it were towed behind your character/vehicle on a free-swinging bar.

To do this, you keep track of an intended follow distance d and an intended height h.

Each frame, take the vector from your follow target (after it has moved) to the camera (before it has moved). Normalize it, multiply it by d, then correct the height to h. Now add it to your follow target's position to get your new camera position (you can either set it directly, or lerp the camera toward it for a softer camera feel)

This gives a camera that will be gradually pulled behind you anytime you move away from it. It's a conceptually-simple base, but it has some problems on its own so you'll need to layer additional behaviour on-top:

  • The speed with which the camera gets behind you is inversely proportionate to the follow distance - a close camera swings responsively (maybe even a bit twitchy) while a distant one barely moves. You can fix this by tracking a "fake" camera at a fixed distance from your player that feels like the right balance, then multiplying its offset by a scaling factor to get your real camera offset.

  • It needs some help getting around sharp corners. Normally it follows a curve of pursuit, which means it lazily cuts corners whenever it can. Adding a multiple of the player's "back" vector (negative forward) to the offset before you normalize it helps.

  • Play with the look direction - you'll probably want the camera to look at a point above the follow target, and a ways ahead of it (this pushes the target toward the bottom of the screen so you can see more of what's ahead). Biasing this anticipation vector according to velocity and steering can help the camera feel responsive, without it moving around too much.

\$\endgroup\$
  • \$\begingroup\$ This is a simple base for third-person exploration where you want the character to be able to turn around in-place. If you want a more rigid, racing game type camera, then just set(/lerp) your camera to the player's position plus a combination of their back & up vectors each frame. Rather than a free-swinging bar, this models a rigid bar sticking out the back of the vehicle. The notes on look direction still apply. \$\endgroup\$ – DMGregory Dec 8 '13 at 13:58
  • \$\begingroup\$ Thanks for posting, that's great. I've already implemented the "constant distance" as if it were attached to the car and it follows it, but I am unable to get it to swing around corners (making it stay behind it)... I get the feeling I need to use cos/sin or some algebra to make the camera stay being it. Because currently, when I turn, the camera doesn't. \$\endgroup\$ – Reanimation Dec 8 '13 at 20:34
  • \$\begingroup\$ Have you tried either bullet point 2, or the rigid bar method from my first comment? Both of these specifically address getting the camera to stay behind you on a curve. \$\endgroup\$ – DMGregory Dec 10 '13 at 16:33
  • \$\begingroup\$ I'm going to be trying it this evening. But I'm still trying to get my head around how to approach it as my camera at the moment doesn't rotate and only faces north, no matter the direction of the car. \$\endgroup\$ – Reanimation Dec 10 '13 at 16:44
  • \$\begingroup\$ That part's fairly straightforward. How do you specify a rotation for your camera? Look target + up vector, view matrix, quaternions, Euler angles, other? \$\endgroup\$ – DMGregory Dec 10 '13 at 16:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.