Mouse look

Hi what is the preferred way to do a first person, mouse look.

Do I now use the mouse actuator instead of python, as shown in this video?

Just wondering because my original mouselook script doesn’t work in the newest version of blender.

Cheers,
Iamthwee

There a lot of ways to do MouseLook ! I’ve some mouse scripts that works fairly well with 2.76b. Personally I use the mouse actuator to do it now it’s as fast as any of the scripts I’ve got…

I like to treat all inputs the same, so if I’m making a small game and using logic bricks for input, I’ll use logic bricks for the mouse.
If I’m using a method to map keys to controls in python (eg a keymapper, complex GUI’s etc) then I’ll directly access the mouse.

Both ways exist, and both are useful. Pick one and see if it fits what you are doing with it.

Here is the script set-up I have used for a good-feeling mouse-look.

def get_window():
    return (render.getWindowWidth(), render.getWindowHeight())


def get_window_center():
    window = get_window()
    return (window[0]//2, window[1]//2)


def center_mouse():
    center = get_window_center()
    render.setMousePosition(center[0],center[1])



def look(cont):
    #mouse-look
    own = cont.owner
    m = cont.sensors['mouse_move']
    
    head = own.children['Head']
    
    sensitivity = own['mouse_sensitivity'] * 0.01
    smooth = own['mouse_smooth']
    
    if 'oldX' not in own:
        center = get_window_center()
        own['oldX'] = center[0]
        own['oldY'] = center[1]
    else:
        source = Vector(get_window_center())
        mpos = Vector(m.position)
        x = source.x - mpos.x
        y = source.y - mpos.y
        
        own['oldX'] = own['oldX'] * smooth + x * (1.0 - smooth)
        own['oldY'] = own['oldY'] * smooth + y * (1.0 - smooth)
        
        x = own['oldX'] * sensitivity
        y = own['oldY'] * sensitivity*(render.getWindowHeight() / render.getWindowWidth())
        
        own.applyRotation([0,0,x], False)
        head.applyRotation([y,0,0], True)


        ori = head.localOrientation.to_euler()
        if ori.x <= -0.6:
            ori.x = -0.6
        elif ori.x >= 0.6:
            ori.x = 0.6
        head.localOrientation = ori
        
        center_mouse()

Thanks to Mike Pan for the original code.

The script goes on your presumed FPS rigs ‘body’ (the ‘head’ being either a child object which has the camera childed to that, or the head could just be the camera).
To Set Up:
-Name your camera child ‘Head’
-Give the body (the object that’s running this script) the following properties as floats:
-‘mouse_sensitivity’
-‘mouse_smooth’

To make the script work, noodle its controller to a Mouse sensor set to Movement. The python controller should be on Module mode set to ‘mouse.look’, if you name this script mouse.py

Yeah I was considering using mike pan’s script, but my other mouse script didn’t seem to work on different platforms and seemed broken under newer versions.

I guess my question was isn’t the mouse look actuator more cross platform and reliable than a python mouse look script. Or could it be just that my mouse look script wasn’t great to begin with.

My guess would be that you were trying Mike’s original script as-is. Which, if I remember correctly, written for ancient Blender whose language has since been changed. Thus, I took the original script and ‘modernized’ it.
Seemed broken how? What does the debug console say? If you’re trying to do anything with scripts without a debugger, you are bound to find yourself with many head-aches :wink:

I’m not sure what is was but, on the same OS platform on a newer version of blender it failed to do anything. That’s why I thought at least using the logic bricks, would be more reliable.

Thanks, I’ll look into this.

deleted wrong thread

Hi what is the preferred way to do a first person, mouse look.

I prefer a joystick, you don’t need Mouselook script with a joystick. :slight_smile:

HG1 fixed Socials FPS in resources (quite a while ago) It works in 2.75. Check out the mouselook script (aim.py) Maybe it will give you some ideas. Haven’t tested it in 2.76 yet though.

peace
Mark

Try this one. This works in 2.76.2. I just combined mouse and keyboard in one script but I didn’t include the rotation cap and smoothing.I made this one because other scripts have too many extra complications/requirements/dependencies. This one needs only an Always sensor in pulse mode.


import bge
width = bge.render.getWindowWidth()
height = bge.render.getWindowHeight()
nWidth = (width // 2) / width
nHeight = (height // 2) / height
scene = bge.logic.getCurrentScene()
keyboard = bge.logic.keyboard
mouse = bge.logic.mouse
center = bge.render.getWindowWidth() / 2, bge.render.getWindowHeight() / 2

active = bge.logic.KX_INPUT_ACTIVE
activated = bge.logic.KX_INPUT_JUST_ACTIVATED

rmb = bge.events.RIGHTMOUSE
w = bge.events.WKEY
s = bge.events.SKEY
a = bge.events.AKEY
d = bge.events.DKEY
lsh = bge.events.LEFTSHIFTKEY
 
def main():
    cont = bge.logic.getCurrentController()
    obj = cont.owner
    rotscale = 0.8
    speed = 24
  
    x = mouse.position[0] - nWidth
    y = mouse.position[1] - nHeight   
    obj.applyRotation([0.0,0.0,-x*rotscale], 0)  
    obj.applyRotation([-y*rotscale,0.0,0.0], 1)    
    bge.render.setMousePosition(int(center[0]),int(center[1]))
    if keyboard.events[w] == active:
        obj.applyMovement([0,0,-speed], 1)
    if keyboard.events[s] == active:
        obj.applyMovement([0,0,speed], 1)
    if keyboard.events[a] == active:
        obj.applyMovement([-speed,0,0], 1)
    if keyboard.events[d] == active:
        obj.applyMovement([speed,0,0], 1)
            
    if (keyboard.events[lsh] == active
    and keyboard.events[w] == active):
        obj.applyMovement([0,0,-speed], 1) 

Attachments

input.zip (650 Bytes)

To input code, plase use code tags:

[ code]Code goes here[ /code]

(remove the space from after the [

Problem is, the capping code from Mike Pan mouselook script is doing some weird stuff when you rotate the camera quickly around Z.This code is also doing the same buggy stuff. Can anybody figure out why is not working properly the capping code or the rotation limiter ?


    orientation = mathutils.Matrix.to_euler(obj.localOrientation)
    
    if orientation.x > 1.9:
        orientation.x = 1.9
    elif orientation.x < 0.8:
        orientation.x = 0.8
    
    obj.localOrientation = mathutils.Euler.to_matrix(orientation) 

Thanks sdfgeoff for the code formatting idea. This code assumes that mathutils is already imported and that obj is the camera that’s calling the script. So it’s more like.



import bge,mathutils
width = bge.render.getWindowWidth()
height = bge.render.getWindowHeight()
nWidth = (width // 2) / width
nHeight = (height // 2) / height
scene = bge.logic.getCurrentScene()
keyboard = bge.logic.keyboard
mouse = bge.logic.mouse
center = bge.render.getWindowWidth() / 2, bge.render.getWindowHeight() / 2

active = bge.logic.KX_INPUT_ACTIVE
activated = bge.logic.KX_INPUT_JUST_ACTIVATED

rmb = bge.events.RIGHTMOUSE
w = bge.events.WKEY
s = bge.events.SKEY
a = bge.events.AKEY
d = bge.events.DKEY
lsh = bge.events.LEFTSHIFTKEY
 
 
 
def main():
    cont = bge.logic.getCurrentController()
    obj = cont.owner
    rotscale = 0.8
    speed = 24
  
    x = mouse.position[0] - nWidth
    y = mouse.position[1] - nHeight
    
    orientation = mathutils.Matrix.to_euler(obj.localOrientation)
    if orientation.x > 1.9:
        orientation.x = 1.9
    elif orientation.x < 0.8:
        orientation.x = 0.8  
    obj.localOrientation = mathutils.Euler.to_matrix(orientation)
         
    obj.applyRotation([0.0,0.0,-x*rotscale], 0)  
    obj.applyRotation([-y*rotscale,0.0,0.0], 1)    
    bge.render.setMousePosition(int(center[0]),int(center[1]))
    if keyboard.events[w] == active:
        obj.applyMovement([0,0,-speed], 1)
    if keyboard.events[s] == active:
        obj.applyMovement([0,0,speed], 1)
    if keyboard.events[a] == active:
        obj.applyMovement([-speed,0,0], 1)
    if keyboard.events[d] == active:
        obj.applyMovement([speed,0,0], 1)
            
    if (keyboard.events[lsh] == active
    and keyboard.events[w] == active):
        obj.applyMovement([0,0,-speed], 1)


There is some kind of interference between applyRotation and the orientation code.