Cam Rotation limit

Hey guys,

I have found a cool mouselook script in Martinsh’ flare playground, and it works perfectly as is, but I was wondering if anyone has a spare few minutes, if you could help me out to add a few extra lines, to limit the up/down rotation of the camera (rotation of the empty that the camera is parented to)

Script attached to this post.

#Blender Game Engine 2.55 Simple Camera Look#Created by Mike Pan:

# Use mouse to look around
# W,A,S,D key to walk around
# E and C key to ascend and decend

from bge import logic as G
from bge import render as R
from bge import events
from mathutils import *

scene = G.getCurrentScene()

yaw = scene.objects["Empty"]

speed = 0.08				# walk speed
sensitivity = 0.003		# mouse sensitivity
smooth = 0.75			# mouse smoothing (0.0 - 0.99)

cont = G.getCurrentController()
owner = cont.owner
Mouse = cont.sensors["Mouse"]

w = R.getWindowWidth()//2
h = R.getWindowHeight()//2
screen_center = (w, h)

# center mouse on first frame, create temp variables
if "oldX" not in owner:

	R.setMousePosition(w + 1, h + 1)
	owner["oldX"] = 0.0
	owner["oldY"] = 0.0

	scrc = Vector(screen_center)
	mpos = Vector(Mouse.position)
	x = scrc.x-mpos.x
	y = scrc.y-mpos.y

	# Smooth movement
	owner['oldX'] = (owner['oldX']*smooth + x*(1.0-smooth))
	owner['oldY'] = (owner['oldY']*smooth + y*(1.0-smooth))
	x = owner['oldX']* sensitivity
	y = owner['oldY']* sensitivity
	# set the values
	owner.applyRotation([0, 0, x], False)
	yaw.applyRotation([y, 0, 0], True)
	# Center mouse in game window
keyboard =


kbleft = events.DKEY # Replace these with others, if you wish
kbright = events.AKEY # An example would be 'events.WKEY, DKEY, SKEY, and AKEY
kbup = events.SKEY
kbdown = events.WKEY # 


if not 'moveinit' in owner:
    owner['moveinit'] = 1
    owner['mx'] = 0.0
    owner['my'] = 0.0
    # ~~SETTINGS~~ #
    # Tweak these settings to fit your needs
    owner['accel'] = 2.0      # Acceleration
    owner['maxspd'] = 3.5    # Top speed
    owner['friction'] = 0.75   # Friction percentage; set to 0.0 for immediate stop
    owner['movelocal'] = 1    # Move on local axis?
if keyboard[kbleft]:
    owner['mx'] += owner['accel']
elif keyboard[kbright]:
    owner['mx'] -= owner['accel']
    owner['mx'] *= owner['friction']
if keyboard[kbup]:
    owner['my'] += owner['accel']
elif keyboard[kbdown]:
    owner['my'] -= owner['accel']
    owner['my'] *= owner['friction']
# Clamping
if owner['mx'] > owner['maxspd']:
    owner['mx'] = owner['maxspd']
elif owner['mx'] < -owner['maxspd']:
    owner['mx'] = -owner['maxspd']
if owner['my'] > owner['maxspd']:
    owner['my'] = owner['maxspd']
elif owner['my'] < -owner['maxspd']:
    owner['my'] = -owner['maxspd']
# Actual movement
owner.setLinearVelocity([owner['my'], owner['mx'], owner.getLinearVelocity()[2]], owner['movelocal'])

Is there any chance someone could implement that for me into this existing one? :slight_smile:


In a separate script - by getting worldOrientation

basically, I want to tell the empty, that when it’s over a certain positive value with it’s rotation, and below a negative value, to stop rotating. In this case, up and down with it’s local X axis.

Thank you in advance, should anyone care to help me out :slight_smile:


Alright so I’m not the guy to ask for help on anything Martinsh made but I would suggest checking out the new mouselook sensor/actuator set up that is in Blender 2.72. It has the set up you’re talking about built in. There is a small bug with threshold but other than that it’s really simple.

maybe you can try this: give a rotation constraint to your empty, like so:

I’ll give you the steps to solve the problem:

Your empty has an orientation matrix that actually describes how the empty is currently rotated. If you find it’s world orientation you will always have its rotation relative to the world perspective.

In the BGE API, there are functions that can help you see the actual rotation in radians on your empty (in mathutils there’s a function that converts the orientation matrix into an euler vector form).

All you have to do is check whether the x rotation of the empty is going to be over pi/2 or less than -pi/2. If it is, set the x rotation to pi/2 or -pi/2 respectively.

Once you have your next rotation, convert it back into an orientation matrix, and set the empty’s rotation to the next rotation.

Good luck.

ok, here is ‘logic mouse’

it sets a property using python, that can then be evaluated using logic and or python.


MouseDemo3x.blend (471 KB)

As far as I know, in BGE, the only supported constraint from the Properties Editor –> Constraints Tab is the Rigid Body Joint.

most of them work for armatures,

ah ok, good to know

Hey guys, first off thanks to everybody who replied!

sunix - I’ve actually tried the “limit rotation” constraint, didn’t do anything. I think it only works for physics?

BluePrint and Lucrecious - You two just gave me a good idea, which led to the following attempt (sadly unsuccessful)…

So, I added a property (float) to the empty called “ONY” and attached a python script to it that always gets the orientation of the empty, and sets the value if the “ONY” property accordingly. Yaay. It returns values between 0 and 2. A bit confusing as I was expecting it to return negative values as well, but no big deal.

It’s also clamped (values between 0.9 - top, and 1.79 - bottom)

from bge import logiccont = logic.getCurrentController()
obj = cont.owner
rotation = obj.worldOrientation.to_euler()

obj['ONY'] = rotation.x

if rotation.x < 0.9:
    obj['ONY'] = 0.9
if rotation.x > 1.79:
    obj['ONY'] = 1.79

Anyways, then I was thinking, what if I just tell the “” script to only execute the rotation for the empty when the value of Empty[‘ONY’] is between 0.9 and 1.79. Would be logical, after all.

Then I did this (in the mouselook script)

if yaw['ONY'] >= 0.9 and yaw['ONY'] <= 1.79:
        yaw.applyRotation([y, 0, 0], True)

So, this works in terms that it does actually stop the rotation of the empty, but it stops moving for good. After the property “ONY” has reached 0.9, it stops and then whatever I do I can’t get the camera moving again, even though I did >= (larger or equal). Also, when “ONY” reaches 1.79, nothing happens. The camera’s rotating further. So I’m genuinely stuck with this…

Am I very far from the solution…?

Btw, thanks to everyone suggesting other “mouselook” scripts, but I’d much prefer to use this specific one. It has everything in it super nicely laid out including player movement and all. I just wanted to add this extra feature…

Honestly guys, thank you for being patient and helpful.

Maybe you need to return to normal.

îf rotation_x + new mouse input_x < max : rotation_x +=new mouse input_x

else :

you need to check the new input against the min/max rot