Godot Version
4.6.1 stable (nixpkgs unstable)
Question
My game build (fps character controller) is functioning perfectly normally on binary builds, however on the web (zen browser, firefox based, tested via itch.io), the FPS camera behaves rather oddly. The mouse capture and release is handled through a proper _input callback, and functions fine, as far as i’m aware. however the input behavior itself results in any mouse movement making the character look up and spin clockwise, regardless of input direction, with small variations in behavior based on mouse input.
Pressing escape once to register the browser input capture escape results in expected camera behavior, but with a freed cursor, which means that it frequently escapes the game window and ceases to provide input. Another escape triggers the game to free the cursor as intended, and it no longer tracks movement, captured or otherwise. Clicking returns to upward spinning behavior.
Here is the rotation code:
# rot_input has been tested with both event.screen_relative and event.relative
func rotate_look(rot_input : Vector2):
look_rotation.x -= rot_input.y * look_speed
look_rotation.x = clamp(look_rotation.x, deg_to_rad(-85), deg_to_rad(85))
look_rotation.y -= rot_input.x * look_speed
if mouse_captured:
transform.basis = Basis()
rotate_y(look_rotation.y)
head.transform.basis = Basis()
head.rotate_x(look_rotation.x)
Do you ever reset the value of look_rotation back to zero? Currently this looks like it would build up speed inside the look_rotation variable, which is applied every time the function is called via rotate_y and head.rotate_x
1 Like
Hmm, I tested this, but it just resulted in locking the look direction in place, where any movement is briefly reflected, then quickly reset back to the locked direction, though this was just testing it in engine, and not on the web.
The current system does work perfectly fine in engine, and on binary builds; the web export is where we get odd behavior. I think the potential of compounding input does make sense in terms of what’s happening on the web build, but I guess I just don’t get why the binary builds read mouse input perfectly fine but the web build does not.
I just ran some logging on the raw rot_input that the look_rotation derives from. It’s significantly more negative, (almost entirely so) on the web than locally. Will keep digging.
It’s probably worth simplifying your code if you aren’t using look_rotation for anything else you can edit the rotation values directly
func rotate_look(rot_input : Vector2):
rotation.y -= rot_input.x * look_speed
head.rotation.x -= rot_input.x * look_speed
const MAX_TILT = deg_to_rad(85)
head.rotation.x = clampf(head.rotation.x, -MAX_TILT, MAX_TILT)
Though I don’t know how you are calling rotate_look, or if you do use look_rotation elsewhere
This is definitely cleaner, and works great locally with the second rot_input flipped to y, however the odd behavior on web still persists due to the rot_input values still being far too negative as compared to local.
rotate_look is called from _unhandled_input like so:
if mouse_captured and event is InputEventMouseMotion:
rotate_look(event.screen_relative)
and look_rotation is not used anywhere else.
Ah maybe the Web build cannot accurately assess the screen size for screen_relative? Does .relative work any better? Are you on a high DPI screen?
From testing .relative and .screen_relative, both perform pretty much identically and reproduce the bug.
I’m on a Framework 16 laptop: 2560x1600, 16 inch display.
I’ve been trying to dig around the project settings to see if there are any related settings here, but I’ve got noting yet.