Hey. I’m having trouble with my player’s y rotation wrapping around 180. More specifically, I’m trying to make it so my player’s rotation gets clamped to a range of -30 and +30 degrees when they’re climbing. Most angles work fine, but as soon as the player’s rotation is about to go over 180, everything breaks. See attached video:
As you can see, trying to climb behind the cube makes the clamp totally break. Here’s my code:
if _mouse_input:
if _is_climbing or _is_leaning:
# only rotate left and right in clamped range
rotate_y(deg_to_rad(-event.relative.x * MOUSE_SENSITIVITY))
rotation_degrees.y = clampf(rotation_degrees.y, current_rotation - 30.0, current_rotation + 30.0)
else:
NECK.rotate_x((deg_to_rad(-event.relative.y * MOUSE_SENSITIVITY))) # rotate up and down
NECK.rotation.x = clamp(NECK.rotation.x, -TILT_LIMIT, TILT_LIMIT)
rotate_y(deg_to_rad(-event.relative.x * MOUSE_SENSITIVITY))
I set current_rotation both in the climb and lean functions as just current_rotation = rotation_degrees.y to get the relative rotation for when I need it. Best thing I could think of as of now…
Try accumulating the rotation separately from rotate_y() and clamping that rather than the applied rotation. For example:
extends Node3D
@export var MOUSE_SENSITIVITY = 0.05
@export var _is_climbing = false:
set(v):
_is_climbing = v
_yaw_cur = _yaw
var _yaw = 0.0
var _yaw_cur = 0.0
func _input(event: InputEvent) -> void:
if event is not InputEventMouseMotion:
return
_yaw -= event.relative.x * MOUSE_SENSITIVITY
if _is_climbing:
# only rotate left and right in clamped range
var m = _yaw_cur - deg_to_rad(30.0)
var M = _yaw_cur + deg_to_rad(30.0)
_yaw = clampf(_yaw, m, M)
else:
# do neck rotation
pass
# Construct basis from rotation
transform.basis = Basis()
rotate_object_local(Vector3(0, 1, 0), _yaw)
Note: MOUSE_SENSITIVITY here would have to be modified.