calebc01

I'm working on a project that involves dynamically altering the size of bones in a skeleton, while maintaining the animation sequences. My application also doesn't use slots and images - instead, it takes the bones and renders dynamically generated sprites to them. Because the Unity Runtime wasn't really designed to do that, I ended up writing my own parser that takes the JSON file and reconstructs the skeleton as a collection of Unity game objects - from there, it's fairly easy to change anything in my own scripts.

I was *going to go ahead and implement my own code to handle the animation as well, but I've realized that I need to use Spine's IK for some more complex animations. I think that re-implementing the IK is going to be a larger project than I want to tackle at this point.

The best thing for me to do would be to take the data in the Unity Runtime's skeleton object and modify it in-place, so that I don't have to re-implement the entire runtime. That's probably what I should have done in the first place. Is it possible to access and modify that data dynamically? Where is a good place to start? To attach my dynamically generated images, I can probably just turn them into actual images and attach them to the skeleton slots, so that I can use the runtime for that portion. But I still need to modify the skeleton data itself.

To be more specific, I'm referring to the "bones" section of the JSON file - I modify the length, x, y, and rotation data. The "animations" section remains unmodified. I don't want to modify the file itself, but the file stored in memory.

Thanks in advance!

-- 02 Jan 2016, 13:00 --

Here's a solution, and it works without even modifying the runtime! I dug into the Unity Runtime and found that there exists a list of BoneData objects called 'bones' in the SkeletonData class. There is a 'get' accessor method, so the data is accessible. And since it returns a reference to a list of BoneData objects, the data can be modified. Woot! The code below works.
public class SomeClass : MonoBehavior
{
private SkeletonAnimation skeleton;

void Start()
{
skeleton = GetComponent<SkeletonAnimation>();

Spine.ExposedList<Spine.BoneData> skeletonBones = skeleton.skeleton.data.Bones;

foreach(Spine.BoneData bone in skeletonBones)
{
// Change yon bones here, young squire!
}
}

}
The runtime code is very well-structured, so thanks for that.

-- 02 Jan 2016, 14:09 --

I've also figured out how to access the current bone states dynamically. I'm sure most people don't need this, but in my case, I want to draw on top of the bones dynamically. To do so, I need the bone states as they change throughout the animation. The following code can be used to do so:
public class SomeClass : MonoBehavior
{
private SkeletonAnimation skeleton;
private Spine.ExposedList<Spine.Bone> skeletonBones;

void Start()
{
skeleton = GetComponent<SkeletonAnimation>();

skeletonBones = skeleton.skeleton.Bones;
}

void LateUpdate()
{
foreach (Spine.Bone bone in skeletonBones)
{
// The state of the bone (translation, rotation, etc.) can be accessed here.
}
}
}
Cheers!
Avatar
calebc01
  • Postovi: 3

Pharan

Glad to hear you got it.
Spine is built on stateless (Data) and stateful (Skeleton) objects. Data stores the Setup Pose from Spine editor.

All animations and stateful data are always applied additively to the Setup pose which serves as the base.
So modifying the setup pose by modifying the bones in SkeletonData causes an offset effect for all transformations done manually or by animations.
But despite being against the "stateless" designation, Nate seems to have provided several samples of modifying skeleton data at runtime so it is recommended use, I guess.
The thing you probably want to do is store your original setup pose values if ever you need to return to it.

LateUpdate may not be a good option if you want to ensure execution order.
But SkeletonAnimation has callbacks for different stages of its animation and skeleton update.
Subscribe to the UpdateComplete event to get or perform operations post-animation-apply for that frame.
UpdateWorld and UpdateLocal are finer-grain points within the animation update process.

Having Unity pack the images, instead of having to rely on TK2D or Spine's external packer, is definitely something we want to support down the line if it provides enough conveniences. Not having to manually repack textures whenever you need to change something, or need third-party stuff for packing, is great.
Avatar
Pharan
  • Postovi: 5366


Natrag na Unity