Godot Version
4.2.2
Question
Currently I’m trying to rotate a bone, which I get with skeleton.find_bone("Neck")
, smoothly based on a set of data I get externally.
My data is represented as X, Y and Z angles going from roughly -90 to +90.
So as an example if I have an arrow and the coords X = 0, Y = 45, Z = 0
, I’d expect it to point center up at a 45 degree angle. If I then change the Z to 90 I’d expect the arrow to still point at the same angle upwards, but now pointing towards the right. (I hope this makes sense)
So far the closest working code I found was:
var bone_pose:Transform3D = skeleton.global_transform * skeleton.get_bone_global_pose(neckBone)
bone_pose = bone_pose.looking_at(Vector3(0, 0, 0))
skeleton.set_bone_global_pose_override(neckBone, skeleton.global_transform.affine_inverse() * bone_pose, 1.0, true)
However this is neither smooth, nor am I able to find a good way to convert my angles to a Vector3.
Is there a way to do this in a simple and clean manner?
Edit: After thinking about it a little I thought of a little hack that could work, but I also don’t know how to pull it off. Basically instead of rotating the bone with the data directly I could rotate an object that is ankered to position of the bone and then have the bone face that object. Would that work and if so, how would that be pulled off smoothly? Is there some kind of trace / follow method for bones?
Edit 2: After trying it out I went with the option from my edit, which while being jank, still works well enough for what is essentially a V0.1. Here is how it looks for anyone interested:
@onready var skeleton: Skeleton3D = get_node("StoneModel/Armature/Skeleton3D")
@onready var neckBone = skeleton.find_bone("Neck")
@onready var lookPoint: Marker3D = get_node("LookPoint")
var cords = {"x": 0, "y": 0, "z": 0}
func _process(delta):
# Data is being served from a UDP server
var udpAnswer = udp.get_packet().get_string_from_utf8().split(",")
cords["x"] = int(udpAnswer[0])
cords["y"] = int(udpAnswer[1])
cords["z"] = int(udpAnswer[2])
lookPoint.position.y = -cords["x"]
lookPoint.position.x = -cords["z"]
var headRotation: Transform3D = skeleton.get_bone_global_pose_no_override(neckBone)
headRotation = headRotation.looking_at(lookPoint.global_transform.origin)
skeleton.set_bone_global_pose_override(neckBone, headRotation, 1.0, true)