Search Unity

Feature Request Sprite Library Asset Drag and Drop

Discussion in '2D Experimental Preview' started by digiwombat, Dec 27, 2020.

  1. digiwombat

    digiwombat

    Joined:
    Sep 26, 2013
    Posts:
    30
    Howdy.

    So, I like the idea of using Sprite Libraries and Resolvers as a solution over my current method (LateUpdate Dictionary lookups), however, I have a considerable number of animation frames, all of which are named properly in their respective sheets.

    The sad part of this is that I cannot drag and drop those named sprites onto a Sprite Library Asset, I have to manually drag each sprite over and add a key string, in spite of the sprites already being named. Unless I am missing a trick or misunderstanding how things work, this would require me to manually select 60+ sprites for every piece of clothing and hairstyle in my game to use the Libraries.

    If I'm missing something, please point me in the right direction here, otherwise, I would very much like to see the ability to drag and drop sprites onto a category and have them be added without all the tedious manual entry.

    Edit: It's probably worth mentioning that I'm doing frame-by-frame sprite animation. Not bone-based stuff.
     
    Last edited: Dec 27, 2020
  2. digiwombat

    digiwombat

    Joined:
    Sep 26, 2013
    Posts:
    30
    Well, I wrote it myself because that's just how things go. Sadly, it's not going to work for my needs because the Inspector is just desperately slow and laggy with more than a few sprites in any given Category (my base sheet has around 350) and since Frame-by-Frame animation for sprites seems to be an unsupported use-case for 2D Animation, I'll be just not using the package.

    Here's the code for anyone who wants it. Add it to Line 66 of SpriteLibraryAssetInspector.cs file in the 2D Animation package.

    Code (CSharp):
    1. Event evt = Event.current;
    2. switch (evt.type)
    3. {
    4.     case EventType.DragUpdated:
    5.     case EventType.DragPerform:
    6.         if (!rect.Contains (evt.mousePosition))
    7.             return;
    8.         DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
    9.         if (evt.type == EventType.DragPerform)
    10.         {
    11.             DragAndDrop.AcceptDrag ();
    12.             SpriteLibraryAsset m_SpriteLib = (SpriteLibraryAsset)target;
    13.             List<Categorylabel> list = m_SpriteLib.categories[index].categoryList;
    14.             list.Clear();
    15.             foreach (Sprite dragged_object in DragAndDrop.objectReferences)
    16.             {
    17.                 list.Add(new Categorylabel() { name = dragged_object.name, sprite = dragged_object });
    18.             }
    19.         }
    20.         break;
    21. }
     
  3. Ted_Wikman

    Ted_Wikman

    Unity Technologies

    Joined:
    Oct 7, 2019
    Posts:
    383
    Hello @digiwombat,
    Sorry for a late reply, and thank you for the feedback and the code solution.
    Apart from the drag-and-drop feedback, you also mention two additional issues:
    What kind of amount of Sprites/Categories are we talking about before it starts becoming noticeable slow?

    Why does frame-by-frame animations seem unsupported? We have a frame-by-frame (flipbook) example in our 2D Animation Samples, using Sprite Swap. (link). Could you elaborate a bit more?

    Thanks!
     
  4. digiwombat

    digiwombat

    Joined:
    Sep 26, 2013
    Posts:
    30
    Hey @Ted_Wikman. No worries on the slow reply. I know the 2D team is small and probably terminally busy, haha.

    Not sure if it's version specific (I'm on 2020.2.4) but even just setting the number of entries to 35 started lagging my editor. My current player animation set contains 350 frames which makes the entire UI go unresponsive, I believe due to validation checks being done but I haven't glanced at the code since I wrote the drag/drop. The lag was present on two high spec machines and goes away if I manage to close the inspector for the sprite library asset.

    As to the second part, I guess I should qualify it an expand a bit and say it is not a properly supported use case, or at least poorly supported. For small animation sets with only minimal swaps, it's basically workable. But, again, until I wrote a solution there was no drag and drop, which would have meant setting up a single sprite swap for anything would mean manually adding 350 sprite names manually and dragging them over. This was clearly never tested for or expected as a use case and even then, for larger amounts of swaps (many shirts or hats, say) the system doesn't allow for the automation of anything, meaning all sprites would need to be manually added when updating the base spritesheet rather than just pointing it at a folder or file and having it read those and create the stuff based on the sprites in it.

    If frame by frame animation swaps were given first-class consideration UX issues like these would maybe have been experienced or considered because I'm willing to bet even adding 20-30 sprite by hand and then adding variants would have made someone go "well this isn't fun."

    It reminds me of the Tilemap situation. Our base tilemap for exteriors has 1100 tiles. And the UX for large sets like that never seemed to be a consideration since the team making them doesn't seem to work with them. And that's understandable but then getting anything in the workflow changed is basically never going to happen. And it also means I don't used Unity's solution because creating 1100 extra loose files rather than just using a sheet and offsets to generate IDs is just worse. It also makes swapping tilesheets (in my case for season changes) a much less straightforward workflow.

    Again, understandable with 2D because the team making it was clearly considering bone-based animation primarily given how tied it is to the 2D Animation package, but just no good for people working with higher frame counts.
     
  5. Ted_Wikman

    Ted_Wikman

    Unity Technologies

    Joined:
    Oct 7, 2019
    Posts:
    383
    Thanks a lot for the insights @digiwombat. Getting feedback with concrete numbers like this is really valuable, since it gives us the ability to build more test cases that includes a wider range of the projects built with the 2D toolset.

    I think your comments on the UX flow not being very friendly for a project like yours is spot on, and it is something we should address in future releases.

    If we zero in on the SpriteLibrary Asset, and let's say that we add
    - Drag and Drop support to create multiple labels in one go
    - No editor frame drop when inspecting a large SpriteLibrary Asset (~500 labels)
    Would this resolve your issues working with SpriteSwap and Frame-by-frame animations? Or are there more issues that would block you?
     
  6. digiwombat

    digiwombat

    Joined:
    Sep 26, 2013
    Posts:
    30
    Thanks for taking a look at that and caring about the use-case, @Ted_Wikman.

    As to whether that would make SpriteSwap work for my project, it's unlikely for my current project owing to factors I'll talk about below. I do think it would make it usable for MOST projects using frame-by-frame animation with sprite swapping though.

    In my case, it's a question of scale and automation. My game has 40-50 shirts per gender, 10-20 pants, bunches of shoes, hairstyles, facial hair, and a number of skintones. So the fact that any additional animation being added would need to be manually recreated falls short of my current solution, which isn't necessarily ideal itself.

    My current solution involves a giant enum of sprite names which I then swap in an animator, but I can feed it a Resource path at runtime, load all the sprites into a Dictionary<Enum, Sprite> and swap them without generating garbage (it'd be nice to be able to do that with strings, but Unity's Object.get_name() generates garbage every call so it's not workable). It's a bit clunky maintaining the Enum but I had some trouble with the AnimationClips respecting my String hash ints. Either way it's still very automatic and essentially transparent to my artist and myself once the animations/enum are setup, since I just swap the path and fill the dictionary.

    I imagine the scale problem is a roadblock that anyone doing a heavy player customization frame-by-frame game will hit with the 2D Animation system's SpriteSwap, that making the initial SpriteLibraryAssets would be easy enough, but that managing them could become a slow, tremendous chore that's prone to missing changes due to needing to manually rebuild all the variants.

    My best suggestion would be an editor like the one for SpriteAtlases that would allow the generation of SpriteLibraryAssets from a folder or multi-sprite Texture2D path. That would allow people to tell the editor "Hey, these are the things I want to make into SpriteLibraryAssets" and it will scale better than having to drag fifty different shirts, thirty pants, etc, over to the spriteswapper any time there's a touch up done to a sprite or a new animation added more widely. Just set it up once, hit generate, and all the SpriteLibraryAssets are made for you.

    Thanks again for the time and consideration.
     
  7. Ted_Wikman

    Ted_Wikman

    Unity Technologies

    Joined:
    Oct 7, 2019
    Posts:
    383
    Some happy news, while confirming the performance issue in Sprite Library Assets, I realized that the ability to drag and drop Sprites into a Sprite Library Asset is in the shipped 2D Animation 6.0.0-pre.2. I previously confused it with the later version we are working on. Sorry for the confusion!

    I am also able to reproduce the performance issue you reported when adding ~250 Sprites into a Sprite Library Asset and then inspecting it. So this is added to our backlog, and we will tackle it in a future release of 2D Animations.

    While testing with many Sprites in one Sprite Library Asset, I also saw the issue you were pointing out, that the inspector experience is not great, even if we tackle the low frame rate issue we have now. I've added this to our backlog as well so we can do additional research to see how we could improve this area. I think your idea with making the Sprite Library Asset work more like the Sprite Atlases is interesting, but I am not sure how the customization would work for the users when they want to define category rules for the different folders. But it is a good starting point for us to begin our research.

    Thanks for your input, it really helps us improve the 2D Animation experience.
     
  8. KatonaSaint

    KatonaSaint

    Joined:
    Dec 10, 2020
    Posts:
    2
    I found this thread when trying to search for more information about the SpriteResolver and SpriteLibrary. This functionality is just what I've been looking for to be able to use the same animations with different spritesheets!

    I've kinda found the same issues as digiwombat--specifically, the effort required setting up the SpriteLibraries with large (and many) spritesheets. I was curious if there might be some improvements being made. Ted, you mentioned that drag and dropping sprites into a Sprite Library Asset is in the shipped 2D Animation 6.0.0; is this dragging and dropping several sprites at once to create/populate Category Lists, or just dropping sprites one at a time into each Category List item? I downloaded Unity 2021.1 but I'm not seeing bulk drag/drop into Sprite Libraries (though I might still be using an older version of 2D Animation? I'm trying to figure out how to access 2D Animation 6.0.0 in the package manager).

    While I'm excited about having this new functionality, I'm weighing how much more work it will be to set up sprite libraries for all my different characters (and different versions of each character). For example, my current workflow to create an animated character prefab:
    1. Create animations by dragging and dropping many sprites (at once) from a spritesheet into a the Animation window (a few dozen animations, each with spritesheets of 16-32 sprites, so dragging/dropping is great!). 1 step for Y animations, regardless of how many frames are in the animation (thanks to drag and drop creating keyframes for all the sprites in an sprite image at once).
    2. Create and link animations in the Animator window
    3. (Repeat 1 and 2 for each new character)

    Since #2 can get very complex for my characters, I'm hoping to be able to reuse the Animations and Controllers for multiple characters by utilizing the Sprite Library/Resolver functionality. Additionally, even for the same character, I could use a Sprite Resolver/Sprite Library to give the sprite character multiple skins.

    However, with the current workflow (as I understand), in order to use Sprite Library with characters, I have to:
    1. Create a SpriteLibraryAsset. For each animation, I add a new Category List item in the SpriteLibraryAsset. For each Category List item, I have to type in a Label value, and drag and drop one sprite from the animation's spritesheet to the Sprite input. If this animation has 32 unique frames, I have to type 32 Labels, and drag and drop 32 individuals sprites from the sprite sheet (this is where I'm not seeing bulk drag and drop--though I thought old versions might have had it from old documentation?). X steps (where X is the number of frames in the animation) for Y animations
    2. Create animations by moving to each time frame (one by one) and choosing which Label sprite to use for the frame. Repeat for each animation frame (so if there are 32 frames, I go through and choose a time and frame 32 times, as there's no bulk creation of animations like simply dragging and dropping sprites in a spritesheet). X (where X is the number of frames in the animation) steps for Y animations
    3. Create and link animations
    4. (Repeat step 1 for each new character. Steps 2 and 3 are only done once for all characters that share the animations)
    So while I can reuse animation and controllers with the Sprite Library/Resolver, it actually makes animation creation a lot more work intensive. I have to set up Category Items for each frame of each animation (both sprite and label) for each character. I also have to set up animation keys for each frame of each animation once (but only once across all the characters that reuse the given animator/controller).

    I was hoping an implementation of this might be a bit more simple, like creating animations normally (i.e., dragging and dropping spritesheet frames onto the Animation window to auto create keyframes), but having a way to swap out which spritesheet file is being used to pull individual sprites from. This would require sprite sheets to have the same number of sprites (and maybe even the same dimensions/locations of sprites?), but I'm not sure if this is a dealbreaker for game devs or artists. All my sheets would be the exact same sizes with the exact same number and dimensions of sprites.

    Or, at least being able to use drag and drop to create Sprite Library Category Lists from spritesheets (or just multiple sprites) would be a huge improvement. Additionally, being able to quickly/bulk create animation keys from Sprite Library Category Lists would be very cool.

    Anyway, just sharing some user experience and input. Thanks, and keep up the great work-
     
  9. Ted_Wikman

    Ted_Wikman

    Unity Technologies

    Joined:
    Oct 7, 2019
    Posts:
    383
    Hello @KatonaSaint and welcome to the discussion!
    Thanks for your detailed explanation of your workflow. These step by step guides helps us see how the tools are being used by you all.

    To get 2D Animation 6.0, you need two things:
    1. Unity 2021.1
    2. Enable Pre-Release packages in your project settings
    Since 2021.1 is in beta, 2D Animation 6.0 is also in a pre-released state and you have to check the enable Pre-Release packages box to allow your project to install pre-release packages. Once this is done, you should be able to see 2D Animation 6.0 in the package manager, per usual.

    In 6.0 we have drag and drop, where you can select either single or multiple sprites and create either Categories or new Labels by dropping the selection onto either the general Sprite Library Asset window to create new Categories, or inside a Category area to create new labels. Do note that you have to select Sprite assets, not Texture assets. Sprite assets are the sub assets of a Texture asset.

    When you drag and drop multiple sprites into a category, they will be created with their Sprite name. See this sample to get a look at how we setup our Sprite Swap system for a flipbook/frame-by-frame animation demo.

    With this drag and drop functionality, it seems like your main issue remaining is to create the animation clips, is that correct? This is something we do not have a solution for right now, but it is something worth thinking about for future releases.

    In your sprite sheet example, it is true that you could swap out the atlas to get a similar effect as using the SpriteSwap system. However, our Sprite Atlas system is mainly created to switch out one Atlas for another, by loading and unloading the atlases. Have a look at these examples on how it would work.

    Thanks again for your feedback, and do let us know if you have any more questions or suggestions!
     
  10. KatonaSaint

    KatonaSaint

    Joined:
    Dec 10, 2020
    Posts:
    2
    Thanks again for the info, Ted-

    I was able to get all the pre-release components working with your instructions. Additionally, I could verify that drag-and-drop works in both the ways you describe (with either single or multiple sprites, and creating either new Categories or new Labels).

    However, it seems like dragging and dropping multiple sprites works only when creating the Main Library. When I try to create a secondary library off of the main library (for my second character), it looks like I have to drag and drop sprites one-by-one over the existing sprites that were set up in the main library (i.e., I can't drop all the sprites from the sprite sheet at once like I could the first time). I guess this makes sense (so as to ensure you have the exact same number of sprites), but unfortunately this probably won't work for me considering how much work it is to drag and drop 64 sprites for each of the many dozen animations (especially if I have to do it for multiple characters after creating the initial one). Let me know, though, if this should be working.

    I'll look into the Sprite Atlas approach, but it sounds like it's not exactly what I'm looking for.

    I did find an asset in the Asset Store that does exactly what I was hoping to do (basically swap out equal-dimensioned sprite sheets). Unfortunately, it doesn't handle blend trees (sounds like it's a Unity API limitation or something?), but I'm going to see if I can find workarounds.

    Thanks again for the help.
     
  11. Ted_Wikman

    Ted_Wikman

    Unity Technologies

    Joined:
    Oct 7, 2019
    Posts:
    383
    Great that you managed to pull down 2D Animation 6.0, and you got the drag and drop to work. Yes, it is true that drag and drop does not work as you might expect with Sprite Library variants. Great catch, let me bring this back to the team to discuss what kind of improvements we can make there. Unfortunately I do not have a fix for you in the meantime, you have to drag the Sprites one by one into the labels in the variant.

    The Sprite Atlas approach is suitable if you want to swap one complete set for another (think having all the trees on one Sprite Atlas, and swapping the atlas out for a new one where the trees are covered in snow, for a Christmas update).

    Moving on to Sprite Swap in a Blend Tree. For the 2D Animation package, we have a bug we are looking into where the SpriteKey (and Category/Label in 2D Animation < 6.0) has its value blended between the states in the Blend Tree. The workaround here is to set the blend value to exact values, so it does not blend between two or more states at the same time. Since SpriteKey is a hash value, if it gets blended, it cannot be resolved by the SpriteResolver leading to unwanted behaviour.

    I didn't know about the Animator Sprite Swap system on the asset store, thanks for sharing!

    Thanks again for the feedback, it helps us understand your pain points when working with 2D Animation in Unity.
     
unityunity