#OnAnimatorIK in ECS

1 messages · Page 1 of 1 (latest)

long hamlet
#

I am trying to work out how to access the Animator of both the Ghost which the client owns and the ghost which the client does not own to allow broadcast of OnAnimatorIK; is there a better way to do this?

#
using UnityEngine;
using Unity.Mathematics;

/// <summary>
/// This monobehaviour is automatically added to the game object if it is linked to an entity.
/// It allows to keep track of it's entity counter part.
/// </summary>
public class EntityGameObject : MonoBehaviour
{
    public Entity Entity;
    public World World;

    private Animator _animator;
    private bool _animatorCached = false;

    public void AssignEntity(Entity e, World world)
    {
        Entity = e;
        World = world;
    }

    void LateUpdate()
    {
        if (World == null || !World.IsCreated || !World.EntityManager.Exists(Entity))
            return;
        transform.position += Vector3.up * 0.75f;
    }

    private Animator GetAnimator()
    {
        if (!_animatorCached)
        {
            _animator = GetComponent<Animator>();
            if (_animator == null)
            {
                _animator = GetComponentInChildren<Animator>();
            }
            _animatorCached = true;
        }
        return _animator;
    }

    //Disabled Head IK rotation, cannot access Ghost's animator yet to assign Ghost's head rotation.
    void OnAnimatorIK()
    {
        if (World == null || !World.IsCreated || !World.EntityManager.Exists(Entity) || !World.EntityManager.HasComponent<NetcodePlayerInput>(Entity))
            return;

        Animator animator = GetAnimator();
        if (animator == null)
            return;

        var netcodePlayerInput = World.EntityManager.GetComponentData<NetcodePlayerInput>(Entity);
        if (netcodePlayerInput.IsTethered == true)
        {
            //Hand Position IK
            animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1f);
            animator.SetIKPosition(AvatarIKGoal.RightHand, netcodePlayerInput.TetherAnchor);
        }
    }

}
#

Would something akin to this work?:

                .WithAll<NetcodePlayerInput>()
                .WithAll<GhostOwnerIsLocal>()
                .WithAll<Animator>()
                .ForEach((Entity entity, ref NetcodePlayerInput netcodePlayerInput, ref NetcodePlayerState netcodePlayerState, ref NetcodeCameraFollowComponent camera) =>
                {

                }).WithoutBurst().Run();
            
            // Handle non-owned Ghosts (update animator from networked state data)
            Entities
                .WithAll<NetcodePlayerInput>()
                .WithAll<GhostOwner>()
                .WithNone<GhostOwnerIsLocal>()
                .WithAll<Animator>()
                .ForEach((Entity entity, ref NetcodePlayerState netcodePlayerState) =>
                {
                }).WithoutBurst().Run();```
#

I'm going to try instead just broadcasting each Transform separately for the heirarchy; I've just checked the client and as you can imagine, the bone positions are different on server+client and client, therefore I should only need a reference to said Transforms to be able to tell them what they should be on the other ghost that we don't own; not sure that makes sense but ye

silk plinth
#

Entities.ForEach is deprecated and has been removed in 6.5 - you probably want to avoid it

#

as for your question, i don't like accessing entity world from gameobjects (at what point during the world update is OnAnimatorIK and the mass checks you need is basically why)

#

so my personal preference would just be to write to your EntityGameObject from a system every frame with whatever data it needs in OnAnimatorIK

#

which might be what you're trying to do with those 2 EFE? if so then yeah i'd just swap it to systemapi.query, make the query include EntityGameObject then just write the data you need if it's own or not owned

long hamlet
#

@silk plinth ty x