Search Unity

[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:
    87

    An easy to use, standalone sprite animation system


    Hi everyone!

    I'm very glad to announce my first plugin, Spritedow Animator! I make lots of 2D games and the workflow with Mecanim always bothered me, so I decided to make this little plugin in order to enchance my productivity making animations with spritesheets. I use it everyday on my workspace so I'll improve it with new features, totally free.

    I hope you like it and find it as usefull as I do!

    Spritedow Animator is a simple and standalone alternative to Mecanim to animate sprites frame by frame.

    Just drop your sprites or spritesheets to the editor and you will have an awesome animation in a jiffy (hehe).

    NOTE
    This plugin is oriented to programmers: althought it has a visual animation editor, all the cool features need some code to work.

    FEATURES
    • Simple and easy to use Animation editor
    • Animation preview
    • Play animations forward or backward
    • Play random animations
    • Animate ignoring time scale
    • Custom animation framerate
    • Custom frame duration
    • Basic events (onPlay, onStop...)
    • Custom events
    • Works with SpriteRenderer and UI Images
    • Renderer control methods
    • Make simple behaviours without code (loop, random, play on awake...)
    • Completely standalone, this plugin does not use the Unity's animation system




     
    Last edited: Jan 13, 2023
  2. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Changelog
    2.0.1
    • Fixed a bug with the UI Animator.
    • Replaced the UI Animator "Adapt Pivot" property for the new "Preserve Aspect Ratio" property.
    2.0.0
    VERSION 2.0.0 IS NOT COMPATIBLE WITH PREVIOUS VERSIONS OF SPRITEDOW ANIMATOR.

    PLEASE, DON'T UPDATE IF YOU CANNOT AFFORD TO LOSE ALL YOUR ANIMATIONS AND FIX API CHANGES.
    • Added actions to the Animation Window
    • Added actions to the API
    • Improved overall performance
    • Improved API
    1.2.0

    • Added Animation Duration in seconds to the animation API.
    • Added "Reverse Frames" to the frames list.
    • Improved performance of the animations on low FPS games.
    1.1.2
    • Fixed a bug where the sprites appear dark on projects with linear color space.
    • Improved the synchronization between the Sprite Animation Window and the Sprite Animation inspectors.
    1.1.1

    • Fixed a bug with custom events not triggering on frame 0.
    • Fixed a bug with out of bounds index using time instead of frames on the animator.
    • Fixed a bug where the animations would play faster on the editor than ingame.
    • Improved the way the AnimationDuration of the animations is calculated.
    • Added PlayStartingAtNormalized time (without parameter, with animation name and with animation) to the animator API.
    • Added GetFrameTime (with and without FPS specified) to the animation API.
    • Added GetFrameAtNormalizedTime (with and without FPS specified) to the animation API.
    1.1.0
    • Fixed a bug with the times of the frames. Now your animations will play FASTER than before, because they were playing SLOWER than desired.
    • Fixed a bug with animations with empty frames on a UI Animator.
    • Added PlayStartingAtTime methods (without parameter, with animation name and with animation) to play your animation starting at the time (in seconds) desired.
    • Added SetAnimationTime method to set the animation's to the time (in seconds) you want.
    • Added UseAnimatorFPS method to override the animation's FPS.
    • Added UseAnimationFPS method to go back and use the animation FPS.
    • Added CurrentFrameRate property to get the current frame rate used by the animator.
    • Added CurrentAnimationTime property to get the current animation time in seconds.
    1.0.6
    • Added AdaptPivot to the UiImageAnimator
    • Added AnimationDuration to the SpriteAnimation
    • Added PlayStartingAtFrame without animation specified
    • Added PlayStartingAtFrame with SpriteAnimation as a parameter
    • Added AddCustomEvent with SpriteAnimation as a parameter
    • Added AddCustomEventAtEnd without animation specified
    • Added AddCustomEventAtEnd with SpriteAnimation as a parameter
    • Added GetCustomEvent with SpriteAnimation as a parameter
    • Added GetCustomEventAtEnd without animation specified
    • Added GetCustomEventAtEnd with SpriteAnimation as a parameter
    • Added PlayingAnimation proprety that returns the SpriteAnimation currently playing
    • Improved documentation
    1.0.5
    • Added Play method with an Animation as parameter to the API.
    • Improved the editor code.
    • Minor bugs solved.
    1.0.4
    • 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
    1.0.3.4
    • Solved a bug with the disable render on finish.
    • Solved some GC allocation with animators without events
    1.0.3.3
    • Solved a bug with the PlayOnAwake / OneShot / Backwards configuration.
    1.0.3.2
    • Added LoopType to the Basic Behaviours.
    • Added LoopType to the API.
    • Improved Animator Components.
    • Fixed a bug with the panning on the animation window.
    1.0.3.1
    • Fixed a bug with the SpriteAnimationAttribute drawer.
    1.0.3
    • Fixed some layout errors.
    • Fixed the horizontal panning going backwards.
    • Fixed a false warning showing that the starting frame is out of bounds when the animation only has 1 frame.
    • Added SpriteRenderer to the API.
    • CurrentAnimation returns an empty string if there's no current animation.
    • Improved the animation creation editor.
    • SpriteAnimation Attribute now refresh correctly.
    • SpriteAnimation Attribute now shows a warning if the animator has no animations.
    • Now the asset created will not be selected on the project view after doing so.
    • Removed the "animationName" field from the Animation. The asset name is now the one used.
    1.0.2.2
    • Added PlayStartingAtFrame to the API.
    • Added Panning to the animation preview window.
      • You can reset the animation preview window pressing the "F" key.
    1.0.2.1
    • Now the FPS slide saves the value between animations and if the tool is closed.
    • Solved a compilation bug with the animation attribute drawer.
    1.0.2
    • Added [SpriteAnimationField] attribute to show animation lists instead of text fields on the editor without custom editors.
    • Added Start At Random Frame to the basic behaviours inspector.
    • Added "FlipSpriteY" to the API.
    • Added "StartAtRandomFrame" to the API.
    • Added "Initialize" to the API.
    • Improved documentation.
    • Solved a bug with very similar animation names not playing correctly.
    • Solved a bug with very short animations not playing the first frame.
    • Minor refactors.
    • Updated readme.
    1.0.1.3
    • Added a new example with a simple Platformer.
    • Added the reorderable list to the SpriteAnimation asset. You can now rearrange, add or remove frames of your animations directly form its asset.
    • Added "Current Frame" to the API.
    • Solved a bug with short animations replayed without looping them.
    • Improved the serialization of the editor.
    • Encapsulated some public attributes, now privates.
    • Rearranged some folders.
    1.0.1.2
    • Now the frames will be sorted with an AlphaNumeric sort and not with an ASCII value sort.
    • Solved a bug with the last frame of the animation keeping for too long.
    1.0.1.1
    • Now the frames will be correctly sorted by name if you drop multiple textures to the drag and drop box.
    1.0.1
    • Added disable renderer on finish to the basic behaviours.​
    • Added delay between loops to the basic behaviours.​
    • Added delay between loops to the API.​
    • Improved the frame delete on the frame list of the editor.​
    • Fixed a bug that gave a null reference when the last frame of the animation was deleted​
    • Fixed a bug that caused the animation not to be selected when it was created.​

     
    Last edited: Jan 13, 2023
  3. wherewolfjohnson

    wherewolfjohnson

    Joined:
    Jan 20, 2016
    Posts:
    6
    Hi I recently bought this plugin and have a few questions/issues. I have a hard time importing images for some reason, it takes 3 or 4 tries before the sprites get recognized. When they do import they are out of order, my naming convention is File_A_0000 through FIle_A_0090 etc.

    I was also wondering if you could explain how to invoke the sprite into the scene, it outputs a *.asset file I'm not sure where to go from there.
     
  4. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi, first of all, thank you for your purchase!

    The import issue is weird, I had no problem importing them to the editor with a simple drag and drop to the sprite editor box. I'll see if it's some kind of bug. Maybe it's because they're separated textures and not a spritesheet. I'll try to improve that.

    As for the order of the sprites, if there are all on the same spritesheet it gets the order correctly, but I've seen that it doesn't works with different textures, I'll fix that on the next update ASAP.

    To start using the animations, you need to create a GameObject on your scene and add the SpriteAnimator component. There you can configure the basic behaviour of the animation (play on awake, looping, etc.) and access the API animation through code.

    If you need something more, don't hesitate to ask!

    UPDATE
    The sort issue with different textures is now solved and will be in the next update!
     
    Last edited: Apr 23, 2017
  5. killradius

    killradius

    Joined:
    Apr 4, 2014
    Posts:
    2
    I'd love to use this, but I'm having an issue with it where my animations (short, a few frames), get hung up on the last frame before looping back to the beginning. I have all the delay variables turned off / max delay set to zero. This only hapens in game, and not in the preview window.

    This is a cool solution you've built otherwise.
     
  6. Elendow

    Elendow

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

    Thanks for your feedback, that must be some kind of bug and need a solution ASAP. I'll keep you informed, it will be solved on the next update for sure!!!

    UPDATE
    It was a bug indeed. I solved it and the submission to the asset store is pending review now. I hope this solves all your problems, sorry for the inconvenience!!

    This update includes also a change on the algorithm sorting the sprites by name in order to make it alphanumeric :)

    Cheers!!
     
    Last edited: May 3, 2017
  7. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    @Elendow Could I get a video or more documentation on how the scripting part of the plugin works, so I can better understand what is included in the package?
     
  8. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi @Ben-BearFish

    Yes, I'll prepare a video and upload this weekend with some examples of code. The package includes a scene with an example of the event system usage, but I can post it here without problem:

    Code (CSharp):
    1. using UnityEngine;
    2. using Elendow.SpritedowAnimator;
    3.  
    4. public class EventExample : MonoBehaviour
    5. {
    6.     private SpriteAnimator spriteAnimator;
    7.     private ParticleSystem particles;
    8.  
    9.     private void Awake()
    10.     {
    11.         particles = GetComponentInChildren<ParticleSystem>();
    12.  
    13.         // Here we add an event to the 9th frame of the animation Slimedow
    14.         // After that, we subscribe the method "BurstParticles"
    15.         // We can also get the event with spriteAnimator.GetCustomEvent("Slimedow", 9) and suscribe whatever we want
    16.         spriteAnimator = GetComponent<SpriteAnimator>();
    17.         spriteAnimator.AddCustomEvent("Slimedow", 9).AddListener(BurstParticles);
    18.  
    19.         // Then we simply play the animation and the magic begins
    20.         spriteAnimator.Play(false);
    21.     }
    22.  
    23.     private void BurstParticles(BaseAnimator caller)
    24.     {
    25.         particles.Play();
    26.     }
    27. }
    In this code, I play an animation looped (Play(false)) and suscribe the BurstParticles to the 9th frame. So, every time the animation plays the 9th frame the BurstParticles will be called.

    As I said, I'll try to record more usage examples on a video this weekend, hope this helps in the meantime :)

    Cheers!
     
  9. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    Do you know if we can set the events in the editor inspector?
     
  10. Elendow

    Elendow

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

    It's not possible at the moment. I'm looking for a way to do it, it's on the roadmap but I don't know when I could push it to the Asset Store. Sorry for that.

    Cheers :)
     
  11. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    I made a new example where you can see simple calls to the asset API. It's a simple platformer using things like "Play", "CurrentAnimation", "FlipSpriteX"...

    The example will be included in the next version with some improvements and I recorded everything, so, you have a video in the first post with the process.

    Hope this helps!
     
  12. Sluggy

    Sluggy

    Joined:
    Nov 27, 2012
    Posts:
    989
    Hi Elendow. I recently purchased your asset and wanted to give you some feedback about it. Overall it seems nice and simple and I don't want to take away from that because that's a very strong point. However, there are a few issues that I wanted to comment on.

    1) Proprietary animation format. I was really really hoping this would use Unity's built in animation clips since that's what all of my tools (and most everyone else's) work with. I've had to shelve using this asset within minutes of purchasing it because of that (though I will like use it for my next project since I won't be so invested in animations that already exist).

    2) Strings for animation names? You really ought to be using a string-to-hash system. It allows for users to enter human-friendly strings that get converted into ints internally. This will cut down on runtime allocations significantly if you're using a lot of sprites. Though it's not hard to write one yourself I recently discovered that Unity actually has one already. Simply using the type PropertyName instead of strings for your animation names will make it a relatively simple process. Keep in mind this will likely break pre-existing projects if user upgrade.

    Anyway, thanks for this contribution to the asset store!
     
    theANMATOR2b likes this.
  13. Elendow

    Elendow

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

    Thanks a lot for your feedback, it really means a lot to me and it's the best way to improve this asset :)

    Well, point by point ^^

    1) Thats true, my target with this plugin was exactly that, I always tought that the unity animation system was too complex for simple sprite animations. If you want an animation window using the unity animation system you could try this plugin https://www.assetstore.unity3d.com/#!/content/71177?aid=1101lIr6 that is basically a reskin for the animation window oriented to sprites.

    2) Yes, that's something that I always wanted to change, but I didn't because of what you said, it will break the pre-existing projects. I'm looking for a mid-term solution that improves this and doesn't break the previous projects.

    I keep working on this asset to improve it, if I can solve this issues, I'll get in touch with you :)

    Cheers!
     
  14. Sluggy

    Sluggy

    Joined:
    Nov 27, 2012
    Posts:
    989
    You might have misunderstood me here so I just wanted to clarify: I meant that it would have been nice to use Unity's animation clips in a animator that isn't mecanim. But I won't argue the point since there are quite a few hurdles to jump through to get such a thing working and most folks just use mechanim as a backend anyway. Anyway, thanks for the response and keep up the good work.

    P.S. Wanted to point out that I did end up using this for some smaller parts in my current project. It's quite refreshing to simply be able to churn out a script in two minutes that just plays an animation. :D
     
  15. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Oh, I understand now, I never really thought in that, I'll check if I can do something with that :)

    I'm really happy that you've been able to enjoy the plugin, I'm actually using it the same way in my current work, for FX and stuff like that.

    Thanks a lot for your feedback, it really makes me happy to see that someone is using this asset and finds it usefull :)
     
  16. Crystan

    Crystan

    Joined:
    Oct 11, 2014
    Posts:
    20
    Hi!
    I thought i might share a little script I wrote for SpriteDow:

    I have a lot of objects that use the same animations with the exact frame count and timing but of course with different sprites. It became quite annoying to copy the animations and replace each frame manually. So I wrote a script that allows you to replace frames of multiple animations, as long as the sprites of the animations you want to replace are all located in the same folder.

    Example:
    Old Frames:
    [OLDsprites\jumpAnimation.asset]
    OLDsprites\jump1.png
    OLDsprites\jump2.png

    [OLDsprites\shootAnimation.asset]
    OLDsprites\shoot1.png
    OLDsprites\shoot2.png

    Replaced Frames:
    [NEWsprites\jumpAnimation.asset]
    NEWsprites\jump1.png
    NEWsprites\jump2.png

    [NEWsprites\shootAnimation.asset]
    NEWsprites\shoot1.png
    NEWsprites\shoot2.png

    All you have to do is to add the script to a empty game object, make a copy of all animations you want to replace to another folder (or in whatever way you organize your animations) and put all animations you want to replace into the list of the script.

    Now open the context menu of the script (the small gear in the upper corner of the script in the inspector window) and select "Replace Frames". The context option "Get current image path" allows you to get the sprite path of the current animations, so its easier to replace animations which share the same root path.

    I recommend to make a few test to get how it works. I doubt it can harm your animations in anyway, the only thing that might happen afaik is that you have a mixture of new and old frames IF you didn't use the script in the correct way.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Elendow.SpritedowAnimator;
    5.  
    6. #if UNITY_EDITOR
    7. using UnityEditor;
    8. #endif
    9.  
    10. public class cs_spriteDowAnimationTool : MonoBehaviour
    11. {
    12. #if UNITY_EDITOR
    13.     [Header("All frames in all animations present in the list have to share the same folder")]
    14.     public List<SpriteAnimation> anim;
    15.     [Header("Source Image Path")]
    16.     public string imagePath;
    17.  
    18.     [ContextMenu("Get current image path")]
    19.     public void getInfoFromCurrentAnimation()
    20.     {
    21.         if (anim.Count > 0)
    22.         {
    23.             if (anim[0].Frames.Count > 0)
    24.             {
    25.                 imagePath = AssetDatabase.GetAssetPath(anim[0].Frames[0]);
    26.                 imagePath = imagePath.Replace(anim[0].Frames[0].name + ".png", "");
    27.             }
    28.             else
    29.             {
    30.                 Debug.Log("No Frames found");
    31.             }
    32.         }
    33.         else
    34.         {
    35.             Debug.Log("No Animations found");
    36.         }
    37.     }
    38.     [ContextMenu("Replace Frames")]
    39.     public void replaceInfoFromCurrentAnimation()
    40.     {
    41.         if (anim.Count > 0)
    42.         {
    43.             foreach (var dowAnims in anim)
    44.             {
    45.                 if (dowAnims.Frames.Count > 0)
    46.                 {
    47.                     if (imagePath != "")
    48.                     {
    49.                         for (int i = 0; i < dowAnims.Frames.Count; i++)
    50.                         {
    51.                             if (AssetDatabase.LoadAssetAtPath(imagePath + dowAnims.Frames[i].name + ".png", typeof(Sprite)) as Sprite)
    52.                             {
    53.                                 Sprite newFrame = AssetDatabase.LoadAssetAtPath(imagePath + dowAnims.Frames[i].name + ".png", typeof(Sprite)) as Sprite;
    54.                                 dowAnims.Frames[i] = newFrame;
    55.                             }
    56.                             else
    57.                             {
    58.                                 Debug.Log("Image Name/Folder >>>" + imagePath + dowAnims.Frames[i].name + ".png" + "<<< is not the same/not present");
    59.                             }
    60.                         }
    61.  
    62.                     }
    63.                     else
    64.                     {
    65.                         Debug.Log("No image Path set");
    66.                     }
    67.                 }
    68.                 else
    69.                 {
    70.                     Debug.Log("No Frames present");
    71.                 }
    72.             }
    73.         }
    74.         else
    75.         {
    76.             Debug.Log("No Animator Source selected");
    77.         }
    78.     }
    79. #endif
    80. }
    81.  
     
    theANMATOR2b likes this.
  17. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Woah, nice one @Crystian!

    Never tought that someone would need that, but this trick is really cool. You could improve it using an EditorWindow, that way you don't need a GameObject on the scene to execute your code.

    I'm glad you're using the asset and improving it, it's really cool, seriously.

    Cheers!
     
    Crystan and theANMATOR2b like this.
  18. hjupter

    hjupter

    Joined:
    Dec 23, 2011
    Posts:
    628
    Can this play multiple animations at the same time? I mean I have a multisprite character (head, body, weapon) and I would like to play those 3 animations at the same then for example replace the sword animation for the axe animation.
     
  19. hjupter

    hjupter

    Joined:
    Dec 23, 2011
    Posts:
    628
    I just realized this doesnt make much sense since this works with one sprite renderer so I would need to use 3 different components one for each.
     
  20. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Yeah, that's exactly what I was gonna tell you. BUT, I could make a "PlayAnimationFromFrame". That way you could play the axe animation starting where the sword animation was.

    Tell me if that could be useful to you and I'll try to add in the next update :)
     
  21. Crystan

    Crystan

    Joined:
    Oct 11, 2014
    Posts:
    20
    The UnityEditor gui code seems always way to inconvenient to me, so I never have the motivation to get into it. ;)

    In my project i have also a multi layered character and I wrote a script that calls every object at once. You can either create a list or individual variables for each multisprite/object, so you don't have to get rid of the missing objects in the list when you switch weapons.
     
  22. Elendow

    Elendow

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

    New versión released with minor changes:
    • Added PlayStartingAtFrame to the API.
    • Added Panning to the animation preview window.
      • You can reset the animation preview window pressing the "F" key.

    Feel free to suggest more improvements :)
     
    Crystan likes this.
  23. Crystan

    Crystan

    Joined:
    Oct 11, 2014
    Posts:
    20
    Thanks for the update. :)

    Since you've asked, I've actually got a suggestion:

    What do you think about the option to change the layer order and maybe even the actual layer per frame? It would be also neat if you'd have the option to not only set the order to a certain value but also to subtract/add the set order value to the current order value of the sprite renderer.

    I know this suggestion is quite specific and actually based on a "issue" I've encountered in my current project, so I would understand if you're not interested in adding it. In that case I would still be able to add that feature through the animator extension script I wrote to counter game/engine related problems. ;)
     
  24. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi!

    Thats a quite interesting suggestion and relatively easy to implement, I'll see how I can fit on the Animation Window :)

    I've added this on my roadmap!
     
    Crystan likes this.
  25. erlioniel

    erlioniel

    Joined:
    Aug 31, 2015
    Posts:
    8
    Hi @Elendow !

    Thank you for the asset, I have some feedback for you :)

    1. There is a small issue with inverted axises in animation preview.
    2. A zoom limitation in the preview window isn't good for my current use case. I'm working with pixelart and have to zoom 300%+ that isn't possible in most cases
    3. Also it might be useful to add some kind of state machine to work with states instead of animations. Maybe later I will try to make something like that. In this case I will try to share.

    But anyway your asset is awesome and save a lot of time for me! Thank you again for sharing
     
  26. Elendow

    Elendow

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

    Thanks for your feedback! I'm going to check the 1 and 2 issues and I'll try to fix them for the next update :)

    Regarding the third issue, the target of Spritedow is exactly that, avoid state machines. If you need something like that, with transitions and all, you could use Mechanim instead :)

    Cheers!
     
    Crystan likes this.
  27. erlioniel

    erlioniel

    Joined:
    Aug 31, 2015
    Posts:
    8
    Hello again. Found another major issue related to the repeating animations: Update function doesn't change a sprite to the first frame when reseting animation. As a result the first frame is always missing in repeating animation.
     
  28. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Well, that's a big issue. I'll try to solve it this ASAP and send an update later this weekend. With the update I'll include your previous feedback.
     
    Crystan likes this.
  29. Elendow

    Elendow

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

    Sorry for the late response on the lastest issues, I was very bussy at work and had some problems with internet at home...

    But version 1.0.3 has ben submited to the Asset Store and is waiting approval, here's the change log:

    - Fixed some layout errors.
    - Fixed the horizontal panning going backwards.
    - Fixed a false warning showing that the starting frame is out of bounds when the animation only has 1 frame.
    - Removed the "animationName" field from the Animation. The asset name is now the one used.
    - Added SpriteRenderer to the API.
    - CurrentAnimation returns an empty string if there's no current animation.
    - Improved the animation creation editor, prettier, simpler.
    - Improved the zoom on the animation preview window (now you can zoom to nearest and farthest planes).
    - SpriteAnimation Attribute now refresh correctly without having to select/deselect the animator object.
    - SpriteAnimation Attribute now shows a warning if the animator has no animations.
    - Now the asset created will not be selected on the project view after doing so.

    Thanks to everyone giving feedback and helping me to improve the plugin, you make this possible.

    Also, the first 'big' game using Spritedow Animator is being released soon on consoles!
    I'm talking about Agatha Knife, dropping on Nintendo Switch on April 26th and on Xbox One on April 27th :)

     
  30. erlioniel

    erlioniel

    Joined:
    Aug 31, 2015
    Posts:
    8
    Hi @Elendow,

    First of all congratulations with the release! It looks amazing! Hope I will release my... khm... project at some point too :)

    Actually I think that it will be really hard to update the library for me.

    First of all about compatibility. Version 1.0.3 means that the migration from 1.0.2 will be painless, because only some minor fixes without API changes will be in the release. At least that was my assumings, because of semantic versioning (https://semver.org/) used by most of mature projects.

    In my case this change with asset names is the reason why I should refactor a huge part of my project to migrate. The reason is that I was using the name field in animation as a type of it. For example I have two objects and two animation assets called object1_idle and object2_idle. But both of them contain "idle" as name and I was able to use them from the same script.

    Also I've noticed a lot of strange design decisions in the library. For instance if we have animation asset why we should add it to some component list manually to play it programmatically? And why we are playing string (name of asset) instead of asset itself? Also there is good option to add start animation and set random animation flag, but there is no option to add default animation.

    So I'm not blaming, your library is cool enough and helped me a lot. I will still use it without update and will leave my 5 star review in asset store and add some additional notes about limitations. Also I'm hoping that you will improve the library and I will be able to update it later.
     
  31. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi erlioniel and thanks for your feedback, I really appreciate it.

    First of all, I don't think your code with the animations is working correctly. My asset searches the animations on the list using the name, if two equal names are in the list the search algorithm will find only one, always the same. If you play your "idle" animation the animator will find only the first on the list, and the second one will never be called.

    Now the strange decisions :) I've used strings to call the animations in order to improve the search on the list. Probably not the best idea, that's true, but its pretty easy to use and make custom inspectors for it, and my idea was always do something simple and easy to use. Maybe I try to do something better, I'm all ears :)

    The animation list on the inspector is made that way in order to make easy to add an animator to an object without using code, that's something my designer uses a lot. But you can add the animations programmatically with the Initialize method. That way you can initialize the animation list and the basic behaviours of the animator without using the animation list of the inspector.

    You're completely right, I could add a Play with an animation reference instead of a name. That's possible.

    For the default animation, I see the starting animation has the default one. If you are talking about an animation that plays automatically when no animation is playing... I can add something like that.

    Again, thanks a lot for your feedback, I'm always eager to improve this and make a better asset for you all.

    Cheers!
     
  32. erlioniel

    erlioniel

    Joined:
    Aug 31, 2015
    Posts:
    8

    My example wasn't clear, I will try to describe a bit more.

    So I have two actors (for example Cat and Dog) with different sprite sheets (cat.png and dog.png) and different idle animations (cat_idle and dog_idle). Before I was able to create only one controller (AnimalController) and play animation using SpriteAnimator.Play("idle").

    I know that only the first animation (if names will be the same in the same list) will play, that's obvious :) But that is not the case.

    The idea behind default animation is correct, I can share small code changes that I've made to support that (usualy used for idle animation in my case).

    I will say that good option might be to create a dictionary string => asset reference as animation list. In this case user will be able to add animations manually, add them by script and at the same point library will support Play by reference option.
     
  33. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Oh, I understand now. My advice is not to "hardcode" strings, that causes more GC Alloc because C# creates a new string everytime. You can add a field called "IdleAnimation" and use the SpriteAnimationAttribute to choose which animation you want in your AnimalController inspector. You have an example of that in the PlatformerExample.

    I'll try to add the default animation and improve the animation system to include more possibilities.

    Thanks again for your feedback, that would help me to improve this A LOT.
     
  34. Nikita500

    Nikita500

    Joined:
    Aug 18, 2015
    Posts:
    67
    Hi,Ty for plugin. Why sprite looks dark in Sprite Animator preview compare to sprites in asset folder / cant see animation:) My unity is 2018.2.0f2 personal
     

    Attached Files:

    Last edited: Jul 19, 2018
  35. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Wow, that's an issue I wasn't aware of. In which SO are you working?
     
  36. Nikita500

    Nikita500

    Joined:
    Aug 18, 2015
    Posts:
    67
    Sorry what is SO ? if operating system- im on windows 10:)
     
  37. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Lol, yes, sorry, I typed OS in spanish.

    Ok, I'm going to check what is happening and try to solve ASAP. Sorry for the inconvenience.
     
  38. Nikita500

    Nikita500

    Joined:
    Aug 18, 2015
    Posts:
    67
    Np.its dont inconvenience me. Scripting part is working as i wanted and very helpful. Ty :)
     
  39. Elendow

    Elendow

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

    I managed to reproduce that "dark" effect on the preview setting the Color Space to Linear on the Player Settings. The preview should work as intended if you set that to Gamma. The same bug occurs on some Unity Assets (the Tilemap Editor, for example) so I asume is something intended.

    Hope this helps you with the issue.

    Cheers!
     
  40. Nikita500

    Nikita500

    Joined:
    Aug 18, 2015
    Posts:
    67
    Ye thank you ,its working now :)
     
  41. me_gone_mad1

    me_gone_mad1

    Joined:
    Feb 2, 2018
    Posts:
    9
    hi just got it, looks cool. don't suppose it comes with a tool to bulk import images laid out in the same way. a lot of the sprite ill be using will follow the same format eg all the sprite sheets conform to sprite 1-10 is the animation for x then 11 - 20 is for y.

    perhaps a tool that takes a bunch of unity sprite sheets and a json file that describes the structure to be imported

    something like:
    Code (JavaScript):
    1. {
    2.     "animation1":[
    3.          {"sprite":0, "duration":1},
    4.          {"sprite":1, "duration":1},
    5.          {"sprite":2, "duration":1},
    6.          {"sprite":3, "duration":1},
    7.          {"sprite":4, "duration":1},
    8.          {"sprite":5, "duration":1},
    9.          {"sprite":6, "duration":1},
    10.          {"sprite":7, "duration":1},
    11.          {"sprite":8, "duration":1},
    12.          {"sprite":9, "duration":1},
    13.          {"sprite":10, "duration":1}
    14.     ]
    15. }
    Thanks
     
  42. me_gone_mad1

    me_gone_mad1

    Joined:
    Feb 2, 2018
    Posts:
    9
    I had a Bash at making it, my editor fu is not amazing but it seems to work.
    feel free to steal/improve

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using UnityEditor;
    5. using UnityEngine;
    6. using System.IO;
    7.  
    8. public class ImportSpriteSheet : Editor
    9. {
    10.     [MenuItem("Assets/Create/Import_Sprite_Sheet")]
    11.     public static void BulkImportSpriteSheet()
    12.     {
    13.         if (Selection.activeObject != null)
    14.         {
    15.             List<Texture2D> sheets = Selection.objects.OfType<Texture2D>().ToList();
    16.             string jsonFilePath = EditorUtility.OpenFilePanel(
    17.                 "import Settings",
    18.                 AssetDatabase.GetAssetPath(Selection.activeObject.GetInstanceID()),
    19.                 "*.*"
    20.                 );
    21.             Debug.Log(jsonFilePath);
    22.             if (jsonFilePath == null || jsonFilePath == "")
    23.             {
    24.                 return;
    25.             }
    26.             System.IO.StreamReader SR = new StreamReader(jsonFilePath);
    27.             SpriteAnimationConfig config = JsonUtility.FromJson<SpriteAnimationConfig>(SR.ReadToEnd());
    28.             SR.Close();
    29.             SR.Dispose();
    30.             if (config == null)
    31.             {
    32.                 return;
    33.             }
    34.             foreach (var s in sheets)
    35.             {
    36.                 string spriteSheet = AssetDatabase.GetAssetPath(s);
    37.                 string sheetname = Path.GetFileNameWithoutExtension(spriteSheet);
    38.                 string superfolder = "Assets/Animations";
    39.                 string newFolderPath = Path.Combine(superfolder, sheetname);
    40.                 if (!AssetDatabase.IsValidFolder(newFolderPath))
    41.                 {
    42.                     string guid = AssetDatabase.CreateFolder(superfolder, sheetname);
    43.                     newFolderPath = AssetDatabase.GUIDToAssetPath(guid);
    44.                 }
    45.                 List<Sprite> sprites = AssetDatabase.LoadAllAssetsAtPath(spriteSheet)
    46.                     .OfType<Sprite>().ToList();
    47.                 foreach (var animation in config.animations)
    48.                 {
    49.                     var a = ScriptableObject.CreateInstance<Elendow.SpritedowAnimator.SpriteAnimation>();
    50.                     a.Frames = animation.frames.Select(o => (sprites.Count > o.frame) ? sprites[o.frame] : null).ToList();
    51.                     a.FramesDuration = animation.frames.Select(o => o.duration).ToList();
    52.                     a.FPS = config.fps;
    53.                     AssetDatabase.CreateAsset(a, Path.Combine(superfolder, sheetname, animation.name+".asset"));
    54.                 }
    55.  
    56.             }
    57.         }
    58.     }
    59. }
    Code (CSharp):
    1. using System.Collections.Generic;
    2.  
    3. [System.Serializable]
    4. public class SpriteAnimationConfig
    5. {
    6.     public int fps;
    7.     public List<AnimationStructure> animations;
    8. }
    Code (CSharp):
    1. using System.Collections.Generic;
    2.  
    3. [System.Serializable]
    4. public class AnimationStructure
    5. {
    6.     public string name;
    7.     public List<FrameInfo> frames;
    8. }
    Code (CSharp):
    1. [System.Serializable]
    2. public class FrameInfo
    3. {
    4.     public int frame;
    5.     public int duration;
    6. }
     
  43. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi me_gone_mad1, I'm glad you managed make it yourself! I've done some scripts very similar to yours for a project, but I never included them to the plugin because they're very specific to my needs. But I've made the API accesible to everyone to make things like your easier to do.

    If you need something to improve your tool, feel free to ask!
     
  44. me_gone_mad1

    me_gone_mad1

    Joined:
    Feb 2, 2018
    Posts:
    9

    well I'm bulk importing as i plan to add them to a scriptable object as they are made, that way i can make a factory prefab and pass the whole set in as one object, meaning to go from an image to an npc has as few steps.
    so far i have it down to:
    1) split sprite sheet
    2) bulk-import animations into a npc args scriptable object
    3) add a new npc prefab to the scene and give it the above scriptable object.

    can you see any quick wins to reduce this loop? or better ways to achieve the above script? make it more user friendly?
    editor scripts are still magic to me, getting the json file above i ended up relying on system as i couldn't get a textasset to load from the assetdatabase.

    Thanks :)
     
  45. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hum, you could use OnPostprocessAllAssets to automatize de process inside Unity and generate the animations every time you import a texture and a json together.

    Code (CSharp):
    1.     private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
    2.     {
    3.         List<TextAsset> jsons = new List<TextAsset>();
    4.         List<Texture2D> textures = new List<Texture2D>();
    5.  
    6.         foreach (string assetName in importedAssets)
    7.         {
    8.             if (assetName.Contains(".json"))
    9.             {
    10.                 TextAsset jsonAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(assetName);
    11.  
    12.                 if (jsonAsset != null)
    13.                     jsons.Add(jsonAsset);
    14.             }
    15.             else if(assetName.Contains(".png"))
    16.             {
    17.                 Texture2D textureAsset = AssetDatabase.LoadAssetAtPath<Texture2D>(assetName);
    18.  
    19.                 if (textureAsset != null)
    20.                     textures.Add(textureAsset);
    21.             }
    22.  
    23.             // Generate your animations like you do in your editor window!
    24.         }
    25.     }
    Remember to use the "userData" on your importer object to flag it as imported, or you'll create an animation everytime you reimport that asset.

    Hope this helps :)
     
  46. me_gone_mad1

    me_gone_mad1

    Joined:
    Feb 2, 2018
    Posts:
    9
    that's a good plan. thanks
     
  47. Khakimov

    Khakimov

    Joined:
    Aug 23, 2015
    Posts:
    2
    Thank you for plugin!
    Has anyone next problem: Adding new frame produce an error "Assertion failed: Unsupported render texture format :48" ?
     
  48. Elendow

    Elendow

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

    I can't reproduce your error, can you show me the import settings of the texture you used?
     
  49. Khakimov

    Khakimov

    Joined:
    Aug 23, 2015
    Posts:
    2
  50. Elendow

    Elendow

    Joined:
    Apr 9, 2014
    Posts:
    87
    Hi, I'm very sorry for the late reply. I've trying to reproduce this without luck. The only thing that comes to mind is that something is wrong with the texture itself...

    Could you try with multiple textures and see if something pops out?

    Thanks for your patience.