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. 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

Official 2D Animation 7.0 released for Unity 2021.2

Discussion in '2D' started by rustum, Oct 25, 2021.

  1. Upp000

    Upp000

    Joined:
    Mar 4, 2021
    Posts:
    52
    imagine if I build a game like vampire survivor, there will be so many enemies in the screen.
     
  2. Ted_Wikman

    Ted_Wikman

    Unity Technologies

    Joined:
    Oct 7, 2019
    Posts:
    786
    @PBKitty thank you for your feedback on both the Sprite Library flow and the Sprite Resolver. Regarding the Sprite Library flow, I would like to ask the same question to you as I did to PanthenEye;

    All of this information helps us understand and prioritize improvements to our 2D toolsets. It also helps us create better internal repro cases, so we can walk similar pipelines to experience the issues first hand.

    @Upp000 do let us know if you experience any issues with the current implementation, and we can take a closer look at it with more use case details at hand.
     
  3. EvOne

    EvOne

    Joined:
    Jan 29, 2016
    Posts:
    172
    "but it is absolutely not a replacement for the removed functionality. It isn't the same as just being able to have everything set up in the art file and set up with a single click."

    "Bingo. It is a lot like if you told 3d devs that they'd now have to manually drag and drop skeleton bones into each imported mesh, or something equally absurd."

    Yes! Absolutely!
    Thank you for the extremely accurate wording!
    All that I can’t explain to the developers for several years.

    -Do not force us, please, every time do everything manually from scratch!
    The Idea of converting groups and layer names to Categories and Labels, in the functionality that was cut out new versions of the package
    -was almost perfect!
    And no "drags and a drop" do not replace this.
     
  4. PBKitty

    PBKitty

    Joined:
    Dec 23, 2021
    Posts:
    39
    ...that is brilliant.
     
    EvOne likes this.
  5. PBKitty

    PBKitty

    Joined:
    Dec 23, 2021
    Posts:
    39
    Ok, so, imagine that you have the fairly typical example of a character that uses sprite libraries for the eyes, mouth, and each hand- so four groups, each with a bunch of variants. In my art software(in my case Photoshop), I can create a group for each of these, and then in unity(with 5.x sprite editor) I select each group and convert it to a library.

    It is very fast and easy; everything is named correctly. And, importantly, I can take art from someone else and as long as they followed the correct workflow I can one-click convert their layer groups to sprite libraries, too.

    So not only does it save a lot of pointless manual work, but it also makes it much easier to collaborate.
     
    EvOne likes this.
  6. alexlamar

    alexlamar

    Joined:
    Jan 16, 2014
    Posts:
    7
    Hi! I'm running into a bug with the replaced broken/constant tangent behavior in the animator for the Sprite Resolver component. Apologies if there is a better place to post this, but I didn't see a pre-release thread for the version I'm using (9.0.0-pre.3)

    Before version 8.00, we would animate the Sprite Resolver's Category/Label hash by keying it in the animator and then settings the key's tangents to Broken/Constant, to prevent interpolation between hash values. This should be done automatically for us now in 8.0.0+, but I am now running into an issue where certain spriteresolver hash values in my animation will swap on a frame even when there is no key set in the animation, indicating some kind of interpolation issue.

    Attaching screenshots that highlights this. Note that the hash for "Head.RGBA: Sprite Resolver.SpriteKey" swaps from 1228760 to 103200 on frame 26 even though it shouldn't key in the animation until frame 33.

    Screen Shot 2022-07-30 at 8.59.35 PM.png Screen Shot 2022-07-30 at 8.59.52 PM.png

    I also filed a bug report! The case # is IN-11884
     
    Last edited: Jul 31, 2022
    EvOne likes this.
  7. Ted_Wikman

    Ted_Wikman

    Unity Technologies

    Joined:
    Oct 7, 2019
    Posts:
    786
    Thanks for flagging this issue @alexlamar.
    It is partially true that you do not need to set key's tangents to Broken/Constant in 2D Animation 8.x and newer versions. In 2D Animation 8.x we introduced a new property to fix the Broken/Constant issue prior 2D Animation versions had. This new property is called SpriteHash and will be automatically used when you key new Sprite Resolver frames in 2D Animation 8.x and newer. If you have Animation Clips made in past 2D Animation versions, you can use our new
    2D Animation Asset Upgrader to upgrade these clips to use the new property. Before upgrading your clips, please make sure you have a backup of the clips, so that you can revert if anything goes wrong.

    Let me know if this solves your issue!
     
  8. alexlamar

    alexlamar

    Joined:
    Jan 16, 2014
    Posts:
    7
    Thank you, Ted! I must have missed the new tooling, but I'm glad that you guys included it. The animation upgrader is going smoothly, I'll update you if I run into any additional problems :)
     
    MarekUnity and Ted_Wikman like this.
  9. GamerXP

    GamerXP

    Joined:
    Mar 22, 2014
    Posts:
    65
    Hello. I was messing with sources of animations packages for a while myself, but it became a huge hassle to try to keep it up to date due to all merge conflicts. I thought maybe I should just request that as features instead. It does not work with new batching system anymore as well.

    Basically, it will be great to have extra settings in SpriteSkin components: offset (Vector2), scale (Vector2), flip (int). It's possible to do the same with extra child bones, but it's such a hassle to do that every time and it looks really messy. Those transformations should happen in relation to either root bone, or some extra transform field you define.

    1. Flip feature is really important since I need that a lot when animating stuff. There are flip flags in SpriteRenderer, but they do not work correctly - they flip image in relation to object's root or something, but you usually want to flip in relation to root bone.
    2. There are surprisingly a lot of cases when you want to scale/offset/flip ONLY current sprite, while not affecting it's children - it's pretty hard to do when you have than as child transforms. Those settings help a lot here.
    3. Flip I suggested is int because animator blends bool values as "True as long as transition lasts", while it should be "Changes value in-way". I reported this as a bug, like, 5 years ago, but nothing happened as usual.

    It may not be something in the inspector either - may add some public method for SpriteSkin to load additional transformation matrix so I can make my own extra component to do so.

    Edit:
    How it looked with my changes:

    https://gyazo.com/a70cc3879b90a2ce843c1a683104ec76
    I think it was made in one of the first versions of the package.
     
    Last edited: Aug 22, 2022
    LilGames and EvOne like this.
  10. MarekUnity

    MarekUnity

    Unity Technologies

    Joined:
    Jan 6, 2017
    Posts:
    162
    Hi @GamerXP
    This thread is definitely a good place to share feedback and request features!

    Thanks for sharing this. I think your points make perfect sense and I'll share them with the rest of 2D animation team
     
    GamerXP likes this.
  11. MarekUnity

    MarekUnity

    Unity Technologies

    Joined:
    Jan 6, 2017
    Posts:
    162
    @GamerXP a quick clarification on this point:

    Sprite Renderer flips sprite's mesh based on its pivot position. When using Sprite Skin, deformation is performed first, and then Sprite Renderer flips the X/Y axis before rendering hence the behaviour you're experiencing.

    Could you share some concrete examples of when you apply scale/offset/flip in your animation? For example: turn character head to look left-right. I can imagine that in this kind of situations you would also want to flip the bones that are influencing that sprite?
     
  12. GamerXP

    GamerXP

    Joined:
    Mar 22, 2014
    Posts:
    65
    1. Well, it's just that you often don't want this behaviour when using SpriteSkin. At least I can't imagine me needing this instead of flipping along root bone's axis. Anyhow, this one is a bit hard to use in animations because it has bool-type blending, which works incorrectly.

    2. Hmm.. project where I tested it the most does not load for now, but from what I can remember... For example, you want leg to rotate so feet faces inwards. And you want it to properly translate from outwards-facing to inwards-facing. If I flip the main leg bone - it will also flip child bones, forcing you to rotate those bones to match previous positions. Also, sometimes I want to scale arm or leg by X axis so they appear shorter. Scaling the bone will make child bones look distorted if they are also rotated.
     
    Last edited: Aug 24, 2022
    MarekUnity likes this.
  13. SudoCat

    SudoCat

    Joined:
    Feb 19, 2013
    Posts:
    39
    Howdy! I'm working on some sprite keyframed animation heavy stuff right now, the SpriteLibrary and Resolver workflow is simplifying a lot of my process, however it certainly has its ... quirks. I'm using Unity 2021.3.6f1 LTS with 2D Animation Package 7.0.7

    The most glaring issue I've ran it to has me questioning my own sanity, as I don't seem to find any other people encountering this problem.

    Setting up AnimationClips using the SpriteResolver completely breaks the curves view of the Animation window.

    upload_2022-8-25_10-30-35.png

    Sure, it's keyframed animation, I don't often need the curves view - but I don't think that means causing the editor to explode in errors is an acceptable problem to have with one of Unity's own packages, in a supposedly stable version, within an LTS editor?

    As far as I can gather, this is happening because the float based hashes produced by the SpriteLibrary are absurdly small (e.g. `-1.4877e-09`)

    The thing that further compounded by confusion was when I was poking around inside the SpriteResolver, I see that it looks like the float hashes are only used for the animation window, and the code primarily seems to be converting them to ints for lookups, which presumably wouldn't have this problem to begin with?

    So, uhhh, have I lost the plot, am I missing something, or is this just a big ol' weirdness I should just... live with?

    ---

    While we're here, are there any plans to make more of the 2D tools APIs public? I've been wanting to extend various features to better support a keyframe workflow, such as extending the PSD importer, or adding additional editor windows, but my progress is being majorly hampered by every single method, class, struct being marked internal. It's not like internal truly blocks anything from being used anyway, I've just resorted to some diabolical reflection to achieve what I wanted, without rewriting the entire PSD importer, but it's far from ideal. Similar problems when trying to dynamically generate AnimationClips, the SpriteLibraryAsset.GetStringHash methods aren't public, so it's needlessly difficult to work with.
     
    Last edited: Aug 25, 2022
    EvOne and LilGames like this.
  14. rustum

    rustum

    Unity Technologies

    Joined:
    Feb 14, 2015
    Posts:
    189
    DragonCoder likes this.
  15. SudoCat

    SudoCat

    Joined:
    Feb 19, 2013
    Posts:
    39
    but what if we're on LTS and can't use 8.0 :(
     
    EvOne likes this.
  16. Ted_Wikman

    Ted_Wikman

    Unity Technologies

    Joined:
    Oct 7, 2019
    Posts:
    786
    Hello @SudoCat
    No worries, keep posting in this thread if you like. We are just unsticking the thread to make room for the latest verified version of 2D Animation in the top of the 2D forum.

    On to your questions!
    Regarding the APIs, we tend to keep APIs internal by default. This makes it easier for us to make sure that the API surface areas are well tested. We can also make changes faster if the APIs are internal, as we only need to verify with our colleagues if we wish to make breaking changes to the APIs. However, we are always interested to know if there are any APIs you wish us to turn public. Do let us know which APIs and what you intend to use them for, so we can take them into consideration.

    The second question is a bug. Sometimes those manage to sneak into LTS versions of the editor, unfortunately. Please file a bug report so that we can pass it along.

    Thank you for the feedback!
     
    SudoCat likes this.
  17. SudoCat

    SudoCat

    Joined:
    Feb 19, 2013
    Posts:
    39
    Thanks so much for the update!

    This does make sense, although I'm sure I'll still grumble every time I hit an internal I wanna play with. I'll run through some of the use cases I've got, and how I'm dealing with the situation.

    Extending the PSD Importer
    This was one of the big ones. I wanted to add some additional functionality to make the PSD Importer more useful for importing keyframed animations, providing a simpler way of managing our animations. Our animations are made of layered sprites. We want one PSB to equal one clip. This results in a whole lot less sprites hanging around in the project, and makes it much easier to update a single clip.

    In order to achieve this, I created two additional classes, one to extend the PSDImporter, and one to extend the PSDImporterEditor. I needed to display additional settings on the object Inspector, to configuring Animation Clip and Sprite Library generation.

    Ideally, I didn't want to generate the character prefabs when importing PSBs. These files were never used in our project, so seemed a distraction. We also do not use the SpriteSkin system, so in theory I should have been able to simply disable the "use as character" checkbox, add a new checkbox for clip generation, and then I could go about generating clips.

    Unfortunately, it was very difficult to generate clips from the data available to me. I needed to know what sprites resided in which layer groups, and the position offsets used to match them to their positions in the PSB. Most of this data was stored on the internal classes, UnityEditor.U2D.PSD.PSDLayer class, and UnityEditor.U2D.PSD.SpriteMetaData. The properties for storing the PSDLayer classes are all internal. Most frustratingly, this method is exposed to data providers, but the raw output is not available anywhere. Even more frustratingly, the SpriteMetaData was even closer, but still out of reach. The PSDImporter implements ISpriteEditorDataProvider.GetSpriteRects, which when debugging I could see returned SpriteMetaData, but as the class is internal, I was unable to access any of its properties without reflection. The PSDImportData could have also proved helpful, but is also internal.

    This made it incredibly difficult to access any information about the PSD itself, or the layers output from it. In the end, I resorted to a system where I leave the character generation enabled, and then I read those prefabs to access the transform offset positions. Not ideal, but functional.

    The next roadblock was extending the editor. It was here I did decide my only viable option was to resort to some very dubious reflection. The last thing I wanted was to re-implement the entire Inspector pane, however all of the layout functionality is internal. However, the Editor implements a fairly straight forward tabbing system. Here's where the fun begins.

    The tabs rely on a nested struct, UnityEditor.U2D.PSD.PSDImporterEditor.InspectorGUI, which is then used in an array. However, this only configures what callback to execute when the tab is active. The tabs themselves are managed by a readonly property inside the nested Styles class.This left me with no other alternative, I had to resort to lots of very hacky reflection, which is quite unreliable, and will almost definitely break with updates.

    I don't think making those Editor APIs public is the solution of course (maybe the struct). However, I feel it would be incredibly helpful to have a public API to allow adding additional tabs, so we could extend the PSD importer without losing the existing functionality.

    So that's about it for Case Study 1: Extending the PSB importer. These other projects are pipe dreams which I'm yet to thoroughly investigate, as I saw lots of immediate limitations. They consequently, won't have the same level of detail (so should save you some time reading them :oops:)


    - SkeletonTool and associated code is internal. I would have liked to make some extensions to this to aid in generating pivot data for keyframed sprites, without having to utilise SpriteSkinning (which seems a bit overkill when I'm not using mesh deformation). I had hoped to also add my own SpriteEditorModule for previewing and editing clips, such as their timings, but this ultimately proved far too difficult to be worth the time investment at this stage.

    - Editor Styles. There's so many little internal editor styles and UI utilties everywhere, which would be incredibly useful to have access when extending the editor. For my PSDImporterEditor extension, I ended up needing to copy and InspectorUtils.DrawHeaderFoldout into my project. However, In the end it proved preferable anyway, as I needed additional feattures, and the hasMoreOptions argument has not been implemented in this version.

    - Most properties of the PSDImporter are also set to private/internal. This means that derived importers can't read the settings of the base importer. My custom importer requires some specific settings to be enabled in the base, but I can't check for them from my OnImportAsset implementation.

    ---

    Now I'll go report that bug, thanks again for your response, and I hope some of my long rambly feedback is useful.
     
    Last edited: Aug 30, 2022
    EvOne likes this.
  18. Ted_Wikman

    Ted_Wikman

    Unity Technologies

    Joined:
    Oct 7, 2019
    Posts:
    786
    Thanks a lot for that write-down @SudoCat. We have many developers doing all sorts of custom implementations, serving their special needs, so understanding what you are doing and where you had difficulties helps us create better solutions in future versions of Unity.

    It is interesting to hear that you are using psd files, where each layer is a frame in a flipbook animation. What makes this a preferred way of working compared with a "flat" .png spritesheet? This is also something we can look at adding as a feature request to PSD Importer, as we would like to improve our flipbook animation offering in Unity.

    I can also understand that you had a lot of issues extending both PSDImporter and its editor, as we haven't looked into making it extensible for outside usage, at all. But good to know, so that we can consider updating it in future.
     
    SudoCat likes this.
  19. SudoCat

    SudoCat

    Joined:
    Feb 19, 2013
    Posts:
    39
    Before I get into the Big Long Rambling Description™, I'd say that to really improve flipbook animation within Unity, there are some small quality of life improvements that would make a big difference:
    • Project wide setting to change default AnimationClip behaviour to constants instead of smooth curves
    • Project wide setting to change Animator's to stop applying blends to transitions
    • Animation Blend Trees without the blending? Something to make it easier to sync run->walk frames, without interpolating between them
    Easier said than done of course, but a lot of weird bugs appear when I forget to flatten a curve, or remove a transition offset, even more so when using SpriteResolvers.

    The flipbooks are multi-layered, the traditional separate layers for arms to allow playing action animations over the top of movement animations. Our character animations are drawn in Clip Studio, and then exported out as the PSBs.

    Using the PSD importer makes it slightly easier to compose the clips:
    • The PSD importer will automatically extract each layer, and crop it to the smallest possible size.
    • All sprites for each clip are automatically grouped into a single atlas, making it easier to optimise draw calls for each clip (all the parts for a single frame are guaranteed to be within the same texture), while also bypassing the difficulties of using sprite atlases with addressables. There's a little more wasted texture space than using a single sprite atlas for the whole set, but I'm hoping the difference is negligible.
    • The PSD importer also handles positioning the sprites relative to their original position in the PSB, based on the pivot. This data can be easily read for generating the AnimationClips, without having to reference all the original sprites.
    • Setting pivots for a new clip can be done in a single step, as you can edit all the pivots for frames in one clip very quickly.
    • Updating, replacing, or removing clips, frames or layers is a simple and intuitive process for our artist.
    • Lastly, it also makes it easier to navigate the project. We don't need to have masses of folders filled with sprites, split out into clips and layers. Each character gets one folder, with about 30 PSBs in it. It's a minor difference, but it does make it easier to navigate the project!

    It's probably worth noting that we aren't actually creating any AnimationClip assets within the OnImportAsset step. During that process, I'm simply storing all the relevant data in a ScriptableObject within the PSB, then adding a button to the Inspector to trigger the generation, outputting clips to the specified folder.

    There are two main reasons for this:
    1. Thanks to the SpriteLibrary/Resolver pattern, we no longer need a clip per character - only a new Sprite Library. Thus we only need to generate these clips once, for the "base" character. We can manually control when we update them, and they aren't directly associated with the PSB file.
    2. If we added the AnimationClips as subassets of the PSB, they'd be read only. We need to control the positions of other transforms to use as anchors for VFX. By keeping the clips separate, we can update these things. I've configured the Clip Creation method to only overwrite specific AnimationCurve bindings, and the clip settings, so no data is lost via re-import.
    We then have the other side of this, which is updating the SpriteLibraries. It's a similar process; store some data in a ScriptableObject during OnImportAsset, provide an reference to a SpriteLib in the inspector, update it via button.

    This workflow likely is far from perfect, but it's a big improvement over our previous import system. A nice benefit of this workflow was the minimal need for maintaining any custom UI, and a lot of the logic was provided for us by the existing tooling.

    I find leveraging individual tools to build custom workflows are often more useful than predefined workflows, which might not fit the weird needs of chaotic users.

    Ideally, we'd ditch the entire prefab generation, as we never use the prefabs, and just use the data from PSDLayer and
    SpriteMetaData to produce the same results.

    It would perhaps be better still to achieve this using custom SpriteEditorModules, rather than piggy-backing off the importer, however I found them slightly more difficult to work with, considering the restrictions on PSDLayer and SpriteMetaData access, combined with a lack of documentation. They also lacked the ability to automatically update data when the asset was imported, which is useful for keeping everything up to date.

    I started down this route by an initial intent to leverage more of the 2D system, such as using the bones for managing pivots, and providing clip previews in SpriteEditorModules. Ultimately, as the work has gone on, there's been less and less of the provided features I've found suitable for our needs.

    Having written this out and taken a step back from the process, perhaps the implementation I've arrived at is misuse of tools, or more bluntly, a bastardisation of them. Using asset importers without the expressed intent to create any asset more meaningful than data stores probably highlights that I could, and perhaps should be tackling this differently, which is certainly something I'll think more on. However, the current workflow I've ended up with does feel good. It's easy for our non-technical team members to understand and use. It feels simple, and there's a low development maintenance cost.
     
  20. leyreley

    leyreley

    Joined:
    Oct 7, 2015
    Posts:
    4
    Just found out about this, it's great!
    Would it be possible to make animations with this and import them in UI Toolkit instead of using spritesheets?
     
  21. DragonCoder

    DragonCoder

    Joined:
    Jul 3, 2015
    Posts:
    853
    What are you wanting to do using UI Toolkit exactly? Wouldn't bone-based animations of this kind be a bit overkill for UI?
    The sprite renderer which is capable of accessing bone data etc. is not compatible with UI toolkit unfortunately and think not for "old" Ugui either (but that can be interwebbed with normal rendering if really needed).

    For a full on funky, creative UI you might need to use normal sprite renderers. That gives you all liberty (like this) but at cost of convenience when it comes to automatically adapting to screen ratio.
     
  22. leyreley

    leyreley

    Joined:
    Oct 7, 2015
    Posts:
    4
    I'm working on some card UI with UI toolkit, and animating the transitions between cards with the ones that uitk provides. Inside the card I want some spine-like animation of some 2d characters. I recently started looking to see how to integrate spine with this, and ended up here.
     
  23. GamerXP

    GamerXP

    Joined:
    Mar 22, 2014
    Posts:
    65
    I was comparing 2D Animation package with Spine a bit, and there was one neat feature that is missing. I wonder if it's possible to implement:

    In Spine, you can animate vertexes directly without bones. It's actually pretty useful if you need to deform body a bit during, for example, run cycle. It's possible to do so with extra bones, but it may require an insane amount of bones on some cases.

    Stuff like blend shapes may be useful as well, but it can be implemented with a custom script if vertex animations are there.
     
    DragonCoder likes this.
  24. Ted_Wikman

    Ted_Wikman

    Unity Technologies

    Joined:
    Oct 7, 2019
    Posts:
    786
    @leyreley have a look at our latest UI Toolkit sample (link). This sample makes use of 2D Animation and UI toolkit, which might give you some inspiration.

    @GamerXP thank you for the feedback. How do you see yourself animating the vertices? and how would it look like within the Animation Window? I'll add this to our backlog.
     
    leyreley likes this.
  25. GamerXP

    GamerXP

    Joined:
    Mar 22, 2014
    Posts:
    65
    You select an object with SkinMesh and it shows you sprite's verticles and edges. You can then select any and do movement, rotation and scale with them.

    There is how it works in Spine, and it seems convenient enough to work with:
    https://gyazo.com/74e86a23ebd65cce9acc26c1415d841b

    Well, thing is.. I somehow doubt it's possible to do with current Unity's animation system. Because it can't animate array's values. Maybe some internal magic can do something about it.
     
    DragonCoder and Ted_Wikman like this.
  26. leyreley

    leyreley

    Joined:
    Oct 7, 2015
    Posts:
    4
    Thanks a lot! It looks great and I didn't saw this before!
     
    Ted_Wikman likes this.
  27. PBKitty

    PBKitty

    Joined:
    Dec 23, 2021
    Posts:
    39
    I can confirm that this happens, at least.
     
  28. PBKitty

    PBKitty

    Joined:
    Dec 23, 2021
    Posts:
    39
    My friend made a working prototype of something like that where it generated an empty object for selected vertices to use as handles in animation. Not sure if he is still working on it.

    (My hacky solution was just to add a bone to each vertex I wanted to animate, which was obviously not ideal but it works.)

    I think that being able to save blendshapes to the sprite mesh would be a nice alternative.
     
    Ted_Wikman likes this.
  29. Ted_Wikman

    Ted_Wikman

    Unity Technologies

    Joined:
    Oct 7, 2019
    Posts:
    786
    This is a known bug with Sprite Resolver/Sprite Library's Category & Label hashing values. This has been fixed in Unity 2022.1 and onwards, if the Animation Clip makes use of the new Sprite Hash-value to key the Category/Label in the animation. If your animation clip does not utilise Sprite Hash, you can use our upgrading tool (also in Unity 2022.1 and onwards) to upgrade the values in your clips.
     
    PBKitty likes this.
unityunity