简体   繁体   中英

How to fixate the camera on the player, so when the player moves the camera will follow

I am trying to make a OpenGL game in java in which you are a spaceship and you fly around in 3D space, the aim is to eliminate all of the enemy spaceships in the level. However, I cannot seem to figure out how to make the camera fixate/follow the player. I want to do this so that i can move the player (AKA: spacehip) around using user input and the camera will follow so that the player doesn't go out of sight (off the screen).

NOTE: I'm using modern OpenGL. (Shaders ...), not the fixed function pipeline.

(i'll explain in general code, not Java, but the syntax is easy to translate) Assuming you're using transformation with Matrix all the objects in the scene are rendered By:

B * M * P,

while:

B = Base (or View/Camera) matrix
M = Model (or objects, like the enemies or the player spaceship) matrix
P = Projection matrix

in the Update cycle, which comes before the rendering cycle, right after you update the player's spaceship Model matrix, change the Base matrix accordingly, for example to put the camera behind the spaceship first find the heading vector of the spaceship and the up vector of the spaceship :

Vector3 vHeading = shipMatrix * Vector3(0.0,0.0,1.0);
Vector3 vShipUp = shipMatrix * Vector3(0.0,1.0,0.0);

then create the camera matrix placed behind the spaceship and looking at the spaceship using a LookAt calculations:

/// set the offsets between the camera and the spaceship            ///
float distCameraToShip = 2.0;
float cameraElevation = 2.0;
// find the ship position                                            ///
Vector3 vShipTranslation = shipMatrix.GetTranslation();
/// or Vector3 vShipTranslation = shipMatrix * Vector3(0.0,0.0,0.0); ///

/// calculate the camera transformation                              ///
Vector3 vCameraPos = vShipTranslation - vHeading * distCameraToShip + vShipUp * cameraElevation;

Matrix4x4 cameraMatrix = LookAt(vCameraPos, vShipTranslation, vShipUp);

a LookAt Implementation:

CMatrix4x4 LookAt(Vector3 vEye, Vector3 vObject, Vector3 vUp)
{
Vector3 n = normalize(vEye - vObject);
        Vector3 u = cross(vUp , n);
        Vector3 v = cross(n , u);

        float m[16] = { u[0], v[0], n[0], 0.0f,
            u[1], v[1], n[1], 0.0f,
            u[2], v[2], n[2], 0.0f,
            (u * -1.0 * vEye) ,
            (v * -1.0 * vEye) ,
            (n * -1.0 * vEye),
            1.0f };

return m;
}

you use this camera matrix for all the rendering cycle and pass it to the shader ex:

////// Vertex shader ///

/// it is recommended to do the multiplication on the CPU and pass the ModelViewMatrix to the shader, here is just to example ///
uniform mat4 u_BaseMatrix;
uniform mat4 u_ModelMatrix;
uniform mat4 u_ProjectionMatrix;

in vec3 a_VerAttrib;

void main()
{
gl_Position = u_ProjectionMatrix * u_BaseMatrix * u_ModelMatrix * vec4(a_VertAttrib, 1.0);
}

now you can start manipulating the camera and give it all kinds of cool interpolations, like set the distance between the camera and the ship according to the ship's speed :

float distCameraToShip = 2.0 + pow(shipSpeed,2.0) * 0.1;

you can also use time smooth filter to give it a cool following effect:

/// dt = time diff between updating cycles, or 1/FrameRate ///
float ct = 1.0 / (1.0 + dt);
cameraMatrix = cameraMatrix + (previousCameraMatrix - cameraMatrix) * ct;

In order to keep the camera fixed of the player you will need to specify what what yaw and pitch (rotations) you would like applied to the camera and a distance away from the player then you would computer they distances to translate the camera so that you see the player from that angle.

Here is a brilliant tutorial on exactly what you are asking: https://youtu.be/PoxDDZmctnU

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM