Mouselook drift when not in fillscreen mode?

A very common problem with mouselook scripts is that the camera angle “drifts” (even when the mouse is still) in windowed mode. After investigating this, it seems like the problem is inherent to logic.mouse.position itself, because it likes to return slightly off-center values, even after you center the mouse cursor manually. Does anyone know of a way around this? I suppose you could add a small buffer zone where the mouse’s position can be slightly off-center, but it won’t effect the camera’s rotation. But is there a better way?

Statue.blend (862 KB)
I havent encountered any drifting with my set up. You can look at it if you want, I built it from the guides inside of the API.

Had this problem with a mouselook script I wrote awhile back.
I was doing something wrong.
Can’t remember what exactly… something like using an int when it should have been a float etc.
Give the code a good review and make sure nothing like that is happening.

Huh, well you’re doing two things different from me. You’re using bge.render.setMousePosition, whereas I’m using bge.logic.mouse.position, and you’re getting the width and height of the window to determine the central position, whereas I just use logic.mouse.position = (0.5,0.5). It seems like your way works much better. Thanks.

Edit: Okay, I’ve got it all figured out now. The reason your setup doesn’t drift has nothing to do with the things I mentioned above. It’s because your mouselook is triggered by a mouse sensor, so when the mouse isn’t moving, the sensor doesn’t activate, and camera movement stops.

No matter what method you use to center the mouse, sometimes the mouse won’t be perfectly centered, and when you retrieve the mouse’s position, you’ll get back a slightly off-center value. I think this happens when the screen has an even number of pixels in width or height, as no pixel falls exactly on the center of the screen, so BGE has to snap it to the nearest pixel value, causing errors.

So the two options to solve the drifting are:

  1. Use a mouse sensor to activate my mouselook script
  2. Attempt to correct the drift manually in my Python script
  1. should always be used to avoid unnecessary processing
  2. is mentioned above -> truncating parts of the system moue cursor location (e.g. when converting float to int)

You set mouse position with integer parameters. Each value represents a pixel. There are no fractions of pixels.
bge.render.setMousePosition(x, y)

The mouse sensor gives you the integer values:
KX_MouseSensor.position
You can use them directly. If the mouse wasn’t moved, the values do not differ from the set values above.

While the mouse module returns normalized floats:
bge.logic.mouse.position
If you have an even number of pixels in window size the normalized value of the mouse cursor position can never be exactly 0.5.
You have to translate them to pixel space first (integer values). Then you can see if the coordinate matches the coordinates set above.

Just wanted to say thanks. That was a very helpful explanation.

I’m gonna ask another little question. In every mouseLook script I’ve checked out, including the nice one that Redikann just posted, there’s an issue where, if you move the mouse too quickly, it gets “stuck” and stutters. It seems to be a problem that’s inherent to BGE’s mouse-checking, whether done through a sensor or through logic.mouse.position. Has anyone else noticed this problem? Or is it possibly an issue on my end, i.e. my mouse or drivers?