Search Unity

[RELEASED] Spritedow Animator, a simple sprite animation system

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

  1. NaughtyMoleGames

    NaughtyMoleGames

    Joined:
    Jan 25, 2018
    Posts:
    51
    Anyway to get ping-pong animation option added? Thanks!
     
  2. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi!

    I'm preparing and update to solve some little issues and I'll try to add this on it!
     
    NaughtyMoleGames likes this.
  3. NaughtyMoleGames

    NaughtyMoleGames

    Joined:
    Jan 25, 2018
    Posts:
    51
    One more thing id love to see is the 'elendow tools' menu just merged into the generic "Tools" menu used by most plugin developers.
     
  4. Lars-Steenhoff

    Lars-Steenhoff

    Joined:
    Aug 7, 2007
    Posts:
    3,527
    Is playmaker already supported?
     
  5. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Will do, thanks for the tip :)

    It's on my roadmap to add support for Playmaker, NodeCanvas and Bolt, but for the moment they're not supported, sorry.
     
    Lars-Steenhoff likes this.
  6. PixelEnvision

    PixelEnvision

    Joined:
    Feb 7, 2012
    Posts:
    513
    Hello,

    I've just purchased and downloaded latest version to use it in my current project.

    When I tick "Play on Awake" it gives the following error upon game start and when enabling disabled object "Animation 'null0' not found."

    There is a single animation and it's properly linked and works otherwise.

    Can you please take a look?
     
  7. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi there,

    You are correct, there's a bug with the animation list of the SpriteAnimation component. I'll try to solve this for the next update that will be live later this month.

    In the meantime, you can solve this problem going to the "BaseAnimator.cs" script and making public the "startAnimation" field, on the line 55.

    I'm very sorry for this inconventient, thanks for pointing this out.
     
    PixelEnvision likes this.
  8. PixelEnvision

    PixelEnvision

    Joined:
    Feb 7, 2012
    Posts:
    513
    Not a problem, and thanks for the prompt reply with a quick fix... :)
     
  9. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi everyone!

    The 1.0.3.2 version is now released!

    Changelog:
    - Added LoopType to the Basic Behaviours.
    - Added LoopType to the API.
    - Improved Animator Components.
    - Fixed a bug with the panning on the animation window.
    - The Elendow Tools menu is now on the Tools menu.

    All the feedback is well received!
     
  10. PixelEnvision

    PixelEnvision

    Joined:
    Feb 7, 2012
    Posts:
    513
    Great! I've just started integrating this to static sprites in my current project. So far it's working great, I'm glad with the purchase. Previously I was using PowerSprite animation which is also nice, but it's dependent on unity's animation system and overhead, which caused my move.

    May I have few suggestions?
    * I would love to be able to use play command in a coroutine where it returns play state. i.e. something like

    yield return animatior.Play("Walk").WaitForCompletion ();

    I think I can do yield return new WaitWhile (() => animatior.IsPlaying () && animatior.CurrentAnimation("Walk")); but native support as above would be easier/cleaner to use.

    * In animation window it would be helpful to have flip x,y option and even better rotation support customisation for each image. That would allow re-using same frames something like looking left & right within the same animation...

    Thanks!
     
  11. PixelEnvision

    PixelEnvision

    Joined:
    Feb 7, 2012
    Posts:
    513
    Hi again,

    Backwards option doesn't seems to be working with the latest update.

    Component is on a prefab, play on awake, one shot & backwards checked. When instantiated, it shows actual first frame and stays there. If backwards is unticked it works as expected.
     
  12. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Yes, there was a bug here. I submitted an update that will be live ASAP.

    Regarding this, you can use the event system for both. You can use "OnFinished" for the "WaitForCompletion" and the custom events to flip the character on a specific frame.

    I'll try to implement your suggestions tho.

    Cheers.
     
    PixelEnvision likes this.
  13. PixelEnvision

    PixelEnvision

    Joined:
    Feb 7, 2012
    Posts:
    513
    Hello, thanks for the replies before.

    I think there is another bug. There is one animation of the list, Play on awake, One Shot & Disable render of finish checked.

    When instantiated prefab starts with sprite renderer disabled, it plays the animation but of course nothing displayed.

    If I untick Disable render of finish it works but of course disable is not working...
     
  14. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    I'll see what is happening. In the meantime you can have the sprite renderer enabled but without sprite. Sorry for the troubles :(
     
  15. PixelEnvision

    PixelEnvision

    Joined:
    Feb 7, 2012
    Posts:
    513
    No problem and thank you. :)

    Btw, I'll have a small suggestion for your next update.

    While doing my GC Allocations sweep on my project I've noticed BaseAnimator.Update() method generated a small garbage. Apparently it was coming from the currentAnimation.Name call. Changing code a bit fixed that, at least when not using custom events and it shouldn't cause any issues.

    Code (CSharp):
    1.                     // Check events
    2.                     if (customEvents != null)
    3.                     {
    4.                         SpriteAnimatorEventInfo frameInfo = new SpriteAnimatorEventInfo(currentAnimation.Name, frameIndex);
    5.                         if (customEvents.ContainsKey(frameInfo))
    6.                             customEvents[frameInfo].Invoke(this);
    7.                     }
     
  16. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi there,

    I just released an update with this little change and the bug with the disabled renderers fixed.

    Thanks for your feedback!
     
    PixelEnvision likes this.
  17. PixelEnvision

    PixelEnvision

    Joined:
    Feb 7, 2012
    Posts:
    513
    Hi again,

    I have a UI image (coin) which animates once in a while, so it has UI Animator component with a single animation and nothing ticked on Basic Settings.

    After the new update I've noticed that image disappears on startup but appears when animation is played. It looks like the culprit was SetActiveRenderer(false); on line 91 of BaseAnimatior.cs and removing that line fixes the issue.

    I've wanted to let you know and also wanted ask the purpose of disabling the image on Awake? I just need to know if removing that might broke some other code...
     
  18. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi there,

    That's probably a line of code I left there by accident when I was testing the last bug. You can safely remove it and I just updated to remove it to everyone.

    Cheers.
     
  19. PixelEnvision

    PixelEnvision

    Joined:
    Feb 7, 2012
    Posts:
    513
    Ok, great! Thanks for the prompt reply. :)
     
  20. NaughtyMoleGames

    NaughtyMoleGames

    Joined:
    Jan 25, 2018
    Posts:
    51
    Hey, Would love to see StopAtFrame() or Stop(frametostopat) added. This would allow users to remove one sprite idle animations and to just stop the animation. Thanks!
     
  21. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi there,

    I'll think about it, but you could do that using the CustomEvent system. You can add an event to the frame you want and stop the animation at that frame.

    Cheers!
     
  22. NaughtyMoleGames

    NaughtyMoleGames

    Joined:
    Jan 25, 2018
    Posts:
    51
    Im unsure what you mean?
     
  23. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Code (CSharp):
    1.  
    2. string idleAnimation;
    3. int frameToStop;
    4.  
    5. private void Start()
    6. {
    7.     animator.AddCustomEvent(idleAnimation, frameToStop).AddListener(StopAnimator);
    8. }
    9.  
    10. private void StopAnimator(BaseAnimator animator)
    11. {
    12.     animator.Stop();
    13. }
    14.  
    With that code you can stop the animator on the desired frame (frameToStop) of the animation you want (idleAnimation). You can do this for any animation on your animator. At least, if I understood correctly what you want to do xD
     
  24. NaughtyMoleGames

    NaughtyMoleGames

    Joined:
    Jan 25, 2018
    Posts:
    51

    The problem with that code is it stops everytime it gets to that frame.

    I just want to do;

    Code (CSharp):
    1. int frameToStopAt = 2;
    2.  
    3. animator.Stop(frameToStopAt);
    Then I don't even need an idle animation. Because it sets the spriterenderer to the frame called in the stop event.

    EDIT: Added this to baseAnimator.cs

    Code (CSharp):
    1. /// <summary>
    2. /// Stops the animation at a certain frame.
    3. /// </summary>
    4. public void Stop(int frame)
    5. {
    6.         randomStartFrameApplied = false;
    7.         playing = false;
    8.         onStop.Invoke();
    9.         SetActiveRenderer(!disableRendererOnFinish);
    10.         ChangeFrame(currentAnimation.GetFrame(frame));
    11. }
     
    Last edited: Mar 8, 2019
  25. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi again,
    I'll add the method, but I'm still unsure why you need this functionality. Could you explain it to me with and example please?
    Thanks :)
     
  26. NaughtyMoleGames

    NaughtyMoleGames

    Joined:
    Jan 25, 2018
    Posts:
    51
    There are multiple reasons you might want this;

    1. Lets say you have some kind of freeze skill, you can just call stop on the animator which would stop it on a certain frame instead of on the currently active frame.
    2. No need to have idle animations...Lets say you have 3 frames (left foot forward, both feet together, right foot forward) and you just yoyo the animation for walking, well if you want to just use the both feet together frame as your idle Frame you can just call stop(1) anytime you want to stop the animation. This is nice because then you don't need to do additional coding for current direction, etc.

    Hope those made sense
     
  27. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi everyone!

    I just submitted the versión 1.0.4 to the asset store, and it will be live when Unity gives the approval.

    Changelog:
    - Added Fallback animation to the basic behaviours
    - Added Fallback animation type to the basic behaviours
    - Added SetFallbackAnimation to the API
    - Added RemoveFallbackAnimation to the API
    - Added StopAtFrame to the API
    - Solved some minor bugs on the preview window

    I hope you like the new features!

    And by the way, thank you very much for the explanation. I hope the StopAtFrame that I implemented will be useful to you :)
     
  28. kylewill713

    kylewill713

    Joined:
    Jun 22, 2016
    Posts:
    5
    Looks like there is an issue with sprite preview editor tool offset of the sprite in Unity 2019, link to screenshot

    https://imgur.com/a/Xmiae09
     
  29. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi, I'm truly sorry for the late reply, I was out for some days and couldn't answer.

    In what version of Untity 2019 and what OS?

    I'll try to fix it ASAP, thanks for your patience!
     
  30. kylewill713

    kylewill713

    Joined:
    Jun 22, 2016
    Posts:
    5
    I'm running Unity 2019.1.3f1 -> Windows 10, I noticed it when I upgraded my project from 2018 to 2019. I just made a blank project and imported the asset screenshot attached.

    https://imgur.com/a/gp0J2sL

    The tool is still usable its, just a little annoying
     
  31. SuperAhao

    SuperAhao

    Joined:
    Apr 23, 2018
    Posts:
    8
    I want to know if the event useful for every frame
     
  32. SuperAhao

    SuperAhao

    Joined:
    Apr 23, 2018
    Posts:
    8
    how about select sprites and creat a animation can save time

    and if can make a events inspector ? use UntiyAction can drag object,sel fun and write param

    thanks
     
  33. SuperAhao

    SuperAhao

    Joined:
    Apr 23, 2018
    Posts:
    8

    every frame some actions
     
  34. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi,

    I don't quite understand your questions but I'll try to answer you:

    Yes, you can put an event to every frame, but maybe is not the best thing to do due performance and garbadge generation.

    There is an animation editor where you can drop your sprites to automatically generate animations, it's very fast, that was the original purpose of this asset.

    No, you can't set events on the inspector, those are code oriented and for the moment will stay that way, sorry.

    I hope this helps :)
     
  35. SuperAhao

    SuperAhao

    Joined:
    Apr 23, 2018
    Posts:
    8
    sorry My english is poor .

    The fps setting have two part, the slider and the inputFiled,why not set the two part to one, I can get the preview and make sure that is the result I want.
     
  36. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Sometimes you want to preview an animation with a different FPS without changing it's value, that's basically why there are two different fields.
     
  37. SuperAhao

    SuperAhao

    Joined:
    Apr 23, 2018
    Posts:
    8
    Thanks,but I thinks select sprites and make animations is nessary, I don't want to creat a asset and drop sprites, why sel sprites and creat a asset, just one step.Even now it is fast also.

    I got the reason why not set events on the inspector, in my view, event is frame oriented, but two way I both can accept.

    And about the two fps... everywhere is the preview fps, is not the set fps...
     
  38. SuperAhao

    SuperAhao

    Joined:
    Apr 23, 2018
    Posts:
    8
    upload_2019-9-4_1-5-42.png

    The preview is always stay the same whit the slider, not the real value.
     
  39. SuperAhao

    SuperAhao

    Joined:
    Apr 23, 2018
    Posts:
    8
    I hope when I editor animation, the preview is the result what I want, not set the inputFiled again.
     
  40. SuperAhao

    SuperAhao

    Joined:
    Apr 23, 2018
    Posts:
    8

    I get the way "events are cod oriented", this can separate view and logic Thanks
     
  41. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Interesting asset. I have few questions.

    1. Does it work with Unity sprite atlas?
    2. Since this is custom animation system, when does the actual sprite renderer sprite update happen? During update fixedupdate or unscaled time?
    3. Is it possible to get current frame sprite name or should i get that from sprite renderer after animator has finished updating it?
    4. Are there any events that we can subscribe to when animation has finished playing, or started to play?
    5. For custom events, do I have to add one manually by code every time I want to play the specific animation?
    6. Can we add more than one custom events per animation?
    7. Comparing to mechanim, how does it perform in terms of performance?
    8. When you play animation does it update sprite renderer at the same time or on the next frame?
    9. When you disable and enable animator, does it continue from where it left off in terms of frames it was playing? Or will it reset?
    10. If you use addressable to load animation assets, will it find sprites correctly if atlas is also loaded?

    Ta!
     
  42. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi there, wow, lot's of questions :)

    1. Yes, as long as you make the correct reference to the sprite you want, it works with Unity Sprite atlas, individual textures... everything.
    2. It happens in the update and you can specify if you want it affect by the timescale or not.
    3. The animator has a reference to the sprite renderer, so you can get it from there. I didn't add a reference to that because you have to wait anyway the update of the animator to get the current sprite...
    4. Yes, those come by default.
    5. No, once created the custom events will be firing always, no need to create them every time you play the animation.
    6. Yes, as many as frames has the animation.
    7. It's very lightweight, I'm currently using it on a project with hundreds of animations playing simultaneously and it runs pretty smooth. The events alocate some GC because I use Unity Events, but nothing to worry about.
    8. Depending if you stopped the animation or not previously. If the animation is a new animation, it will change the sprite at the same time you play it. If the animation was playing previously and you are resuming it, it will change the sprite when needed.
    9. There's a "Resume" method you can call to resume the animation and a "Reset" method you can call to play it from the beginning, you decide.
    10. I don't know for sure, I haven't tested it yet with Addresables... With AssetBundles it works perfectly fine so I guess with Addresables it works fine too. Gonna run some tests and I tell you then :)

    Thanks for your interest! If you have any more questions don't hesitate to ask :)
     
  43. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Hi. Thanks for the detailed answer. I have went ahead and purchased the asset.
    However, I would like to ask, one more thing if I may. This may, may not directly related to the asset itself, but anyway.

    I want to create a template animation and then replace it on demand during runtime to hot swap sprites. This is for say if I have a body sprite animation, then I want to swap it with some other body sprite animation. What do you think the best method be? Create animation assets per variation and then swapping them out seems like I would need to create 100s of animation asset files, which I would very much like to avoid.

    This is the reason why I asked about the no.3 where I could get the name of the sprite for current animation frame. The reason why I don't want to get it off from Sprite Renderer is that any .name property access in Unity is going to cause GC allocation. So it is much more prefered to be able to say... tag along the event just before animator updates sprite on the Sprite Renderer and be able to supply the custom sprite based on the current animation's sprite name ( cached ).

    Any idea for this kind of swapping sprite?
     
  44. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hum, that is possible if you want extend a bit the plugin. You can get the current animation on the animator and swap the sprites on the sprite list of the animator. The thing is you still will need to have the sprite lists somewhere.

    Also, the animations are scriptable objects so, any change made to them on runtime will be saved. You probably want to make a copy of the animations to use on runtime.
     
  45. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Can we add variation of PlayStartingAtFrame with spriteAnimation as source input as well?

    Also PlayStartingAtFrame is a good idea, but can we add PlayStartingAtNormalizedTime also? Otherwise, we have to manually calculate which frame it needs to play at if I say want to play from half way of the animation.
     
  46. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Also , when you play animation with animation as input, how do you add custom events to it?
     
  47. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi there,

    I'll add the PlayStartingAtFrame with SpriteAnimation as a parameter in the next update. The same for the custom events with an animation as a parameter. It will be ready next week probably :)

    As for the Normalized Time, everything in this plugin uses frame based time, so I'll stick to that, but I'll add a property to count the total frames (including the frame duration) to make this calculations more easy, I hope that this is fine for you :)
     
  48. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Sure. Right, I was playing with the asset today, and I found that the onFinish is somewhat limited on what it should mean... To explain myself, if I set the animation to loop, then onFinish gets called on every last frame. This is ok, if that is what it is supposed to be doing, but we need another one that gets called when animation finished playing and it is not looping. This is because otherwise, onFinish gets called for both looping and non looping animations so it is not possible to distinguish between them. I can ofcouse add custom events to all the animations, but if I have a lot of animations, then it is hard to add all the events individually. If I have event that gets called when non looping animation gets finished playing along with current onFinish, then I can use both to do more interesting event handling.
     
  49. Elendow

    Elendow

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

    You can check inside the OnFinish event what animation is playing when the event is called using the "CurrentAnimation" o the new "PlayingAnimation" that will be on the next update, that should help you handle the events of looping and non looping animations.

    Anyway, I'll just submitted a new version with added methods to handle custom events with SpriteAnimation as a parameter, that probably should help too with your issue. I'll look into this to add more events or systems to help get you what you want, but after the release of the next version (when Unity approves it).

    Thanks a lot for your feedback :)
     
  50. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Hi.

    I was able to create my own SpriteAnimator class based on the BaseAnimator to do my overriding sprites on the animations. This worked pretty good. All I will probably need is to be able to check the event when animation with no loop is finished. But after taking a look at the code, isn't onStop does what I wanted to do? I was not 100% sure, but it seems like Stop is called when it is done with non looping animation? I could be wrong.. but yeah..

    Also, I can understand that why everything is based on the frames. But what if I had 3 frame animations and wanted to play the animation at exactly half way? There is no way to set my frame to be 1.5 ... This was my obvious reason for asking about it. I could ofcourse increase the fps and modify the animation, but it doesn't sound like intuitive to manually adjust the animation and its fps to suit the need of playing at specific normalized time on the animation.. I think play at normalized time is actually a good idea. The idea is to find out which sprite needs to be update at specific time, and then update internal time tick to be at the specific time. Unity Animator has this feature and some other custom frame animation assets do support this.