Pharan написалThanks for sharing!
That's an odd solution. What's the logic behind it?
Sounds harmless enough to apply immediately to the official runtime.
Hey Pharan,
After some more digging in some non-spine-related area of our code, we found using interface actually crashes our game(which is what our solution is based upon). Although the exact reason is still unknown. We feel there's something else going on in Unity's xbox compiler so it's not necessarily a problem of AOT's. But the following changes in spine did get us further, or made our game crash a few hundred lines later.
In essence, the change is made to avoid the delegate structure inside an interface, by having three other classes implement a new interface. In details: (If you want the source changes, we can just send you the files that are changed.)
// in ISkeletonAnimation.cs
// event UpdateBonesDelegate UpdateLocal;
void addLocalCaller(ISkeletonAnimationCaller caller);
void removeLocalCaller(ISkeletonAnimationCaller caller);
// and the same goes for UpdateWorld and UpdateComplete
// in SkeletonAnimation.cs
// protected event UpdateBonesDelegate _UpdateLocal;
List<ISkeletonAnimationCaller> localCallerList;
public void addLocalCaller(ISkeletonAnimationCaller caller){
if (localCallerList == null)
localCallerList = new List<ISkeletonAnimationCaller> ();
localCallerList.Add (caller);
}
public void removeLocalCaller(ISkeletonAnimationCaller caller){
if (localCallerList == null)
return;
localCallerList.Remove (caller);
}
// the same goes for 'worldCallerList' and 'completeCallerList'
// in SkeletonAnimation.cs::Update() we commented some code and replace it with the following:
if (localCallerList != null)
for (int i = 0; i < localCallerList.Count; i++)
localCallerList [i].onUpdateLocal (this);
skeleton.UpdateWorldTransform();
if (worldCallerList != null) {
for (int i = 0; i < worldCallerList.Count; i++)
worldCallerList [i].onUpdateWorld (this);
skeleton.UpdateWorldTransform();
}
if (completeCallerList != null)
for (int i = 0; i < completeCallerList.Count; i++)
completeCallerList [i].onUpdateComplete (this);
// and the same treatment is done on SkeletonAnimator.cs
// we define a new interface ISkeletonAnimationCaller as following:
public interface ISkeletonAnimationCaller {
void onUpdateLocal(ISkeletonAnimation val);
void onUpdateWorld(ISkeletonAnimation val);
void onUpdateComplete(ISkeletonAnimation val);
}
// SkeletonRagdoll.cs, SkeletonRagdoll2D.cs and SkeletonUtility.cs implement such interface.
// add the following interface implementation methods in SkeletonRagdoll.cs and SkeletonRagdoll2D.cs
public void onUpdateWorld(ISkeletonAnimation val){
UpdateSpineSkeleton (val);
}
public void onUpdateComplete(ISkeletonAnimation val){
}
public void onUpdateLocal(ISkeletonAnimation val){
}
// add the following interface implementation methods in SkeletonUtility.cs
public void onUpdateLocal(ISkeletonAnimation val){
UpdateLocal (val);
}
public void onUpdateWorld(ISkeletonAnimation val){
UpdateWorld (val);
}
public void onUpdateComplete(ISkeletonAnimation val){
UpdateComplete (val);
}