• Runtimes
  • C# Binary Reader/More Unity Support

Hey Guys,I'm new to this forum and/but I want a little help and I wanted hear some opinions on something from the community. I'm working on 2 things, One is a binary reader to read the binary files spine can export, I mostly wanted to talk about that. Then I also want to hear opinions to find if anyone is interested in what I'm working on for unity.

Which is basically a skeletle animation support that has each limb or bone a GameObject in unity, Kinda like how if you imported a 3D model with separate parts in it. Its usefulness is very helpful because you can attach skeletons to a bone or scripts or attach hotboxes to each limb! I was wondering if you guys would be okay with that in the regular unity runtime? I'm already done with it and I just have a little cleanup to do to feel comfortable sharing it.

Now the C# binary reader... I want to make it available to everyone because the file size will drastically reduce a games overall size and that it is faster to read/load. I was able to decipher java's decrepit encoding system they call MUTF-8, only halfway.... I can read String, Integers, regular bytes, and some bools.... But no floats, So I need help with that.

using System;
using System.IO;
using System.Collections.Generic;
using System.Resources;

namespace SpineBinary
{

public class SkeletonJson
{
	public SkeletonJson(string Location)
	{
		FileStream SourceStream = File.Open (Location, FileMode.Open);
		MiscUtil.IO.EndianBinaryReader reader = new MiscUtil.IO.EndianBinaryReader (MiscUtil.Conversion.EndianBitConverter.Big,SourceStream);
		Console.WriteLine("Bones Amount:"+(reader.Read ()-1));
		Console.Write ("Bone Name:" + (reader.ReadString ()));
		Console.Write (" ParentIndex:"+(reader.ReadInt32()));
		Console.Write (" X:"+(reader.ReadSingle() * 1));//Scale is 1 by default
		Console.Write (" Y:"+(reader.ReadSingle() * 1));//Scale is 1 by default
		Console.Write (" W:"+(reader.ReadSingle()));
		Console.Write (" H:"+(reader.ReadSingle()));
		Console.ReadLine ();
	}
}

public class MainClass
{
	
	public static void Main (string[] args)
	{
		SkeletonJson Test = new SkeletonJson ("skeleton.skel");
	}
}
}

What it feeds out:

Bones Amount:3
Bone Name:root ParentIndex:0 X:0 Y:1 W:1 H:0

Some data is being misplaced here or the reader is reading off all of x as one value and letting Y take W's value(BAD!).

Its supposed to be:

Bones Amount:3
Bone Name:root ParentIndex:0 X:0 Y:0 W:1 H:1

This is just a snippet and you guys need John Skeets MiscUtils Library(just the EndianBinaryReader and maybe his streamer). My plan was to adapt his progress and see if I can make it be a java binary file reader(as in it reads java binary files not it being a java binary reader... its not) for Spine's really nice C# runtime.

But if the spine developers(Nate) could actually export spines binary files in something like BSON or UTF-8 or ASCII... Something that isn't Java's home-made contraption. This would be a none issue and we might get somewhere sooner with this.

Some feed back will be a great help to the spine runtime. So you guys could perhaps get Binary Files read on C# and maybe other languages.

Related Discussions
...

You can ignore MUTF-8 and treat it as UTF-8. Spine's UI doesn't allow Unicode input anyway. Nothing in the binary format is specifically about Java.

Can't you use BinaryReader in C#? It looks like it is the C# equivalent of Java's DataInputStream, which is what spine-libgdx's SkeletonBinary uses.

I haven't written documentation for the binary format or SkeletonBinary for all the runtimes yet because the format is not yet stable (needs meshes, FFD, skinning) and also JSON is pretty ok most of the time.

A GameObject per attachment has advantages (eg attaching colliders), but I expect it will perform worse than spine-unity. Also it may be tricky to have attachments hidden and shown. As for it being in the official runtime, I'm not sure. I guess it depends on its complexity. No promises, but if it has all the features needed, is not a lot of code, and you would like to contribute it then I may take on the responsibility of maintaining it in the official runtime. If not we can still link if from the 3rd party section of the runtimes page.

I was fiddling with something similar to your GameObject per bone idea while looking into physics integration. Was just wondering how you have decided to render the skeleton in this setup. Are you creating separate quad meshes and MeshRenderers/MeshFilters for each of the GameObjects and relying on dynamic batching to reduce the draw calls, or are you skinning all GameObjects under a Skinned Mesh Renderer after assigning bones to updated GameObject positions while having those bones influence the various quads? If so, how have you solved Z sorting between the different submeshes on different GameObjects forming the skinned mesh, or on the seperate quads implementation mentioned first.

Or have you simply created an API for exposing the bones as GameObjects so you can attach things to them (rendering duties still left to the existing rendering code written by Nate). If it is the latter, and it is robust and minimal overhead when disabled for those that don't want (single bool to check to enable and look to update GameObjects per frame), I would vote for integration, as quite a few people seem to have rolled their own solutions desiring this functionality. While trying to do the Physics stuff I tried to think about some edge cases that you may also want to consider. Mainly, I believe you should not destroy GameObjects that have been created by the system to match bones. If a bone no longer exists due to them being renamed or removed from an animation when a new .json version is imported you do not want the user to lose the scripts they have attached to the now defunct GameObject. If a rename occurred for example, then you should simply disable the GameObject and Log a warning stating that the bone no longer exists in the animation, maybe asking if you should recycle the GameObject for a different (new) bone (just update GameObject to have new name). Worst case, you create the new GameObject for the renamed bone and allow the user to manually copy across their scripts/components with all variables intact before they delete it manually forever. Then it is on the user not to lose their scripts. You can see that the main issue with such a system is that you have to take care not to destroy scripts or attachments that people have set and all the public variables or configuration they may have populated through the inspector. Also, for attaching colliders take a look at the Physics integration I started just in case it may be of some help to you. It takes care of creating/updating Bounding box colliders and disabling/enabling on required frames. It also at least allows you to override if a collider should be displayed or if you want to put you own custom one on there too (box collider).
If you have all of the above checked off then this will be pretty useful to a lot of people.
Link.

Regards,

Rob

//Nate

Can't you use BinaryReader in C#? It looks like it is the C# equivalent of Java's DataInputStream, which is what spine-libgdx's SkeletonBinary uses.

Well I did use C# BinaryReader in the beggining but it has some issues because the way Java handles UTF-8 Strings & Primitives, On that documentation it shows whats different. I'm still going to figure this out even if it will just be changed when you add meshes. I'm personally curios and I really want to figure this out for the sake of added knowledge I might receive from figuring it out.

I haven't written documentation for the binary format or SkeletonBinary for all the runtimes yet because the format is not yet stable (needs meshes, FFD, skinning) and also JSON is pretty ok most of the time.

Then could you think about Bson?, Works kinda like json except it exports in a Binary format and is traversable from different platforms.... MongoDB & Jackson have a function(s) to convert Json to Bson.... Except MongoDB & Jackson are very large. So I would use a smaller implementation or make a function on the Json reader to except a Bson File and just convert it there... Where ever there is(C#,C++,Java,etc).

A GameObject per attachment has advantages (eg attaching colliders), but I expect it will perform worse than spine-unity. Also it may be tricky to have attachments hidden and shown. As for it being in the official runtime, I'm not sure. I guess it depends on its complexity. No promises, but if it has all the features needed, is not a lot of code, and you would like to contribute it then I may take on the responsibility of maintaining it in the official runtime. If not we can still link if from the 3rd party section of the runtimes page.

I actually wrote a piggy-back class/Component for Spine.Bone and it is used by a special SkeletonComponent so people can choose not to use it.... Its still drawn under one mesh Comp(The base SkeletonComponent) though... For performance I could attach points to the bone object. When the new skeleton Component runs it will create bone Components and a Gameobject for each bone and attach the bone to the Component. The bone Component then updates itself to the spot where the bone is. I'm going to write facilities to change the scale,Position and even rotation via the bone Component eventually(Half implemented)... Working out how to do the rest might be a confusing effort. Maybe move the mesh points for the bone? and not the bone itself... So the user can flop from animated to not animated via bone comp.

//ProudLittlePinwheel

Mainly, I believe you should not destroy GameObjects that have been created by the system to match bones.

Solved that bit... Made a button and it will make a BoneComp for each bone, If an existing bone is changed via the animation file, the bones with same names are modified(but not replaced) and new bones comps are made/added if different.

Also, for attaching colliders take a look at the Physics integration I started just in case it may be of some help to you. It takes care of creating/updating Bounding box colliders and disabling/enabling on required frames.

Shouldn't be too hard... Might make a spine poly collider, and spine joint so users can make pretty nasty contraptions.

Thanks for the input, Rob!

CoryGold a écrit

//Nate
Well I did use C# BinaryReader in the beggining but it has some issues because the way Java handles UTF-8 Strings & Primitives, On that documentation it shows whats different. I'm still going to figure this out even if it will just be changed when you add meshes. I'm personally curios and I really want to figure this out for the sake of added knowledge I might receive from figuring it out.

Fair enough. 🙂 You can treat MUTF-8 as UTF-8, no need to do anything special. Eg:
http://stackoverflow.com/a/1393579
BinaryReader should be able to read strings and primitives, though I admit I've never tried it. 8) Wait, I forgot I implement my own string format which optimizes for ASCII. No wonder BinaryReader couldn't read it! Sorry. You'll need to implement the readInt and readString methods here:
https://github.com/libgdx/libgdx/blob/m ... Input.java
BinaryReader should handle the rest.

Then could you think about Bson?

BSON makes parsing easier, but loses a lot of the benefit of a binary format. It would still write names for the values. Eg, JSON would be "{name:value}" and BSON would be roughly "{Si4nameSi5value}". The SkeletonBinary format writes only the minimal amount of data and in a known order, so is most efficient but slightly harder to parse.

When the new skeleton Component runs it will create bone Components and a Gameobject for each bone and attach the bone to the Component. The bone Component then updates itself to the spot where the bone is.

This is an interesting way to do it. To be clear, you would create a GameObject for each bone, allowing the user to easily attach things to a bone? Probably would be good to only create GameObject for bones that the user cares about. Actually, instead of creating GameObjects automatically, maybe it would make most sense to make a "BoneComponent" that is wired up to a SkeletonComponent and lets the user pick a bone. The BoneComponent can be attached to any GameObject and will adjust its transform to match the skeleton bone.

Nate, I think you hit the nail on the head with that final implementation idea. Would be very easy for users to configure bones and attachments that way, perhaps through a drop down list of the bones in a skeleton shown in an editor script on the new bone component. I feel like it would be very flexible too, you could in theory change which bone a GameObject/BoneComponent is following/snapping to at runtime if you really wanted to! You could also have user configurable information within the BoneComponent to state whether it should draw Bounding Boxes if they are a child attachment, house a custom collider, whether these colliders are disabled via the animation at the right frames, or whether to override this behaviour entirely. Sounds very cool.

CoryGold a écrit

I actually wrote a piggy-back class/Component for Spine.Bone and it is used by a special SkeletonComponent so people can choose not to use it.... Its still drawn under one mesh Comp(The base SkeletonComponent) though... For performance I could attach points to the bone object. When the new skeleton Component runs it will create bone Components and a Gameobject for each bone and attach the bone to the Component. The bone Component then updates itself to the spot where the bone is. I'm going to write facilities to change the scale,Position and even rotation via the bone Component eventually(Half implemented)... Working out how to do the rest might be a confusing effort. Maybe move the mesh points for the bone? and not the bone itself... So the user can flop from animated to not animated via bone comp.

Is the above have the same functionality as Nate described? I'm not following some parts, like here

For performance I could attach points to the bone object.

I'm not sure what you mean by points? And is the bone object you are referring to the GameObject, or is it a Unity bone? If it uses a Unity bone, would it not just be easier to update the transform of the GameObject rather that the Bone component? Or is this more overhead? Or am I getting completely confused... :bang:

Anyway, looking forward to this, I think it could be really flexible and super useful! Thanks CoryGold for all your efforts 🙂

Regards

Rob

Wait, I forgot I implement my own string format which optimizes for ASCII. No wonder BinaryReader couldn't read it! Sorry. You'll need to implement the readInt and readString methods

You know I looked at the Libgdx docs... But it never really accord to me that it could be the main reason I couldn't get it to work. Thanks man.

For performance I could attach points to the bone object.

Mesh points... Because I want like one draw call from the skeleton component.
So when you adjust the bone(With animation off)... You may move, rotate and scale without spine overriding it. And the bone object will set the (mesh)points according to its location, rotate & scale.

Sorry for the confusion there.... I have a slight issue getting the words across on a equal meaning.

perhaps through a drop down list of the bones in a skeleton shown

I can work on that... Shouldn't be too hard.

Anyway, looking forward to this, I think it could be really flexible and super useful! Thanks CoryGold for all your efforts

No problem, I'm making it for my future/current games so I kinda need it. You guys really helped me out with this feedback. I will pop it over to github as soon as I apply this feedback.

Quick note here... I thought of a way I can handle 2D collision boxes... If you have a 2D poly collider and you have a bone component under the same object, if the check box for Bounding boxes to poly2D is on, It will set the points to the poly collider.

Aha! I think I follow now, thanks for the explanation. So to be sure though, what you have created can actually affect the skeleton being rendered. If I update the skeleton which updates my BoneComponent, then move my BoneComponent, it will move vertices associated with that bone. What about other bones that are children of that bone, will they be affected too, or only if you have further BoneComponent created which point to those bones? I'm guessing if you force all bones to be built you would have ended up with a nice hierarchy of parent and child bones as parent and child GameObjects. What about now that you can specify some bones and not others? How will the hierarchy be organised, if at all (BoneComponents could now potentially sit happily outside of the skeleton GameObject, you could even do something seriously stoopid, like make the skeleton a child of one of its own bones).

Also, does all this require using Skinned Mesh Renderers in order to work, as this will break dynamic batching between multiple skeletons using the same atlas, which may be a consideration for some people who have managed to batch multiple enemies, etc on screen, by not using multiple materials. If so could there be a system to batch multiple skinned meshes that share the same material and still preserve all of their individual functionality/animations? I'm just wondering how you reference to the mesh vertices you wanted to alter or if you assigned bones with weights in order to do the movement.

Was actually thinking of writing an implementation of SkeletonComponent that uses Skinned Mesh Renderers and Unity bones in order to perform the animation. But then FFD is coming in (which would be compatible) but Skinning I believe would to be almost like an FFD override (meaning you would still have alter mesh vertices each frame) rendering it kinda pointless. Doubt there is much in the performance differences though?

Again looking forward to having a hands on play so I can make further evaluations/suggestions. Rob 😃

I'm not sure about the BoneComponent driving the skeleton, but it might be interesting. To start I think it is best to keep it simple, a BoneComponent that adjusts the GameObject it is attached to using a bone from a skeleton. Task:
https://trello.com/c/RWIT6WQd/59-boneco ... spine-tk2d

Image!

Hey guys,
Just dropping in for a progress update... Kinda proof really.
I made a tool to make bone components and I settled on something that pretty much doesn't take much memory and is fine for efficiency. If you have a game object with the same name as a bone... It uses it... As long as it has a bone component... Cuts down on clutter too! I did this because there is a really annoying glitch were when you hit play it looses what bone it was attached to(something tells me thats supposed to happen). I guess a new skeleton is made on play or I can't retain values on execution, either way. This works out and does as advertised. Now I need to work on manipulation... Unless you guys are fine with not being able to mess with the "Transforms" and letting the skeleton manipulating it?

Also if you want a bone component destroyed... Destroy the game object its attached to.
The bone component doesn't touch the skeleton and the skeleton doesn't keep track of it except on launch were it attaches a bone to the Bone Component.

Let me know what you guys think... I still have some work to do on it.(Physics,Sub Meshes Manipulation and optimizations)

//LittlePinWheel

What about other bones that are children of that bone

Might do a hierarchy and check if a bone is parented then make components for those too and let unity manage the transforms and the offsets.

Also, does all this require using Skinned Mesh Renderers in order to work, as this will break dynamic batching between multiple skeletons using the same atlas, which may be a consideration for some people who have managed to batch multiple enemies, etc on screen, by not using multiple materials. If so could there be a system to batch multiple skinned meshes that share the same material and still preserve all of their individual functionality/animations? I'm just wondering how you reference to the mesh vertices you wanted to alter or if you assigned bones with weights in order to do the movement.

I'm not changing anything on the rendering system yet... When I will, I will be moving the Sub mesh's for bones components to manipulate.... Which I'm still working on. And if you are wondering how I will reference the points or do weights... Still working on that. But the bone has a matrix and the base skeleton component has some code I might find useful to get what I need for the manipulation.
I'm going to have to play with it.

If that doesn't work I'm going to "Steal" the submesh and make it a mesh on the Bone Component's game object and rewrite the SkeletonComponent.... But thats last resort... As I imagine is inefficient(More draw calls) and like diving into a hornets nest.... Also many toes will be stepped on if I submit it to Github. 😛

//Nate

Kinda flattered that my forum post made it on the development trello board. 😛

Looks cool!

You probably want to store the bone name in the BoneComponent and then look up the bone as needed, caching if possible. You'll have to handle if the skeleton is recreated, which is probably why you lose your selection when you press play.

TBH, probably the only thing I'd merge, at least at first, is a BoneComponent that is created manually, has a way to choose a SkeletonComponent and a bone, and updates its transform to match the bone. This is the simplest thing possible and we can build on the complexity from there.

You probably want to store the bone name in the BoneComponent and then look up the bone as needed, caching if possible. You'll have to handle if the skeleton is recreated, which is probably why you lose your selection when you press play.

Your probably right on that bit. I will make the Bone Component more like that and remove the modified SkeletonAnimationComponent. Because that would cut down on the confusion. Anyway we can document the instructions so the user knows how to use it? Or make one? Leave a little commented instruction inside the bone component? Maybe add a bone component on the example scene? Both?

I will try to make it really hard to mess this up on the user side of things.

TBH, probably the only thing I'd merge, at least at first, is a BoneComponent that is created manually, has a way to choose a SkeletonComponent and a bone, and updates its transform to match the bone. This is the simplest thing possible and we can build on the complexity from there.

Thats what it is right now... I will a make the slight modifications mentioned above and pass it over on github!

I was able to read everything in the Spine binary file until I got to Meshes... I read how many points are in the array but it feeds me just 1! So it reads only one part of a point(X) and fails to read the rest of the File.

Well I learned a lot about how Binary files work but I think I will stop working on this until Spine becomes a little more ripe.

I also made the Bone Component, Its been sitting on the Github pull request list for Spine.

Should read a varint that is the number of vertices in the mesh, then read that many floats.

Saw your PR, thanks. May be some time before I can get to it, want to get animating meshes done!

10 jours plus tard

Hi!
I've made simple component called "BonnesAttachment", that allows attach GameObject to submesh center. This object moves with animation so you can attach colliders or whatever you want to it
Link to unitypackage: https://www.dropbox.com/s/cjndt6r2klusk ... itypackage