Third Person Camera

Figured I’d upload this third person camera I’ve been making since I put quite a bit of work into it.

The logic brick setup is extremely simple since it mostly consists of Python code.

In addition to mouse smoothing and zooming, it uses ray sensors to avoid objects that have a “camera blocking” property. For example, if an object passes between the player character and the camera, the camera will jump in front of the object. If there is an obstruction behind the camera, it will move closer to the player to avoid clipping through walls and the like.

I put a couple planes in the scene with the camera blocking property to demonstrate this feature.

Hope you guys find it useful! :smiley:

EDIT:

Did a bit more work on the camera. The updated file is in a post below.

3rdPersonCamera_v2.blend (434 KB)

2 Likes

Thank you it was very useful!

Forgot to mention this before.

Feel free to use the code for whatever you want, commercial or otherwise. I wouldn’t mind being credited though.

I will use it and you will be in the Credits for the game, and I’m asking cause I don’t want to mess this up: Can you add a Zoom function to it? (I can but its cheap)

It already has zoom. It’s mapped to the E and Q keys in the blend file.

Near the top of the script you’ll see these lines:

ZoomIn = bge.events.EKEY
ZoomOut = bge.events.QKEY

If you want to use the mouse wheel to zoom, just change them to this:

ZoomIn = bge.events.WHEELUPMOUSE
ZoomOut = bge.events.WHEELDOWNMOUSE

I’d love to see you game when it’s done by the way.

Did a bit more work on it. It now supports horizontal offset so you get a nice over-the-shoulder effect when you zoom in.

The mouse wheel now zooms in and out. the middle mouse button toggles which side the camera is on.

Here’s the new file.

3rdPersonCamera_v2.blend (434 KB)

is there a way that the camera could go 360° on the y-axis?

ps: thx mobious it was ur script that made it possible for me to continue on my gameproject

Sure, just delete lines 112-146 and replace them with this.

    inv = 1
    own['x'] += x
    own['y'] -= y
    
    if own['x'] > math.pi:
        own['x'] -= 2*math.pi
    elif own['x'] <= -2*math.pi:
        own['x'] += 2*math.pi
    if own['y'] > math.pi:
        own['y'] -= 2*math.pi
        inv = -1
    elif own['y'] < 0.0:
        own['y'] += 2*math.pi
        inv = -1
    
    # LR toggling and smoothing
    if keys[ToggleLR] == 1:
        own['LRinv'] *= -1
    dist = own['LRinv']*HOR_OFFSET - own['LR']
    own['LR'] += dist / LRSMOOTH
    dist = own['LR'] / math.pow(own['dist'], 2)
    
    # calculate and set new camera position
    own['tdist'] = own['dist']*math.fabs(math.cos(math.pi/2 - own['y']))
    zshift = own['dist']*math.sin(math.pi/2 - own['y'])
    z = player.worldPosition[2] + zshift + Z_OFFSET
    yshift = own['tdist']*-math.cos(own['x'])
    y = player.worldPosition[1] + yshift + dist*math.sin(own['x'])
    xshift = own['tdist']*math.sin(own['x'])
    x = player.worldPosition[0] + xshift + dist*math.cos(own['x'])
    x *= inv
    y *= inv
    own.worldPosition = [x,y,z]
    
    #set new camera angle
    vec = mathu.Vector((own['y'], 0, own['x']))
    own.localOrientation = vec

Now all we need is to add some character moving like forward ^^ AWESOME SCRIPT by the way :smiley:

This is great Mobious – is there a way to limit rotation of the camera in either the up/down direction or the left/right direction?

There’s already a vertical limit. If you want to change it, just adjust the value of MIN_ANGLE at the top of the script. If you want to implement at horizontal limit, you can do a few small tweaks of your own. Check lines 122-125 for how the vertical limit is implemented. Just do something similar in lines 116-121.

As a side note, looking back on this script now I notice it’s somewhat sloppy. There are unused variables laying around, and it could use a bit of optimization. I may come back to it sometime and rework it, but for now at least it’s functional.

Thanks Mobious - love how well this script works! I didn’t find a variable called MIN_ANGLE, only a MIN_DIST; but I was able to limit the vertical angle with the bounds you set at lines 109 - 112.

Oh, you’re using the first version. I was looking at the second version of the script. It has a couple more features that are handy if you want to download it (it’s in post #6).

No way… this is really cool… thank you so much…:eek::D:evilgrin:

Hi, thank you so much for the sharing!

One question because i think i’m gonna use your script in my project, how would you proceed to add character’s (or any kind of object) movements? If you could just explain the main things you would do, i’d appreciate a lot.

I’ve tried, in your demo file, parenting the camera to Suzanne, adding a keybrd sensors to her as she can moves forward; but i was wondering how about make her turn left or right according to camera rotation…

May be, it could be interesting to make your current script be the “looking around mode” part of a script that would manage movement in a “default mode”.

Thanks for your answer Mobious, and thank for the link. It helps! :slight_smile:

Im trying to make it so when you hold rmb, it zooms in, and when you release rmb, it zooms out, do you know what i should do for that? your script is awesome btw :smiley:

Sure, you just need to make a couple simple changes.

Change lines 31 and 32 to this.

ZoomIn = bge.events.RIGHTMOUSE
ZoomOut = bge.events.RIGHTMOUSE

and replace lines 106-109 with this.

if keys[ZoomIn] != 0 and own['zoom'] >= MIN_DIST + ZOOM_STEP:
    own['zoom'] -= ZOOM_STEP
elif keys[ZoomOut] == 0 and own['zoom'] <= MAX_DIST - ZOOM_STEP:
    own['zoom'] += ZOOM_STEP

it a great work but why cant i use it when i append it on my game?

You have to tell the camera what object to follow by modifying the script.