2D Animation 7.0 released for Unity 2021.2

2D Animation 7.0 released for Unity 2021.2


We are happy to announce that 2D Animation 7.0 is now available with Unity 2021.2. The focus of this version is on improving the user experience with the Skinning Editor.

What’s new?

  • Introduced a Sprite Influence tool that displays which Sprites are influenced by a selected Bone.
  • Added a color picker to the Visibility panel to easily modify bone colours.
  • The associated keyboard shortcut is now displayed in a tooltip when hovering over a Skinning Editor tool.

See the full changelog here.

About 2D Animation
The 2D Animation package adds tooling for rigging a sprite for skeletal animation. This package includes a Skinning Editor module in the Sprite Editor window for creating and editing bones, manual & automatic mesh tessellation as well as skin weights generation and painting. The Sprite Skin runtime component ties this all together to drive sprite deformation.

This also includes support for Multiple Sprite Single Character rigging workflows through 2D PSD Importer Package.

Getting Started

  • Install the latest Unity 2021.2
  • Start a new project with the 2D or 2D URP Template

You can confirm that the 2D Animation 7.0 package is installed by opening Package Manager (Window > Package Manager) and selecting the Packages: In Project from the dropdown.
7599607--944083--In Project.png

You should see a verified version of 2D Animation in your project.

Optional Performance Boost
When animating your characters, you can improve the performance of the animated Sprite’s deformation at runtime by installing both the Burst and Collections package from the Package Manager. You can read more about it here.

What can you do?
Try it out and let us know what you think of the package. We want to know what works as expected, what doesn’t and what is missing.

7 Likes

i found out that spriteskin is so bad

@stickylab when asking for help, do try to give more information than just a screenshot, such as:

  • Number of Sprite Skins in the scene (I would guess you have 6?)
  • Unity version
  • 2D Animation package version

My general suggestion here is to try out our optional performance boost, by installing the Collections and Burst packages.

7642063--952264--upload_2021-11-9_22-22-21.png
i will tell the info later , btw

i cannot install the burst

curently i used unity 2020
i make a lot of spriteskins because itry to make leaf that has spring bone
.
ah so i have to use unity 2021 ?

[Package Manager Window] Cannot perform upm operation: Package name ‘com.Unity.Collections’ is invalid. [InvalidParameter].
UnityEditor.EditorApplication:Internal_CallUpdateFunctions ()

i already used 2021.2 but i can not install the collections package

7642732--952387--upload_2021-11-10_1-58-44.png

does burst works with net 2.1 ? i watch the tutorial about burst and he said that the api must be 4

The optional performance implementation is supported from Unity 2019.4 and onwards. You should only have to install the Burst and Collections package, no need to change any project settings.

If you create a new 2D project in Unity 2020.3, can you install the burst and collections package following this guide?

i dont know how to install collection in 2019 ,there is no instal by name in package manager ,
i failed instaling burst in 2020

im succass in 2021 but the scene vew seems buggy
( it is not like usual in previous version ,extremly very hard to control just game object in hierrarcy ) sometimes the tools doesnot appears so have to do it in transform
7645513--952993--upload_2021-11-11_0-50-13.png

ah ok iwill try this method Introduction to 2D Animation | 2D Animation | 5.0.10

finnaly i can install it in 2020 ,thanks

1 Like

Hi, I’m loving the 2D animation package, thank you for making it!

I was wondering if you could help me out with an issue I’m having. I’m doing a project that will ultimately be on WebGL. I have a character that animates with bones and skin and that all works great. What I want to do is give the user the option to upload a png to create a custom skin for the character.

What I’m currently doing is that I have the Texture2D loaded into memory(?) and I am creating a sprite out of it with Sprite.Create() and trying to swap it into the character via SpriteLibarary.AddOverride. I get this error when I try to do this. (Note: I am testing in Unity Editor, and I’m using package version 5.0.9 because I can’t upgrade to 2021)


IndexOutOfRangeException: Index 1089302692 is out of range of ‘2’ Length.
Unity.Collections.NativeArray1[T].FailOutOfRangeError (System.Int32 index) (at <af218701fe324032b521ddd91f13662b>:0) Unity.Collections.NativeArray1[T].CheckElementReadAccess (System.Int32 index) (at :0)
Unity.Collections.NativeArray1[T].get_Item (System.Int32 index) (at <af218701fe324032b521ddd91f13662b>:0) UnityEngine.U2D.Animation.SpriteSkinUtility.Deform (Unity.Mathematics.float4x4 rootInv, Unity.Collections.NativeSlice1[T] vertices, Unity.Collections.NativeSlice1[T] boneWeights, Unity.Collections.NativeArray1[T] boneTransforms, Unity.Collections.NativeSlice1[T] bindPoses, Unity.Collections.NativeSlice1[T] deformed) (at Library/PackageCache/com.unity.2d.animation@5.0.9/Runtime/SpriteSkinUtility.cs:294)
UnityEngine.U2D.Animation.SpriteSkinUtility.Deform (UnityEngine.Sprite sprite, UnityEngine.Matrix4x4 rootInv, Unity.Collections.NativeSlice1[T] vertices, Unity.Collections.NativeSlice1[T] tangents, Unity.Collections.NativeSlice1[T] boneWeights, Unity.Collections.NativeArray1[T] boneTransforms, Unity.Collections.NativeSlice1[T] bindPoses, Unity.Collections.NativeArray1[T] deformableVertices) (at Library/PackageCache/com.unity.2d.animation@5.0.9/Runtime/SpriteSkinUtility.cs:265)
UnityEngine.U2D.Animation.SpriteSkinUtility.Deform (UnityEngine.Sprite sprite, UnityEngine.Matrix4x4 invRoot, UnityEngine.Transform[ ] boneTransformsArray, Unity.Collections.NativeArray`1[T] deformVertexData) (at Library/PackageCache/com.unity.2d.animation@5.0.9/Runtime/SpriteSkinUtility.cs:358)
UnityEngine.U2D.Animation.SpriteSkin.LateUpdate () (at Library/PackageCache/com.unity.2d.animation@5.0.9/Runtime/SpriteSkin.cs:282)

This is the code I am using below:

public void CustomSkin()
{
customSprite = Sprite.Create(texture2D, new Rect(450, 50, 1150, 1600), new Vector2(0.5f, 0.5f), 100.0f);

string referenceLabel = targetResolver.GetLabel();
Sprite referenceSprite = spriteLibrary.GetSprite(targetCategory, referenceLabel);
SpriteBone[ ] bones = referenceSprite.GetBones();
NativeArray poses = referenceSprite.GetBindPoses();
customSprite.SetBones(bones);
customSprite.SetBindPoses(poses);

const string customLabel = “customTorso”;
spriteLibrary.AddOverride(customSprite, targetCategory, customLabel);
targetResolver.SetCategoryAndLabel(targetCategory, customLabel);
targetResolver.gameObject.GetComponent().color = Color.white;
}

The odd thing is that it all works if I create the sprite a different way: customSprite = Resources.Load(texturePath). By loading the texture as sprite from the Resources folder I get no issues. The problem with this workflow is that if I want my user to upload via WebGL, I can’t save that png to resources and then load it from resources (at least my understanding is that I can’t save anything into Resources folder during runtime).

If you have any suggestions or can let me know what I am doing wrong, I would really appreciate it. Thank you!

Hello @GSanLob ,
First off, thank you for your kind words!

The reason why you see this error is because when you create a Sprite using Sprite.Create, your Sprite does not generate the BoneWeight vertex information per vertex in the mesh. The BoneWeight vertex information is only created by generating a mesh inside the Skinning Editor. So when you later pass the newly generated Sprite mesh into the SpriteSkin component, it fails due to missing data.

My general advice is that you load and use Sprites which already have had their mesh generated inside the Skinning Editor, so that each Sprite contains the data they need in order to function properly with the other 2D Animation components.

But if you want to continue on your path you are currently on, you could also inject BoneWeight data from a reference Sprite or create your own data on the fly. I see from your code that you have a Sprite which already already have the data you are after, so you could do something like this

using Unity.Collections;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.U2D;
using UnityEngine.U2D.Animation;

[RequireComponent(typeof(SpriteRenderer), typeof(SpriteSkin))]
public class SpriteGenerator : MonoBehaviour
{
    public Texture2D myTexture = null;
    public Sprite refSprite;
    
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.K))
        {
            var sprite = CreateSprite();
            AssignSprite(sprite);
        }
    }
    
    Sprite CreateSprite()
    {
        var sprite = Sprite.Create(myTexture, new Rect(0, 0, myTexture.width, myTexture.height), new Vector2(0.5f, 0.5f));

        InjectBoneWeights(sprite);
        
        sprite.SetBones(refSprite.GetBones());
        sprite.SetBindPoses(refSprite.GetBindPoses());

        return sprite;
    }

    void InjectBoneWeights(Sprite targetSprite)
    {
        var vertexCount = targetSprite.vertices.Length;
        var blendWeightArr = new NativeArray<BoneWeight>(vertexCount, Allocator.Temp);
        
        var blendWeightRef = refSprite.GetVertexAttribute<BoneWeight>(VertexAttribute.BlendWeight);
        for (var i = 0; i < blendWeightArr.Length; ++i)
            blendWeightArr[i] = blendWeightRef[i % blendWeightRef.Length];
        
        targetSprite.SetVertexAttribute(VertexAttribute.BlendWeight, blendWeightArr);
        blendWeightArr.Dispose();
    }

    void AssignSprite(Sprite sprite)
    {
        var sr = gameObject.GetComponent<SpriteRenderer>();
        sr.sprite = sprite;
    }
}

A word of caution though, this is not the safest operation and it will most likely be difficult to set the blend weight just right for your generated Sprite.

Let me know how it goes!

Hi Ted. Thank you for such a quick reply! I appreciate it.

I tried the code you added and it worked great! I didn’t get the error and the sprite now moves with the bone. The only issue I am having is how the sprite is cut out of the PNG. For example, in the image below, I tried to replace the forearm sprite with the one that is part of a custom PNG. The whole PNG got attached to the bone. I tried to modify this by changing the Rect details in Sprite.Create by calculating where the Rect cuts would be on the original PNG. However it was very hard to guess and I realized that Unity had packed the sprites in a rectangle and not the original square I had (image below). The problem is I’d love for there to be a standardized skin template that I could have, but because Unity packs the sprites in a different locations and shape, it seems hard to make it all match.

Do you have any suggestions on how I can fix this problem? Is there a different sprite setting I need to do at import? Or something I can do with C# that could give me the data I need to input into the Rect dimensions?

Lastly, regarding the last image, is this what you meant when you said to be cautious when blending weights - (the torso sprite is connected to two bones and when I move the child bone the torso starts to blur and stretch). Is there any way around this? Or would you suggest just keeping 1 bone per 1 sprite in order to avoid this issue?

Thank you so much!
Gleb

I’m happy you got it to work. So in your example, you have one .psb and one .png. The PSD Importer package will generate a Sprite Sheet for the texture data inside the .psb file. For the .png, there is no Sprite Sheet generation. If you want them to have the same texture layout, my suggestion is to either use only .psb or .png files. This will allow you to keep the same texture layout.

As for Sprite Rect calculations, there is no easy way around this, apart from copying data from already existing Sprites. The alternative is to create your own algorithm where you slice and create the Sprite Rects yourself based on data you provide.

For your final issue, it does seem like a blend issue, as you can see some stretching going on.

My general advice would be to start small and simple, and then scale it up. Have one object per texture and make sure it works as intended. Once that works, add more complexity. This way you can more easily debug and understand what goes wrong.

Hi.
Is it possible to have a Single Sprite rigged with more bones and animate the part of the sprite that is arounf the bone ?
Or is it doable by effectors or other 2D features ?

For example I would like to have a bone on a tree branch and animate only that part (without cutting it separately in photoshop).

Thank you

Hello @VP_no1
Yes, you do not need to cut the image into multiple pieces. Have a look at our Snake sample to see it in action.

1 Like

Please specify a step by step workflow becasue in docuemtnation is not very straightforward.
At the moment I did this:

  1. autogeerated geometry
  2. create the bones i needed
  3. created vertices so i encapsulate each bone like in a box
  4. now i should paint the weights

3 – i am not sure if this is the correct way to put the vertices
4 – how should i paint the weights ?

do i select each bone and paint the 4 vertices that encapsulates the bone ?

7691173--962335--upload_2021-11-27_15-59-59.png

I also have the sme problem on rendering the normal sprite. It simply vanishes and I only see the bones. Why ?

edit: for others who enter here: there must be weitght paint on everything else it wont show the sprite.

How to move an edge collider 2d with the bones ?
I have the collider and an effector on a separate GO.
I tried to have this go as child to the bone root but it doesnt move as expected.
I think there shoudl be a way to autogenerate a collider around the bones, becsaue I do not see any other solving.
Any ideas please ?

later edit: i put a box collider on every single bone GO. They do move ok with every encapsulated bone.