skinned animation works...but the positions of the bones are not updating?

I got my animation to work with mt model but when I tried to use the Socket Attach To Component presented in the samples, it parents correctly but doesn’t move. I have tracked the issue down to the bones themselves not moving. idk if it’s a glitch because there is some y movement (less than 0.01) but the animation moves way more than that. All i know since the bones aren’t moving like the animation is so tthe socket attachment script doesn’t work.

Any Ideas?
Here is the model import settings


imported component

Skimmed mesh part

bone thing
6946781--816947--upload_2021-3-17_19-9-12.png

anything else i’m missing?

quick update: i think i got it to work. I added a LateAnimationGraphWriteTransformHandle to a specific bone and now the bone updates properly. I don’t know why but this works. My test was created inside the same project as the Unity Animations Demo projects so i don’t know why my solution is different from the examples. In the demo examples they only needed to apply the LateAnimationGraphWriteTransformHandle to the root node specified in the skinned mesh but it looks like i have to add this to everything…

i will label this as a bug unless someone has an answer.

It hasn’t been a few days since I started looking at DOTS Animation, so I don’t know the exact details.

I’ll only tell you what I’ve found out now.

SkinnedMeshRenderer is changed to MeshRender and deform is performed using the value of SkinMatrix buffer.

Statemachine that acts as an Animator and Graph are created as blobs.

Animation Graph creates RigDefinition based on bone information from RigComponent.

GameObject Bones are changed to Entitiy Components after providing information to RigComponent.

AnimationJob work is done only on Rig data.

Rig Data is fed back to the Bone Entity Component.

However, these Bone Entity Component Data have nothing to do with Skinning.

Skinning only uses data from RigData.

The reason for feeding back to Bone Component Data is for read buffer attachments or constraints.

So no matter how much you move them, it’s useless.

If you want to edit the animation itself, you need to edit the Rig Data yourself. However, such a method is provided only as a contraint.

6741043--776845--upload_2021-1-19_19-3-0.png

1 Like

thanks for your help! i changed my code up a bit and now it’s doing what i want :smile:. my goal was to have the ECS colliders move with the animation. This is for some simulation tests i wanted to experiment with but needed the colliders to move with the animation.

public class BonePhysicsColliderUpdaterComponent : MonoBehaviour, IConvertGameObjectToEntity
{
    public GameObject RigGameObject; // gameobject with the rig component
    public int index; // index of this object in the rig component
    public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    {
        if (enabled)
        {
            dstManager.AddComponentData(entity, new PhysicsColliderFollowEntityData
            {
                RigGameObject = conversionSystem.GetPrimaryEntity(RigGameObject),
                index = index
            });
        }
    }
}

//[UpdateAfter(typeof(MyFirstClip_PlayClipSystem))]
public class Test01Thing : SystemBase
{
    EntityQuery q;
    protected override void OnCreate()
    {
        q = GetEntityQuery(typeof(PhysicsCollider),
            typeof(PhysicsMass),
            ComponentType.ReadOnly(typeof(PhysicsColliderFollowEntityData)),
            typeof(Translation));
    }

    protected override void OnUpdate()
    {
        if (q.CalculateEntityCount() == 0) return;
        Entities
            .WithName("dddddddd")
            .WithBurst()
            .ForEach((Entity entity, ref Translation translation, ref Rotation rotation, in PhysicsColliderFollowEntityData data) =>
            {
                var GetAnimatedLocalToWorld = GetBufferFromEntity<AnimatedLocalToWorld>();
                if (GetAnimatedLocalToWorld.HasComponent(data.RigGameObject))
                {
                    var anims = GetAnimatedLocalToWorld[data.RigGameObject];
                    LocalToWorld tmp = new LocalToWorld { Value = anims[data.index].Value };
                    translation.Value = tmp.Position;
                    rotation.Value = tmp.Rotation;
                }
            }).Schedule();
    }

    void log(string a)
    {
        UnityEngine.Debug.Log(a);
    }
}

public struct PhysicsColliderFollowEntityData : IComponentData
{
    public Entity RigGameObject;
    public int index;
}

useful to deep understand the animation how works.