@tool class_name TrackingBone3D_head extends SkeletonModifier3D @export_enum(" ") var bone: String @export var target: Vector3 = Vector3(0, 0, 0) func _validate_property(property: Dictionary) -> void: if property.name == "bone": var skeleton: Skeleton3D = get_skeleton() if skeleton: property.hint = PROPERTY_HINT_ENUM property.hint_string = skeleton.get_concatenated_bone_names() func _process_modification() -> void: var skeleton: Skeleton3D = get_skeleton() if !skeleton: return # Never happen, but for the safety. var bone_idx: int = skeleton.find_bone(bone) var _parent_idx: int = skeleton.get_bone_parent(bone_idx) var pose: Transform3D = skeleton.global_transform * skeleton.get_bone_global_pose(bone_idx) #var looked_at: Transform3D = _w_look_at(pose, target) var looked_at: Transform3D = pose.looking_at(target, Vector3.UP) var axis: Vector3 = looked_at.basis.y looked_at = looked_at.rotated(axis, PI) skeleton.set_bone_global_pose( bone_idx, Transform3D( (skeleton.global_transform.affine_inverse() * looked_at).basis.orthonormalized(), skeleton.get_bone_global_pose(bone_idx).origin ) )