Are there thoughts about 2D skeletal animation in MG.Extended @craftworkgames?
I’ve been working a bit on a runtime for DragonBones for MG. It’s a 2D skeletal animation tool similar too Spriter/Spine. They have an open-source AS3 (flash) library for it, since it was initially built for flash. DragonBones also has a free editor called DragonBonesPro which is pretty neat (though not open-source). The editor is alright, but could be a lot better. There was a Trello board for ideas for improvements and new features for the editor, but I’m not sure how active development is. I also haven’t heard from the maintainer in a while, which is why I haven’t open-sourced the runtime yet and am not actively working on it. For now the code is very much untested, but I’m pretty satisfied with the overal structure and I’ve been writing some documentation for the important parts. The runtime currently supports basic skeletal animation, changing colors during animations, free form deformation, all with tweening (linear or cubic bezier), changing slot draw order or textures during an animation and events. All of these are supported in DragonBonesPro as well. DBPro also support basic inverse kinematics, but that’s not in the runtime yet. I’ve only worked on it for about a week, before putting it on hold because I haven’t heard from the maintainer, so it’s far from finished. I initially thought it would be a nice (free!) alternative to Spriter/Spine, but I found it hard to work on it not knowing how actively maintained it is. Nevertheless, it’s all very usable in the current state and has some features that the free version of Spriter doesn’t.
Wow, sorry for ranting
Anyways, I was wondering if 2D skeletal animation should be a part of MG.E and figured I’d just put this out there and see what others think of it.
I think it would be cool to see some examples of implementation, a few screen-grabs of code, to demonstrate how one would interact with it. (initialization, update)…
I have done my own animations, like the running robot boss I posted pics of recently , but I have a hard time imagining what you are talking about However if you have something that could speed up the workflow on something like that, I’d be interested.
Here’s a video of DragonBonesPro in action (animating starts about 15 mins in). If you made the animation, using it in MonoGame is a breeze. In the end it should allow building an entire animation through code as well (though you really shouldn’t do that ) and changing pretty much anything dynamically. For example you can change textures in specific places, hide a texture or change the color for a specific texture (all three are really useful for making customizable characters).
Currently to use it, you load the textures for the animation first, then let the texture atlas (this is a large texture with all small textures fitted into it with an associated rectangle for where each small texture is located; DragonBonesPro can export this) load the texture it needs and load a DragonBones instance, passing in the textureAtlas and a graphicsDevice, and retrieve an armature from it (one instance can contain multiple armatures, but the Armature property used below just retrieves the first one for convenience, since often you’ll only have armature; you can have more if you want to nest animations).
var atlas = TextureAtlas.FromJson("Content/AnimationAtlas.json");
_armature = DragonBones.FromJson("Content/Armature.json", atlas, GraphicsDevice).Armature;
That takes care of everything you need to load. If I were to finish this, I’d make a content pipeline extension for this so you can load it using a contentmanager like other MonoGame content. You can then set the animation the armature should play:
_armature.GotoAndPlay("animationName goes here");
And update and draw it like you would expect.
// in Update
// in Draw
_armature.Draw(spriteBatch[, optional parameters for transformations and stuff]);
If you’re interested I’ll put the code on Github this week. So you can look through if you’d like
Yep. We’ve definitely had skeletal animations on the cards since the early days.
I didn’t know about Dragon Bones. Supporting that would definitely reduce the cost barrier. I’d still like to support Spine and Spriter as well though.
Interestingly I’m just starting to get deep into animation code this week. I’ve been improving our sprite sheet animations feature (it was in need of some love) and I’m just starting to look at other kinds of animations. I’d like to get it all working seamlessly together if possible.
Alright, I’ll see if I have time to put it up on Github this week. I’ll write some documentation/do some cleanup first.
I missed that issue! Not sure how much a shared API would add since - like you said - people will only use one of them and different features in DB, Spriter and Spine would complicate this. Might be best to have just 3 seperate implementations. Some consistency in implementation would be nice, since that would make it easier for people to understand the code. I’m open to structural changes in the existing code if there are decent suggestions.
Yeah, I’m not sure what makes sense here yet either. At the moment it’s just a thought. I think there will be some overlap but we’d have to be careful not to make it super complicated.
So I looked into dragonBones, and I still have a question about something like that in connection with monogame, if you have the time…
So I see how it would be nice for non-math based special animations, especially >sprite altering< things, like color and light changes, twisting etc…
But would it also be usefull for math-based or randomized animation?
Like a lot of my animation relies on wave forms or actual wheels and pistons, so I get results I could never “hand draw”,
where things move to where they are calculated to move…
This allows for “custom moves” by my units, smooth animation even at reduced speed, so they dont rely on fixed or pre-determined animation.
you know, swinging the club at where the player is, instead of just swinging the club, or stepping where the player is instead of just stepping…
Declare some vector2s as joints, pivot points or hard-points, and some floats as rotations and bone lengths…
-and rotate/transpose them in update, according to whatever is happening in game…
Then draw the sprites on those vectors with those rotations.
Would there still be an advantage to DragonBones in my case?
IMO the sprite altering stuff is the extra for DB and skeletal animation with transforms is the most important.
You could do the same thing you do in DragonBones by dynamically building an animation and setting the rotation of the bones at a specific frame. There’s support for setting a timescale for playback as well (can be negative for reverse animation). DragonBones doesn’t use pivots, because you can simulate it by adding a bone at the point you want to pivot around and add the slot to that bone. Everything that’s not determined at runtime could be made in DragonBonesPro (but can be done dynamically as well, if you don’t want to use the editor). The wave forms in your case should be translated to cubic bezier curves, but those tweening methods can easily be implemented as extensions to DragonBones since there’s an interface for them (could be put in the core as well, I don’t mind ).
Note that currently there’s limited support for dynamic animation building.
All in all, the DragonBones runtime in your case would provide a higher level API to do these things, but if you’ve built something for that already it’s probably not worth switching over. It does give some more flexibility if you’d like to add customization later.
Routine if you would use DragonBones:
- Create an armature in the editor (or at runtime in initialization) with everything that’s static (your hard-points and stuff) and set some defaults if you want
- Load the armature in the game if you’ve used the editor
- set the rotation/translation and tweening of specific bones/slots at runtime depending on game state in your Update methods
- call DbArmature.Draw(SpriteBatch) on the armature you’re using to draw it
Maybe the way this all works is a bit unclear right now, but I’m writing up a README that should clarify all this. I’ll put it up in a gist (it’s like a Github repo, but for a single file) later today if I have a chance, else I’ll do it tomorrow.
I finally put the code up on GitHub in case anyone wants to check it out. https://github.com/Jjagg/DragonBonesMG
EDIT: There’s a test project included that displays 3 animations. Two of them came with DragonBonesPro, the other was to test free form deformation. The Dragon will jump around, but that was to test animations without tweening. You can use the ‘,’ and ‘.’ keys to slow down and speed up the animations respectively. Playback timescale is clamped between -1.5 and 1.5.
For TY the Tasmanian Tiger in 2013 on Windows 8 and more recently on Steam, we wrote a skinned 2D skeletal animation system. Unfortunately I can’t release it since I don’t own it, but here’s part of a fan’s playthrough video showing the costume selection area where the animation is more visible than on the smaller in-game characters (go back to the start of the video for the in-game stuff, and watch it full-screen). It was done similar to Spine and DragonBones in that the character was broken up into shapes and shapes attached to bones, but we also allowed the animator to draw an arbitrary polygon around each shape, and then each vertex could be weighted to 1, 2, 3 or 4 bones. This allowed us to bend and flex each segment as well rather than each shape being fixed.
That seems a little bit different than how it’s done in DB and Spine, but they do support free form deformation, so you can define points on your images and drag them around during an animation to deform it. Here’s how it’s done in Spine. It’s on the roadmap for Spriter (Pro only) too.
Hello Jjagg, I’m reviving this topic because there’s been no update since last May. First of all, let me tell you that you’ve done an incredible job with DragonBonesMG. I’m seriously amazed that nobody told you so. In fact, I imported your dll in my project and added the code to display an animation of mine and at my great surprise it worked perfectly at the first try ! That’s totally amazing
Translation, rotation and scaling of a sprite works perfectly. But (yes, there’s a but), since you developed DragonBonesMG, the newer version of DragonBones made some changes with FFD for the meshes. In fact, since the 4.6 version it seems there’s no more FFD but only skin deformation with gravity points (the “FFD” property of the “animation” object is now empty in the skeletal json exported from DragonBonesPro). It means that DragonBonesMG can’t display the object at all (in fact, I even had to modify the sources of DragonBonesMG at file “Dispaly/DBMesh.cs” line 49 that triggered a Null Reference Exception).
I tried an older version of DB (4.5) and saw that FFD is simply consisting of moving each points manually, which is hard work, tiring and a lot less realistic than skin weighting. As another note it seems you can’t move the points like this in the newer versions of DragonBones, so that means that no mesh can work in DragonBonesMG since DB 4.6.
So my question is : is there a plan from your part to include the amazing feature of skin weighting in DragonBonesMG ? If no, what would be your insights so that someone else could implement it ? (I’m not saying that I’m doing it, because it really doesn’t fit in my planning and I’m not familiar with the structure of DragonBonesMG, but hey, I’m considering all my options here. Worst case scenario I might have to do it…)
And as I’m here, I would like to have another explanation as well : the DBArmature.Draw() method uses by default the GraphicsDisplay.begin() and .end() methods for each slot. If there is multiple armatures to render containing each a lot of image slots, won’t multiple calls to these begin() and end() methods slow down the program ? If that’s the case wouldn’t it be better to add a new Draw() method to the DBArmature object that doesn’t call begin() nor end() and let the user manage it ? Again, I did not benchmarked this, so it’s possible that it wouldn’t affect performances at all but I would like to have your opinion in the matter.
I hope you read this message. And again, thanks a lot for your amazing work on DragonBonesMG !
I didn’t actually implement FFD as it was in DB when I wrote the library, but I guess I did parse it somehow and that’s what causes the exceptions.
I wrote the library for a game I was working on, but we dropped the game and I haven’t needed the code since so it’s more of a prototype. I just tried to get everything working first and didn’t optimize in any way. So you’re right that draw calls can be done way more efficiently and the code generates a lot of garbage. Also a bunch of processing could be done in a pipeline extension so load times can be reduced. I don’t have plans to continue working on it right now, but if I want to do a game with skeletal animation I will. I’ll post back here when I do That said, if anyone wants to improve the library or implement any new features, feel free to ask for help!
Recently DragonBones got an official open source Unity runtime that might be easy to port for use with MG (I didn’t really look at it), but I found the code of their official ActionScript 3 library very confusing and chaotic, so I’m not sure about the quality of the Unity runtime…
I just saw a YouTube video ( https://www.youtube.com/watch?v=VCSrJ1KHytk) that shows the weighted skinning and it is very impressive! Especially for free software!
Thanks for the swift answer
I tried a unity “module” called DragonBonesCSharp but there was a lot of errors in the scripts when I imported it (surely due to a problem of Unity version that was newer or a mistake from me when I placed the files in the asset/scripts folder ), so I didn’t push it anymore. In light of what you said, maybe I will.
But in fact I really would like to use MonoGame and not Unity. Even if Unity contains a great editor and I’ve been able to easily make sprites move in a matter of minutes, I’m more attracted to the free and open-source-ness of MonoGame.
So for now I think I will immerge myself in the code of DragonBonesMG and try to bake something for the skin deformation with gravity points. No promises though, even if I’m a somewhat experienced developer, I’m far from a confirmed 3D developer ! But I give you my word that if I got something working I will share it with you
Awesome! Let me know if you need any help.