I’m making an open source 3d fps game, and replacing a capsule with a 3d model, the problem I’m having is I can’t find a reliable way to keep the bone from rotating in the x axis too far. repo
Code
func _input(event):
if event is InputEventMouseMotion:
rotate_y(deg_to_rad(-event.relative.x * mouse_sensitivity))
# Get the current pose of the bone
var bonePose = skel.get_bone_global_pose(17)
# Save the original position
var original_position = bonePose.origin
# Define the rotation axis as the X axis
var axis = Vector3(1, 0, 0)
# Define the rotation angle based on relative.x
angle = event.relative.y * mouse_sensitivity * VERTICAL_sensitivity
#angle = clamp(angle, deg_to_rad(-0.671), deg_to_rad(0.265)) # this dose not work
# Apply the rotation to the pose
bonePose = bonePose.rotated(axis, angle)
# Reset the position to the original one
bonePose.origin = original_position
# Set the new pose of the bone
skel.set_bone_global_pose_override(17, bonePose, 1.0, true)
The issue seems to be that you’re clamping the input but not the result. So it’s clamping how far it can move in a single frame, but not overall.
Instead, I’d suggest using an accumulator (just a float you add to or subtract from when you move the mouse), clamping the accumulator, and then using that to lerp between the two angles you want.
I don’t quite get how to use your code but I did figure it out.
here’s what I ended up with
func _input(event):
if event is InputEventMouseMotion:
rotate_y(deg_to_rad(-event.relative.x * mouse_sensitivity))
# Get the current pose of the bone
var bonePose = skel.get_bone_global_pose(17)
# Save the original position
var original_position = bonePose.origin
# Define the rotation axis as the X axis
var axis = Vector3(1, 0, 0)
# Define the rotation angle based on relative.x
angle = event.relative.y * mouse_sensitivity * VERTICAL_sensitivity
# Apply the rotation to the pose
bonePose = bonePose.rotated(axis, angle)
# Changes the basis to a euler
var bonePosEuler = bonePose.basis.get_euler()
# Clamps that euler
bonePosEuler.x = clamp(bonePosEuler.x,-0.671,0.265)
# Turns the euler into a bias
bonePose.basis = Basis().from_euler(bonePosEuler)
# Reset the position to the original one
bonePose.origin = original_position
# Set the new pose of the bone
skel.set_bone_global_pose_override(17, bonePose, 1.0, true)