Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on Dec 8, 2022, between 7 am & 7 pm EST, in the DOTS Dev Blitz Day 2022 - Q&A forum, Discord, and Unity3D Subreddit to learn more about DOTS directly from the Unity Developers.
    Dismiss Notice
  3. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

[RELEASED] Spritedow Animator, a simple sprite animation system

Discussion in 'Assets and Asset Store' started by Elendow, Apr 6, 2017.

  1. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    84
    The update is now live, the changelog shown in the store is incorrect, I had some issues with the backend, but the plugin is correctly updated.
     
  2. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,426
    Thanks will give a go!
     
  3. Rocky_Unity

    Rocky_Unity

    Joined:
    Oct 13, 2017
    Posts:
    91
    Hi Elendow, I was wondering what the possibility of using/adding the Job System to this asset would be? I think that would be an incredible icing to this already delicious cake

    Edit: I am also wondering if you hash your animations, instead of using
    spriteAnimator.Play("SomeAnimation")
    , and use
    spriteAnimator.Play(1)
    instead. Or something like that
     
    Last edited: May 22, 2021
  4. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    84
    Hi there, I'm no expert with the Job System or ECS, so it will be very hard for me to add it, I'll look into it but no promises, thanks for understanding.

    For the other question, the lasts versions of Spritedow can play animations using directly the animation asset instead of using the name of the animation, I encourage using that system, I'll probably deprecate the animation list and the using of names on the next version of the plugin.

    I hope this helps you :)
     
  5. Rocky_Unity

    Rocky_Unity

    Joined:
    Oct 13, 2017
    Posts:
    91
    The job system is a relatively "easy" tool to use, I highly recommend looking into it, if only for fun. It's really cool! I think it could serve perfectly to handle the 'fps timer sprite index' calculations for all objects that are being animated. Whether or not it'll mesh well with other animation logic (like changing the animation), is definitely the challenge. I really think it's possible though.

    It'd be really cool to see performance of 1000, 10000 animated with mechanim, then with your asset, then with your asset on the job system! (no need to mess with ECS in my opinion, that's only beneficial when you have many systems to use ECS with)

    Also, that is great!! I was concerned about having to use strings for animations, I'm glad I don't have to. Love it

    Anyway, I just bought it, I can't wait to dig into it!
     
  6. Rocky_Unity

    Rocky_Unity

    Joined:
    Oct 13, 2017
    Posts:
    91
    Elendow,

    I'm not sure if you have tried this already, but I benchmarked your animator against Unity's Mechanim animator.

    With objects making 6006 calls to your Update() function, your Spritedow animator is about 4x faster than using Unity's Mechanim. This isn't to hate on Unity's mechanim, it just has more overhead to run features/controllers that aren't as necessary with key-frame based sprite animations
     
  7. Rocky_Unity

    Rocky_Unity

    Joined:
    Oct 13, 2017
    Posts:
    91
    Hi Elendow, I hope you are well.

    I've been extensively using your animator the past 4 weeks and have a little more feedback

    1. Ignore my comment from last year about using ECS lol
    2. The animations could really benefit from being able to add in custom `event Actions`. I know there's some support to do this but the only API uses strings, and that's just a no go for anything really, in my opinion. It's also only useable at run-time and I'd rather define the events in the SpriteAnimation.
      1. The purpose is for things like "Sword Hit" events that occur part way through an animation. It's much nicer to define that timing in the animation asset rather than an arbitrary timing value I pick elsewhere in the code
    3. I had to add my own OnStop Action to the animator code because I didn't want to use a UnityEvent. Additionally, it only runs once. I called it, OnStopOneShot so that it removes any callback assigned to it immediately, then runs the callback.
      1. The reason is so that I can do things like reset my character's "State" to idle, after some animations (like attacking).
      2. It'd be awesome if you can add this officially to the asset in whatever way you see fit. There's a danger of infinite recursion if OnStopOneShot gets called and the delegate does something that might call OnStopOneShot again. If you make the type a `Action<SpriteAnimation>`, pass in the animation that is being stopped, you can set OnStopOneShot to null immediately, in order to avoid this situation, with a wrapper function
    Maybe the changes I have made are unnecessary and could be done differently, but it's just feedback for how I've gone about some logic in my code so far

    Besides that I am LOOOOVING it so far :) It does so much that I really needed and skipping mechanim for Key Frame based animations has been tremendous. Thank you for making this invaluable tool!
     
  8. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    84

    Hi there,

    The problem with actions defined on the animation is that I cannot serialize an event with its reference. A event system that you can define on the animation will require some sort of message sending between the animation and the animator and I'm not entirelly sure how this will work. Maybe defining an event on the editor with a name "Sword Hit" in your example, and sending a message "CustomEvent.Invoke("Sword Hit")". This is the way Spine uses events on its runtimes... Not making any promises, but I'll look into it.

    I'll check if I can implement the OnStop, but as for consistency I'll try to implement it with UnityEvents.

    Also, I'm developing right now and update, unfortunately this update will be incompatible with the current animations because I made a big improvement in structure and implementation.

    For starters, the animation fetch using string is completely removed, now you use the asset itself to play it. Also, the animation list is no longer needed, it's there only if you want to loop random animations. Internally, the frames and it's durations are no longer stored in two separate lists but only one with a struct storing both values.

    I've solved some bugs and improved a bit the code. All of this changes are made because after using this plugin in multiple comercial games, this structure is the most used and the most efficient.

    Thanks a lot for your feedback and I'm very glad you are enjoying my little plugin :)
     
    Last edited: Feb 28, 2022
  9. Rocky_Unity

    Rocky_Unity

    Joined:
    Oct 13, 2017
    Posts:
    91
    Those changes sound excellent! I can see if I can convert a basic Action delegate into a UnityEvent.. hmm.

    As for the events, I just made a serialized List<MyEventAction> on the animation asset. It contains a name (I just use the index in the list though because I really don't like referencing by strings) And a time in which it should be called. During play, at the same time I check if a new frame should be set on the sprite renderer, I check if I should call the event. Anything that subscribed will do its thing.

    That's probably not the best route for your asset? I am unsure.
    Ultimately, I can always forward my changes into your update if they are things that you don't think fit for the asset

    I am stoked you are removing the animation fetch using string :). I currently just pass the asset to play any animation, in-fact I usually don't put anything in the serialized fields of the Animator either. At least for my player which has 6 different animators on it. Static stuff like decorations will make use of those serialized fields

    I'm also working on an Aseprite to Spritedow importer tool. I probably won't have it ready for 2 months as I'm working on other parts of my game at the moment, but I will need to finish it soon as I have hundreds of animations to import.

    And congrats on multiple commercial games!! That's so cool. I hope to add mine to that list at the end of this year :)
     
  10. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    84
    I'm using the Spine Runtime approach to the events defined from the editor.

    Now, the animator has a UnityAction called AnimationAction. You can suscribe to that, and each time and action is fired it will send the data from that action, basically the name of the action, the animation and the frame.

    upload_2022-3-5_16-0-2.png

    I know using strings is not the best approach to this kind of things, but you can use the animation and the frame in order to know if it's the event you want.

    This will be in the next update, I don't have an ETA, but I'll try to have it ASAP.
     
  11. Rocky_Unity

    Rocky_Unity

    Joined:
    Oct 13, 2017
    Posts:
    91
    This sounds like exactly what I am hoping to have in the next update :) Especially with your example of "Hit", which is exactly one case I'd like to use it for. I am looking forward to the update!
     
  12. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    84
    Hi everyone,

    A new version of Spritedow Animator have been uploaded.

    BEWARE, THIS VERSION IS NOT COMPATIBLE WITH PREVIOUS VERSIONS OF SPRITEDOW ANIMATOR.

    Changelog:

    - Added actions to the Animation Window
    - Added actions to the API
    - Improved overall performance
    - Improved API

    Sorry for being so late with this update.
     
  13. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,426
    Added actions -< Can you elaborate a bit more please? Is there doc on it?
     
  14. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    84
    Of course.

    Now, when you create animations, you can add an action (or multiple actions) to a frame.

    upload_2022-11-25_9-26-12.png

    In your code, you can suscribe to the Actions event and check what Action have been triggered:

    Code (CSharp):
    1.  
    2. private SpriteAnimator spriteAnimator;
    3.  
    4. private void Awake()
    5. {
    6.     spriteAnimator = GetComponent<SpriteAnimator>();
    7.     spriteAnimator.OnAnimationAction += OnAnimactionAction;
    8. }
    9.  
    10. private void OnAnimactionAction(SpriteAnimationAction action, SpriteAnimation animation)
    11. {
    12.     if (action.Data == "StartJump")
    13.     {
    14.         // Do something
    15.     }
    16. }
    17.  

    Hope this helps :)
     
  15. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,426
    May I suggest that actions can have parameters such as int and string? I have already customized the animator to have similar event system such as below and I found that it needs parameter to be really useful, practically.

    upload_2022-11-29_13-19-1.png
     
  16. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    84
    I don't see a need to add parameters to the actions. The actions aren't mutable so the parameters will be always the same, you can have those on the receiving end of the action and do as you please there.
     
  17. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,426
    Understood, but I always find it helps to not go though parsing strings into different formats when common commands are used with different parameters like. The example I have shown uses enum as action types and parameters because I don't want to parse strings to do a lot of common events with different degree. Something like Unity Animation Events.
     
  18. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    84
    Hi again,

    I understand that strings is not the best, but this is intended to be a generic system, I can't make an enum that you can expand because with every update of the plugin it will be overriden.

    You have, tho, the custom event system still in the plugin, that enables you to add as many events as you want via code, and those don't use strings.
     
  19. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,426
    Sure, I am not saying the you should implement enum as action types. That's just for our project only. What I was going on about was that even if generic system is the main purpose, having string only as a action type and then not having another extra string, bool, float (or int) as a parameter to go with it can be limiting. We would generally want to create event like such as SpawnSFX or SpawnParticle etc with parameters that can choose what to actually follow. Having to have to only rely on single string to do animation event is too limiting, if you don't want to do unnecessary parsing to get details.
     
  20. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    84
    In such case, the script detecting that "SpawnSFX" or "SpawnParticle" dictates what SFX or Particle needs to be spawned, the action contains the Caller Animation and the Action Name, you really don't need to parse anything on that string to know what SFX or Particle needs to be spawned.