Jump to content

SpriterDotNet - An implementation for all C# frameworks


loodakrawa

Recommended Posts

The idea look promising and very useful. I'm trying to find a workflow to use the spriter in unity, but Spriter2UnityDX ( the currently offer ) strip many of the cool stuff in unity.

SpriterDotNet, seems to keep almost all the properties of spriter and I give a shoot tonight... But is not working right now.

Unity 5.0.0f4 When I drop the unitypackage, any of the versions, I get -> Assets/SpriterDotNet/SpriterImporter.cs(108,49): error CS1501: No overload for method `LoadAssetAtPath' takes `1' arguments

Do I miss anything ? That's what I read in the README: "...The easiest way to install SpriterDotNet.Unity is by importing the appropriate .unitypackage... " or I should do/install something else prior this ?

Link to comment
Share on other sites

I manage to clear the error in SpriterImporter.cs, it has something to do with some update in unity 5...

GameObject existing = AssetDatabase.LoadAssetAtPath(prefabPath, typeof( GameObject ) ) as GameObject;
and
asset = AssetDatabase.LoadAssetAtPath (path, typeof(T) ) as T;

So far it seems the only feature missing is mesh animation, but that one is waaaaay new.

Link to comment
Share on other sites

Hi,

I saw on GitHub that you already found a solution. Nice work!
I added a comment: https://github.com/loodakrawa/SpriterDotNet/issues/15#issuecomment-155096864
 

Also, I'll leave the issue open for a short while and then close it as "wontfix" since it only affects older versions + I'll add the version requirements to the docs.

Link to comment
Share on other sites

Hey there. Seems like a really good implementation! I will likely be switching over to this over my own implementation(mine doesn't support all of the Spriter features like yours does). Does this by chance have any support for runtime sprite swaps/attaching of sprites to bones?
(without using the in-spriter based character maps)

 

For example, say I wanted to draw a set of armor over my character(not replace the existing sprite attached to the bone, or define character maps in spriter), does this support say, attaching a helmet(with pre-defined pivot points, etc), to the "Head Bone"? Or will I need to add some kind of support for this manually? (If it doesn't have it, a quick example on how to do so with your implementation would save the trouble of looking through everything in your source code and doing it myself, I can do this if needed, but a quick example would be much appreciated).

Link to comment
Share on other sites

43 minutes ago, Brassx said:

Hey there. Seems like a really good implementation! I will likely be switching over to this over my own implementation(mine doesn't support all of the Spriter features like yours does). Does this by chance have any support for runtime sprite swaps/attaching of sprites to bones?
(without using the in-spriter based character maps)

 

For example, say I wanted to draw a set of armor over my character(not replace the existing sprite attached to the bone, or define character maps in spriter), does this support say, attaching a helmet(with pre-defined pivot points, etc), to the "Head Bone"? Or will I need to add some kind of support for this manually? (If it doesn't have it, a quick example on how to do so with your implementation would save the trouble of looking through everything in your source code and doing it myself, I can do this if needed, but a quick example would be much appreciated).

Hi, 

That would be possible via runtime modification of the Spriter data structure. However, could you perhaps achieve the same effect by adding points to the animation and just drawing armor pieces on those points?

Link to comment
Share on other sites

15 minutes ago, loodakrawa said:

Hi, 

That would be possible via runtime modification of the Spriter data structure. However, could you perhaps achieve the same effect by adding points to the animation and just drawing armor pieces on those points?

That could perhaps work, however, some of the armor pieces are required to draw behind other elements of the Entity(side view, left arm drawn behind body, etc), so I assume the easiest way for me to do this would be to modify the SpriterObject info class, and add a variable pointing to the bone this object is parented to(-1 if none)? Then in the ApplySpriteTransform, I can detect what is being drawn on the bone, and decide whether or not to draw behind it, or in front of it (I won't have multiple things parented to the same bone either, nor will I have the depth of attached sprites changing in animations really.), however, that also has a downfall because since it doesn't contain the bone transform data, I can't really animate the rotation independently of the said SpriterObject in the Spriter editor..

So maybe I can modify it one step further and include the bone info for the bone the SpriterObject is attached to in the ApplySpriteTransform method, then I can use that(and in-code defined pivot/rotation offsets), to determine where to draw said armor piece?

 

Edit:Also a little feature that would be cool(if not yet supported), would be the ability to Rotate bones at runtime, this would be especially useful for shooters, and such that need their character to aim towards the mouse(or more advanced Inverse Kinematics)

Link to comment
Share on other sites

I have another simpler idea. You could add transparent placeholder sprites in the animation itself and then create a character map during runtime to replace the required placeholders with real sprites. This way you get all tranforms and z-indexes calculated out of the box. Does this solve your problem? If not, we'll figure something out.

Regarding IK and other advanced features - I'm investigating what can be done and already working on some features (state machine driven animations). If you feel inspired, feel free to contribute :-)

Link to comment
Share on other sites

  • 2 weeks later...
44 minutes ago, nmad said:

It would be great if you add animation files support. To use animator state machines instead of using spriterAnimator. It is easy to achieve really cool transitions with animator.

I assume you're talking about Unity. Since SpriterDotNet is a framework agnostic library, it doesn't use Unity's animation system and because of that it's not possible to use the animator. However, I'm working on a state machine driven approach in the library itself to achieve a similar effect.

Link to comment
Share on other sites

Hello i'm using this plugin for Unity and it works like a charm, but i have a question if someone can help me:

How can you handle the events of Spriter in Unity?,

For example i want to know when an animation is finished, like an attack animation, change it to the Stand animation
But also i want to know how to handle the events you can add in the timeline

Thanks!

Link to comment
Share on other sites

3 hours ago, exkyo87 said:

Hello i'm using this plugin for Unity and it works like a charm, but i have a question if someone can help me:

How can you handle the events of Spriter in Unity?,

For example i want to know when an animation is finished, like an attack animation, change it to the Stand animation
But also i want to know how to handle the events you can add in the timeline

Thanks!

Hi,

There are two C# events exposed in SpriterAnimator (and UnitySpriterAnimator subclass) which provide the functionality you want: AnimationFinished and EventTriggered

Link to comment
Share on other sites

24 minutes ago, loodakrawa said:

Hi,

There are two C# events exposed in SpriterAnimator (and UnitySpriterAnimator subclass) which provide the functionality you want: AnimationFinished and EventTriggered

I created two functions to handle the events:

	void spriterEvent(string eventName)
	{
	}

	void animationFinish(string animationName) {
	}

and in the update function of the same class i attach this events:
 

	void Update() {
		if (animator == null)
		{
			animator = GetComponent<SpriterDotNetBehaviour>().Animator;
			animator.EventTriggered += spriterEvent;
			animator.AnimationFinished += animationFinish;
		}

and i think it worked, thanks again!

Link to comment
Share on other sites

Testing this in Unity seems to be creating quite a bit of Garbage to be collected. I'd post this in the Unity thread, but any fixes will have to be done on the main lib.

It looks like each Spriter instance is generating about 5kb of garbage each frame.

84y.png

You can see from the profiler, ApplySpriteTransform is creating about .5kb, and then GetFrameData and GetFrameMetaData() are creating about 2.1kb each.

I'm looking into it now, and will post back if I'm able to reduce it. 

Link to comment
Share on other sites

34 minutes ago, esDotDev said:

Testing this in Unity seems to be creating quite a bit of Garbage to be collected. I'd post this in the Unity thread, but any fixes will have to be done on the main lib.

It looks like each Spriter instance is generating about 5kb of garbage each frame.

84y.png

You can see from the profiler, ApplySpriteTransform is creating about .5kb, and then GetFrameData and GetFrameMetaData() are creating about 2.1kb each.

I'm looking into it now, and will post back if I'm able to reduce it. 

This is basically the draw data and metadata for every frame. Did you have any performance issues due to this, or you just want to optimise for the sake of it? I'm a big fan of optimisation but usually I avoid doing it until proven necessary because "premature optimization is the root of all evil" as a smart person said. That being said, feel free to do it and submit a pull request if you get good results. Contributions are always welcome

Link to comment
Share on other sites

Well it is quite worrying, as with 20 units in the scene, I'm seeing GC times of 8ms on a powerful PC, occuring every 3 seconds. This game will eventually run on PS4 / Vita which have much much weaker CPU's.

So, I can't say I have performance issues right now on this PC, but certainly will once they game grows in complexity and runs on weaker machines. And considering I've put a ton of work into the game to remove as much garbage as possible, including object pooling, and optimizing loops and co-routines, it's frustrating to have this massive memory consumption wasting all my hard work.

I agree, in general, premature optimization can be a waste, but the code inside this plugin is _extremely_ hot code, it could easily run several thousand times per second at 60fps with many units in the world, so I'd argue that optimizing this inner loop so it doesn't generate much garbage, is not pre-mature, it's a fundamental requirement.

Tomorrow I'll try and I get this running on PSVita, and will be able to tell you for sure if we're seeing performance issues, but with 8ms collection time on PC, I'm pretty sure we will. 

I've looked at the code, and as you say, most of if it instantiation of Dictionaries, which I'm not really sure how to get around at the moment. I think you might have a much better idea on how you could possible cache/pool/reuse these frame objects, so they don't need to be constantly re-created. 

Another thing I noticed, there's pretty liberal use of for-each loops which (regrettably) are known in Unity to generate garbage because it uses an .NET old compiler.

 

Link to comment
Share on other sites

Also, worth mentioning that Dengar's plugin, which converts the SCML to a UnityAnimation, generates absolutely no garbage, no matter how many instances exist in the scene.

We switched to DotNet, because it seems better supported and seemed more future-proof solution, but it's really a bummer to see how much memory it's chewing through.

 

 

Link to comment
Share on other sites

19 minutes ago, esDotDev said:

Well it is quite worrying, as with 20 units in the scene, I'm seeing GC times of 8ms on a powerful PC, occuring every 3 seconds. This game will eventually run on PS4 / Vita which have much much weaker CPU's.

So, I can't say I have performance issues right now on this PC, but certainly will once they game grows in complexity and runs on weaker machines. And considering I've put a ton of work into the game to remove as much garbage as possible, including object pooling, and optimizing loops and co-routines, it's frustrating to have this massive memory consumption wasting all my hard work.

I agree, in general, premature optimization can be a waste, but the code inside this plugin is _extremely_ hot code, it could easily run several thousand times per second at 60fps with many units in the world, so I'd argue that optimizing this inner loop so it doesn't generate much garbage, is not pre-mature, it's a fundamental requirement.

Tomorrow I'll try and I get this running on PSVita, and will be able to tell you for sure if we're seeing performance issues, but with 8ms collection time on PC, I'm pretty sure we will. 

I've looked at the code, and as you say, most of if it instantiation of Dictionaries, which I'm not really sure how to get around at the moment. I think you might have a much better idea on how you could possible cache/pool/reuse these frame objects, so they don't need to be constantly re-created. 

Another thing I noticed, there's pretty liberal use of for-each loops which (regrettably) are known in Unity to generate garbage because it uses an .NET old compiler.

 

Fair enough - that's a valid point. I have a pretty good idea what can be done so I'll take a look this weekend and hopefully come up with a good solution. I'll let you know how it goes.

Link to comment
Share on other sites

Awesome thanks, we would really appreciate that! 

Also, for what it's worth, we're not using any of the advanced featured of Spriter, no MetaData, Sounds, Tags, Events etc, so I was able to get rid of half the garbage by just ignoring calls to GetMetaData completely.

Might be cool if the plugin was smart enough to know, hey you aren't using sounds, you aren't using events, etc, and maybe run in a more optimized state? Just a thought.
Cheers,

Link to comment
Share on other sites

2 hours ago, esDotDev said:

Awesome thanks, we would really appreciate that! 

Also, for what it's worth, we're not using any of the advanced featured of Spriter, no MetaData, Sounds, Tags, Events etc, so I was able to get rid of half the garbage by just ignoring calls to GetMetaData completely.

Might be cool if the plugin was smart enough to know, hey you aren't using sounds, you aren't using events, etc, and maybe run in a more optimized state? Just a thought.
Cheers,

Good suggestion. However, it would be rather unpractical to detect usage so I'll just expose various flags to allow user to enable/disable individual features. Also, I'll try to fix other things you mentioned in the Unity thread.

Btw, opened issues on github: https://github.com/loodakrawa/SpriterDotNet/issues

Link to comment
Share on other sites

I'm being using the plugin, and i want to use collision boxes as hitboxes for my characters.

But i'm having a problem, when i create a box in Spriter later than the first frame in the timeline in unity doesn't appear.

I must create all the collisions in the first frame?

Also i have a problem with a scml file, maybe my file is corrupted but i don't know, because i keep getting an error when i was testing creating and removing collision in Spriter in this scml file:
IndexOutOfRangeException: Array index is out of range.
SpriterDotNetUnity.SpriterImporter.GetDrawablesCount (SpriterDotNet.SpriterAnimation animation, SpriterDotNet.SpriterMainlineKey key) (at Assets/SpriterDotNet/SpriterImporter.cs:283)
SpriterDotNetUnity.SpriterImporter.GetDrawablesCount (SpriterDotNet.SpriterAnimation animation) (at Assets/SpriterDotNet/SpriterImporter.cs:270)
SpriterDotNetUnity.SpriterImporter.GetDrawablesCount (SpriterDotNet.SpriterEntity entity) (at Assets/SpriterDotNet/SpriterImporter.cs:257)
SpriterDotNetUnity.SpriterImporter.CreateSprites (SpriterDotNet.SpriterEntity entity, SpriterDotNetUnity.ChildData cd, SpriterDotNet.Spriter spriter, UnityEngine.GameObject parent) (at Assets/SpriterDotNet/SpriterImporter.cs:118)
SpriterDotNetUnity.SpriterImporter.CreateSpriter (System.String path) (at Assets/SpriterDotNet/SpriterImporter.cs:76)

thanks again for the help

 

Link to comment
Share on other sites

2 minutes ago, exkyo87 said:

I'm being using the plugin, and i want to use collision boxes as hitboxes for my characters.

But i'm having a problem, when i create a box in Spriter later than the first frame in the timeline in unity doesn't appear.

I must create all the collisions in the first frame?

Also i have a problem with a scml file, maybe my file is corrupted but i don't know, because i keep getting an error when i was testing creating and removing collision in Spriter:
IndexOutOfRangeException: Array index is out of range.
SpriterDotNetUnity.SpriterImporter.GetDrawablesCount (SpriterDotNet.SpriterAnimation animation, SpriterDotNet.SpriterMainlineKey key) (at Assets/SpriterDotNet/SpriterImporter.cs:283)
SpriterDotNetUnity.SpriterImporter.GetDrawablesCount (SpriterDotNet.SpriterAnimation animation) (at Assets/SpriterDotNet/SpriterImporter.cs:270)
SpriterDotNetUnity.SpriterImporter.GetDrawablesCount (SpriterDotNet.SpriterEntity entity) (at Assets/SpriterDotNet/SpriterImporter.cs:257)
SpriterDotNetUnity.SpriterImporter.CreateSprites (SpriterDotNet.SpriterEntity entity, SpriterDotNetUnity.ChildData cd, SpriterDotNet.Spriter spriter, UnityEngine.GameObject parent) (at Assets/SpriterDotNet/SpriterImporter.cs:118)
SpriterDotNetUnity.SpriterImporter.CreateSpriter (System.String path) (at Assets/SpriterDotNet/SpriterImporter.cs:76)

 

Can you please send me the .scml so I can investigate? You can either attach it here or pm me.

Link to comment
Share on other sites

i zip the file because it was larger than the forum max total size

what it's really strange is that when i create a collision in the spriter when i reopen the file it disappear..
EDIT: my file have 3 entity, 
what i see that the problem of the disappear collision in Spriter is something about the entity1 because in the entity0 it doesn't happen,
i tested in the entity0 creating two collision after the first frame in the timeline, they are added in unity but for some reason they appear too small in runtime, scale x and y 0.0001.

loli_000.zip

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...