Simple mouselook module script

I am not sure if this is any use for anyone, but I have worked on this simplified script to use on my projects.
My goal was to make a mouselook with simple capping with as little codelines as possible, so here it is.

Any suggestions for even more simplifications are welcome. Any suggestions that would make the code larger I will simply ignore (I know features can be expanded on project-basis, that wasn’t my goal here).

Capping simply uses camera’s local orientation axises to check if capping is False or True.

Only real failure for now is that the cap doesn’t prevent from looking further than the capping axis if you move mouse enough fast, but it prevents further rotation.

All you need is mouse sensor with movement mode on and attach this in module mode onto a python controller.

[EDIT] Script updated 1.5.2014

  • Drifting should be fixed now.
  • Script should be now even easier to set up and understand

    It seems that with certain resolutions, setting cursor position to 0.5 with bge.mouse.position
    causes drifting since the cursor position cannot reach exact center position. So there’ll always
    be some other values than zero for mouse. Same happens with getWindowWidth() and getWindowHeight() if you don’t floor-divide the value by two (//2).

    #Get the Mouse: Movement - sensor
    m = cont.sensors['Mouse_move']

    #Trigger mouselook only if Mouse sensor is positive (if mouse is being moved)
    if m.positive:
        #Calculate the center pixel position of the window
        center = [bge.render.getWindowWidth()//2, bge.render.getWindowHeight()//2]

        #Calculate the mouse move value and reduce it to make it more manageable as rotation value
        mpos = [-(m.position[0]-center[0]), -(m.position[1]-center[1])]
        mpos = [mpos[0]*0.001, mpos[1]*0.001]
        
        #Calculate mouselook cap based on camera's orientation
        #(Camera is parented to the player hitbox)
        cap = cam.localOrientation[1][2] > -0.1

        #Calculate Camera's orientation compared to horizon
        up = -(cam.localOrientation[2][2]) > 0.0
        down = -(cam.localOrientation[2][2]) < 0.0

        #If cap is True, then stop rotating view further
        if cap:
            if up and mpos[1] < 0.0:
                pass
            elif down and mpos[1] > 0.0:
                pass
            else:
                mpos[1] = 0.0

        #Apply the rotation to player (mouse X to player Z) and
        # camera (mouse Y to camera X)
        obj.applyRotation((0, 0, mpos[0]), False)
        cam.applyRotation((mpos[1], 0, 0), True)

        #Set the mouse cursor position back to center
        bge.render.setMousePosition(center[0], center[1])

Thanks! i ws looking for a simple cap system, but your script have the “mouse drifting”, this is a version modified that fix the problem:

import bge

def mouse_look(cont):
    camera = cont.owner
    
    x = bge.render.getWindowWidth()//2/bge.render.getWindowWidth()-bge.logic.mouse.position[0]
    y = bge.render.getWindowHeight()//2/bge.render.getWindowHeight()-bge.logic.mouse.position[1]
        
    #Mouse Y cap
    cap = camera.localOrientation[1][2] > -0.1
    up = -(camera.localOrientation[2][2]) > 0.0
    down = -(camera.localOrientation[2][2]) < 0.0
        
    if cap:
        if up and y < 0.0:
            pass
        elif down and y > 0.0:
            pass
        else:
            y = 0.0
        
    camera.applyRotation((0,0,x), False)
    camera.applyRotation((y,0,0), True)
        
    bge.logic.mouse.position = (0.5,0.5)

I know. Drifting is due to the fact that for some reason sensor is positive even though it is not. Sounds like a bug, but no idea really what is the cause for this. To fix this I used a margin to avoid drifting


def mouse_look(cont):
    obj = cont.owner
    cam = obj.children[0]
    sensor_m = cont.sensors['Mouse']

    #If mouse is being moved, trigger mouselook
    if sensor_m.positive:
        mx, my = 0, 0
        mx = -(mouse.position[0]-0.5)
        
        obj.applyRotation((0,0,mx), False)
        
        #Mouse Y cap
        cap = cam.localOrientation[1][2] > -0.1
        up = -(cam.localOrientation[2][2]) > 0.0
        down = -(cam.localOrientation[2][2]) < 0.0

        my = -(mouse.position[1]-0.5)
        
        if cap:
            if up and my < 0.0:
                pass
            elif down and my > 0.0:
                pass
            else:
                my = 0.0

        #Drift-fix (You can fizzle with the margin value)
        if mx < 0.001:
            mx = 0.0

        if my < 0.001:
            my = 0.0
        

        cam.applyRotation((my,0,0), True)
        
        mouse.position = (0.50,0.50)