imagine if I build a game like vampire survivor, there will be so many enemies in the screen.
@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.
ā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.
ā¦that is brilliant.
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.
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.
I also filed a bug report! The case # is IN-11884
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!
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
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.
- 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.
- 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.
- 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:
I think it was made in one of the first versions of the package.
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 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?
-
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.
-
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.
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.
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.
Hi 2D folks! 2D Animation 8.0 was released with Unity 2022.1. Iām unsticking this thread. Please join the discussion here.
but what if weāre on LTS and canāt use 8.0
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!
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 )
-
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.
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.
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:
- 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.
- 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.
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?