I did the following:
// Dislike this being global and static, but I couldn't think of an easier way to do it
public static Dictionary<GameObject, Dictionary<string, Vector3>> SavedBones = new Dictionary<GameObject, Dictionary<string, Vector3>>();
public static Vector3 GetBonePosition(SkeletonAnimation skel, string BoneName)
{
Vector3 pos = Vector3.zero;
var bone = skel.skeleton.FindBone(BoneName);
if (bone != null)
{
pos = skel.transform.TransformPoint(bone.WorldX, bone.WorldY, 0f);
}
return pos;
}
public static Vector3 SaveBonePosition(GameObject g, SkeletonAnimation skel, string BoneName)
{
Vector3 pos = Vector3.zero;
var bone = skel.skeleton.FindBone(BoneName);
if (bone != null)
{
pos = skel.transform.TransformPoint(bone.WorldX, bone.WorldY, 0f);
if (SavedBones.ContainsKey(g) == false)
SavedBones[g] = new Dictionary<string, Vector3>();
SavedBones[g][BoneName] = pos;
}
return pos;
}
public static Vector3 GetSavedBoneDelta(GameObject g, SkeletonAnimation skel, string BoneName)
{
Vector3 delta = Vector3.zero;
Dictionary<string, Vector3> SavedBonePosList = null;
if (SavedBones.TryGetValue(g, out SavedBonePosList))
{
Vector3 oldPos;
if (SavedBonePosList.TryGetValue(BoneName, out oldPos))
{
var bone = skel.skeleton.FindBone(BoneName);
if (bone != null)
{
Vector3 newPos = skel.transform.TransformPoint(bone.WorldX, bone.WorldY, 0f);
delta = newPos - oldPos;
}
}
}
return delta;
}
Then inside the object:
void Update()
{
var delta = StaticSpineHelper.GetSavedBoneDelta(this.gameObject, Body, "BoneName");
Debug.LogFormat("The delta is: {0}", delta);
transform.position = transform.position - delta;
}
void LateUpdate()
{
StaticSpineHelper.SaveBonePosition(this.gameObject, Body, "BoneName");
}
And used this to reposition the root object. This version causes the object to move around a bone. You will need to tweak this slightly.