class_name FpsOperatorHands extends Node3D var rig := ImportedOperator.new() func setup(variant: String) -> void: add_child(rig) rig.setup(variant, true) func animate(view_model: Node3D, fighter: Fighter, delta: float) -> void: var state := fighter.animation_state() # Camera/WeaponView already own bob, ADS, recoil and sprint offsets. Sample # only the imported upper-body actions and anchor their grip to that weapon. state.velocity = Vector3.ZERO state.grounded = true state.aim = true state.crouch = false state.slide = 0.0 state.pitch = 0.0 rig.animate_state(delta, state) transform = view_model.transform * rig.weapon_mount.transform.affine_inverse() var body := rig.skeleton.get_parent() as Node3D var to_skeleton := (transform * body.transform * rig.skeleton.transform).affine_inverse() var right_target := rig.pose.global_poses[rig.hand].origin rig.pose.move_shoulder("Right", to_skeleton * Vector3(0.20, -0.28, 0.16)) rig.pose.reach_arm("Right", right_target) var left_hand := rig.skeleton.find_bone("mixamorig_LeftHand") var left_target := rig.pose.global_poses[left_hand].origin if fighter.reload_left <= 0: left_target = to_skeleton * view_model.transform * ImportedOperator.support_point(fighter.weapon) rig.pose.move_shoulder("Left", to_skeleton * Vector3(-0.22, -0.28, 0.16)) rig.pose.reach_arm("Left", left_target)