# Creating a 3rd Person Flying Camera for 3D asteroids game

In order to learn PyOpenGL and test out an engine I am developing, I am trying to write a 3D asteroids flying space shooter game. Currently, I am implementing the camera using a "look at" function positioned right behind the player's ship. The player is able to control the yaw and pitch with the left+right and up+down arrow keys respectively. The results look like this (forgive the placeholder art):

And here is the code snippet in my Player class that implements that:

from pyorama.entity import Entity
from pyorama.math3d.vec3 import Vec3
from pyorama.math3d.mat4 import Mat4
import math

class Player(Entity):

def __init__(self, model, camera):
self.model = model
self.center = self.model.mesh.compute_bounding_sphere().center
self.model.transform = self.model.transform.translate(-self.center)
self.camera = camera
self.key_down_status = {"Left": False, "Right": False, "Up": False, "Down": False}
super(Player, self).__init__()

def update(self):
messages = super(Player, self).update()
for message in messages:
if message.event_type == "key_down":
key = message.data["key_name"]
if key in self.key_down_status.keys():
self.key_down_status[key] = True
if message.event_type == "key_up":
key = message.data["key_name"]
if key in self.key_down_status.keys():
self.key_down_status[key] = False

self.model.transform = self.model.transform.translate(self.center)
if self.key_down_status["Up"]:
self.model.transform = self.model.transform.rotate_x(-0.01)
if self.key_down_status["Down"]:
self.model.transform = self.model.transform.rotate_x(0.01)
if self.key_down_status["Left"]:
self.model.transform = self.model.transform.rotate_y(0.01)
if self.key_down_status["Right"]:
self.model.transform = self.model.transform.rotate_y(-0.01)
self.model.transform = self.model.transform.translate(-self.center)
self.model.transform = self.model.transform.translate(Vec3(0, 0, 0.1))

right = self.model.transform.data[0:3]
up = Vec3(*self.model.transform.data[4:7])
forward = Vec3(*self.model.transform.data[8:11])
position = Vec3(*self.model.transform.data[12:15])

temp = self.model.transform
self.model.transform = self.model.transform.translate(+self.center)
right = self.model.transform.data[0:3]
up = Vec3(*self.model.transform.data[4:7])
forward = Vec3(*self.model.transform.data[8:11])
position = Vec3(*self.model.transform.data[12:15])

self.camera.view = Mat4.look_at(position - 20 * forward, position, up)
self.model.transform = temp


As you can see, the ship stays perfectly still behind and the world rotates around. As a result, it looks very unnatural, as if a 2D ship sprite was simply glued onto the screen!

So my question is, how are third-person cameras in flying games typically implemented? What would a keyboard+mouse control scheme look like that controls yaw, pitch, roll, banking, acceleration/deceleration, etc? Would the camera controls for the camera be separated from moving the ship? Any help would be greatly appreciated.

The camera control is usually semi-separated from the ship's rotation. Instead of making the camera have the same angles as the ship, the camera should try getting closer to the ship's angles.

In your update method get the difference between the ship's angles and the camera's angles, multiply it with a value between 1 and 0 (The greater the value is, the faster the camera will follow the ship) then add it to the camera's angles.

• Haven't had the time to try out your answer yet but thanks, it seems pretty intuitive now! I will update the question with the working result. Jan 17 '17 at 9:52