How Add New IK controll to Full Body IK demo?

I try add SetChestEffector in this demo like the SetBodyEffector,but find some rotation bug: handle.chestBoneStream.SetLocalRotation(stream,handle.chest.GetLocalRotation(stream)),
and,how to update the chestEffector position in lateupdate?

;

using System;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Playables;
using UnityEngine.Experimental.Animations;
//using UnityEditor;

public class FullBodyIK : MonoBehaviour
{
    public bool syncGoal = true;

    [Range(0.0f, 1.5f)]
    public float stiffness = 1.0f;

    [Range(1, 50)]
    public int maxPullIteration = 5;

    [Range(0, 1)]
    public float defaultEffectorPositionWeight = 1.0f;
    [Range(0, 1)]
    public float defaultEffectorRotationWeight = 1.0f;
    [Range(0, 1)]
    public float defaultEffectorPullWeight = 1.0f;
    [Range(0, 1)]
    public float defaultHintWeight = 0.0f;

    private GameObject m_LeftFootEffector;
    private GameObject m_RightFootEffector;
    private GameObject m_LeftHandEffector;
    private GameObject m_RightHandEffector;

    private GameObject m_LeftKneeHintEffector;
    private GameObject m_RightKneeHintEffector;
    private GameObject m_LeftElbowHintEffector;
    private GameObject m_RightElbowHintEffector;

    private GameObject m_LookAtEffector;

    private GameObject m_BodyRotationEffector;
    private GameObject m_ChestRotationEffector;

    private Animator m_Animator;
    private PlayableGraph m_Graph;
    private AnimationScriptPlayable m_IKPlayable;

    private static GameObject CreateEffector(string name)
    {
        var go = SampleUtility.CreateEffector(name, Vector3.zero, Quaternion.identity);
        return go;
    }

    private static GameObject CreateBodyEffector(string name)
    {
        var go = SampleUtility.CreateBodyEffector(name, Vector3.zero, Quaternion.identity);
        return go;
    }
    private static GameObject CreateChestEffector(string name)
    {
        Quaternion roll = new Quaternion();
        roll.SetEulerAngles(0,0,0);
        var go = SampleUtility.CreateBodyEffector(name, Vector3.zero, roll);
        return go;
    }
    private GameObject SetupEffector(ref FullBodyIKJob.EffectorHandle handle, string name)
    {
        var go = CreateEffector(name);
        if (go != null)
        {
            go.AddComponent<Effector>();
            handle.effector = m_Animator.BindSceneTransform(go.transform);
            handle.positionWeight = m_Animator.BindSceneProperty(go.transform, typeof(Effector), "positionWeight");
            handle.rotationWeight = m_Animator.BindSceneProperty(go.transform, typeof(Effector), "rotationWeight");
            handle.pullWeight = m_Animator.BindSceneProperty(go.transform, typeof(Effector), "pullWeight");
        }
        return go;
    }

    private GameObject SetupHintEffector(ref FullBodyIKJob.HintEffectorHandle handle, string name)
    {
        var go = CreateEffector(name);
        if (go != null)
        {
            go.AddComponent<HintEffector>();
            handle.hint = m_Animator.BindSceneTransform(go.transform);
            handle.weight = m_Animator.BindSceneProperty(go.transform, typeof(HintEffector), "weight");
        }
        return go;
    }

    private GameObject SetupLookAtEffector(ref FullBodyIKJob.LookEffectorHandle handle, string name)
    {
        var go = CreateEffector(name);
        if (go != null)
        {
            go.AddComponent<LookAtEffector>();
            handle.lookAt = m_Animator.BindSceneTransform(go.transform);
            handle.eyesWeight = m_Animator.BindSceneProperty(go.transform, typeof(LookAtEffector), "eyesWeight");
            handle.headWeight = m_Animator.BindSceneProperty(go.transform, typeof(LookAtEffector), "headWeight");
            handle.bodyWeight = m_Animator.BindSceneProperty(go.transform, typeof(LookAtEffector), "bodyWeight");
            handle.clampWeight = m_Animator.BindSceneProperty(go.transform, typeof(LookAtEffector), "clampWeight");
        }
        return go;
    }

    private GameObject SetupBodyEffector(ref FullBodyIKJob.BodyEffectorHandle handle, string name)
    {
        var go = CreateBodyEffector(name);
        if (go != null)
        {
            handle.body = m_Animator.BindSceneTransform(go.transform);
        }
        return go;
    }
    private GameObject SetupChestEffector(ref FullBodyIKJob.ChestEffectorHandle handle,string name, HumanBodyBones boneName)
    {
        var go = CreateBodyEffector(name);
        if (go != null)
        {
            handle.chest = m_Animator.BindSceneTransform(go.transform);
            handle.chestBoneStream = m_Animator.BindStreamTransform(m_Animator.GetBoneTransform(boneName));

        }
        return go;
    }
    private void SetupIKLimbHandle(ref FullBodyIKJob.IKLimbHandle handle, HumanBodyBones top, HumanBodyBones middle, HumanBodyBones end)
    {
        handle.top = m_Animator.BindStreamTransform(m_Animator.GetBoneTransform(top));
        handle.middle = m_Animator.BindStreamTransform(m_Animator.GetBoneTransform(middle));
        handle.end = m_Animator.BindStreamTransform(m_Animator.GetBoneTransform(end));
    }

    private void ResetIKWeight()
    {
        m_LeftFootEffector.GetComponent<Effector>().positionWeight = defaultEffectorPositionWeight;
        m_LeftFootEffector.GetComponent<Effector>().rotationWeight = defaultEffectorRotationWeight;
        m_LeftFootEffector.GetComponent<Effector>().pullWeight = defaultEffectorPullWeight;
        m_RightFootEffector.GetComponent<Effector>().positionWeight = defaultEffectorPositionWeight;
        m_RightFootEffector.GetComponent<Effector>().rotationWeight = defaultEffectorRotationWeight;
        m_RightFootEffector.GetComponent<Effector>().pullWeight = defaultEffectorPullWeight;
        m_LeftHandEffector.GetComponent<Effector>().positionWeight = defaultEffectorPositionWeight;
        m_LeftHandEffector.GetComponent<Effector>().rotationWeight = defaultEffectorRotationWeight;
        m_LeftHandEffector.GetComponent<Effector>().pullWeight = defaultEffectorPullWeight;
        m_RightHandEffector.GetComponent<Effector>().positionWeight = defaultEffectorPositionWeight;
        m_RightHandEffector.GetComponent<Effector>().rotationWeight = defaultEffectorRotationWeight;
        m_RightHandEffector.GetComponent<Effector>().pullWeight = defaultEffectorPullWeight;

        m_LeftKneeHintEffector.GetComponent<HintEffector>().weight = defaultHintWeight;
        m_RightKneeHintEffector.GetComponent<HintEffector>().weight = defaultHintWeight;
        m_LeftElbowHintEffector.GetComponent<HintEffector>().weight = defaultHintWeight;
        m_RightElbowHintEffector.GetComponent<HintEffector>().weight = defaultHintWeight;
    }
    public Transform[] targetTrans=new Transform[0];

    private void SyncIKFromPose()
    {
        var selectedTransform = targetTrans;

        var stream = new AnimationStream();
        if (m_Animator.OpenAnimationStream(ref stream))
        {
            AnimationHumanStream humanStream = stream.AsHuman();

            // don't sync if transform is currently selected
            if (!Array.Exists(selectedTransform, tr => tr == m_LeftFootEffector.transform))
            {
                m_LeftFootEffector.transform.position = humanStream.GetGoalPositionFromPose(AvatarIKGoal.LeftFoot);
                m_LeftFootEffector.transform.rotation = humanStream.GetGoalRotationFromPose(AvatarIKGoal.LeftFoot);
            }

            if (!Array.Exists(selectedTransform, tr => tr == m_RightFootEffector.transform))
            {
                m_RightFootEffector.transform.position = humanStream.GetGoalPositionFromPose(AvatarIKGoal.RightFoot);
                m_RightFootEffector.transform.rotation = humanStream.GetGoalRotationFromPose(AvatarIKGoal.RightFoot);
            }

            if (!Array.Exists(selectedTransform, tr => tr == m_LeftHandEffector.transform))
            {
                m_LeftHandEffector.transform.position = humanStream.GetGoalPositionFromPose(AvatarIKGoal.LeftHand);
                m_LeftHandEffector.transform.rotation = humanStream.GetGoalRotationFromPose(AvatarIKGoal.LeftHand);
            }

            if (!Array.Exists(selectedTransform, tr => tr == m_RightHandEffector.transform))
            {
                m_RightHandEffector.transform.position = humanStream.GetGoalPositionFromPose(AvatarIKGoal.RightHand);
                m_RightHandEffector.transform.rotation = humanStream.GetGoalRotationFromPose(AvatarIKGoal.RightHand);
            }

            if (!Array.Exists(selectedTransform, tr => tr == m_LeftKneeHintEffector.transform))
            {
                m_LeftKneeHintEffector.transform.position = humanStream.GetHintPosition(AvatarIKHint.LeftKnee);
            }

            if (!Array.Exists(selectedTransform, tr => tr == m_RightKneeHintEffector.transform))
            {
                m_RightKneeHintEffector.transform.position = humanStream.GetHintPosition(AvatarIKHint.RightKnee);
            }

            if (!Array.Exists(selectedTransform, tr => tr == m_LeftElbowHintEffector.transform))
            {
                m_LeftElbowHintEffector.transform.position = humanStream.GetHintPosition(AvatarIKHint.LeftElbow);
            }

            if (!Array.Exists(selectedTransform, tr => tr == m_RightElbowHintEffector.transform))
            {
                m_RightElbowHintEffector.transform.position = humanStream.GetHintPosition(AvatarIKHint.RightElbow);
            }

            if (!Array.Exists(selectedTransform, tr => tr == m_BodyRotationEffector.transform))
            {
                m_BodyRotationEffector.transform.position = humanStream.bodyPosition;
                m_BodyRotationEffector.transform.rotation = humanStream.bodyRotation;
            }
            if (!Array.Exists(selectedTransform, tr => tr == m_ChestRotationEffector.transform))
            {
                m_ChestRotationEffector.transform.position = job.chestEffector.chestBoneStream.GetPosition(stream);

               // m_ChestRotationEffector.transform.localRotation = job.chestEffector.chestBoneStream.GetRotation(stream);
            }

            m_Animator.CloseAnimationStream(ref stream);
        }
    }
    FullBodyIKJob job;

    void OnEnable()
    {
        m_Animator = GetComponent<Animator>();

        // Setting to Always animate because on the first frame the renderer can be not visible which break syncGoal on start up
        m_Animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;

        if (!m_Animator.avatar.isHuman)
            throw new InvalidOperationException("Avatar must be a humanoid.");

        m_Graph = PlayableGraph.Create();
        m_Graph.SetTimeUpdateMode(DirectorUpdateMode.GameTime);
        var output = AnimationPlayableOutput.Create(m_Graph, "output", m_Animator);

        var clip = SampleUtility.LoadAnimationClipFromFbx("DefaultMale/Models/DefaultMale_Humanoid", "Idle");
        var clipPlayable = AnimationClipPlayable.Create(m_Graph, clip);
        clipPlayable.SetApplyFootIK(false);
        clipPlayable.SetApplyPlayableIK(false);

         job = new FullBodyIKJob();
        job.stiffness = stiffness;
        job.maxPullIteration = maxPullIteration;

        SetupIKLimbHandle(ref job.leftArm, HumanBodyBones.LeftUpperArm, HumanBodyBones.LeftLowerArm, HumanBodyBones.LeftHand);
        SetupIKLimbHandle(ref job.rightArm, HumanBodyBones.RightUpperArm, HumanBodyBones.RightLowerArm, HumanBodyBones.RightHand);
        SetupIKLimbHandle(ref job.leftLeg, HumanBodyBones.LeftUpperLeg, HumanBodyBones.LeftLowerLeg, HumanBodyBones.LeftFoot);
        SetupIKLimbHandle(ref job.rightLeg, HumanBodyBones.RightUpperLeg, HumanBodyBones.RightLowerLeg, HumanBodyBones.RightFoot);
      
        m_LeftFootEffector = SetupEffector(ref job.leftFootEffector, "LeftFootEffector");
        m_RightFootEffector = SetupEffector(ref job.rightFootEffector, "RightFootEffector");
        m_LeftHandEffector = SetupEffector(ref job.leftHandEffector, "LeftHandEffector");
        m_RightHandEffector = SetupEffector(ref job.rightHandEffector, "RightHandEffector");

        m_LeftKneeHintEffector = SetupHintEffector(ref job.leftKneeHintEffector, "LeftKneeHintEffector");
        m_RightKneeHintEffector = SetupHintEffector(ref job.rightKneeHintEffector, "RightKneeHintEffector");
        m_LeftElbowHintEffector = SetupHintEffector(ref job.leftElbowHintEffector, "LeftElbowHintEffector");
        m_RightElbowHintEffector = SetupHintEffector(ref job.rightElbowHintEffector, "RightElbowHintEffector");

        m_LookAtEffector = SetupLookAtEffector(ref job.lookAtEffector, "LookAtEffector");

        m_BodyRotationEffector = SetupBodyEffector(ref job.bodyEffector, "BodyEffector");
        m_ChestRotationEffector = SetupChestEffector(ref job.chestEffector, "UpperChest", HumanBodyBones.UpperChest);
        m_ChestRotationEffector.transform.parent = m_BodyRotationEffector.transform;

        m_IKPlayable = AnimationScriptPlayable.Create(m_Graph, job, 1);
        m_IKPlayable.ConnectInput(0, clipPlayable, 0, 1.0f);

        output.SetSourcePlayable(m_IKPlayable);

        m_Graph.Play();
        m_Graph.Evaluate(0);
        SyncIKFromPose();

        ResetIKWeight();
    }

    void OnDisable()
    {
        GameObject.DestroyImmediate(m_LeftFootEffector);
        GameObject.DestroyImmediate(m_RightFootEffector);
        GameObject.DestroyImmediate(m_LeftHandEffector);
        GameObject.DestroyImmediate(m_RightHandEffector);
        GameObject.DestroyImmediate(m_LeftKneeHintEffector);
        GameObject.DestroyImmediate(m_RightKneeHintEffector);
        GameObject.DestroyImmediate(m_LeftElbowHintEffector);
        GameObject.DestroyImmediate(m_RightElbowHintEffector);
        GameObject.DestroyImmediate(m_LookAtEffector);
        GameObject.DestroyImmediate(m_BodyRotationEffector);
        GameObject.DestroyImmediate(m_ChestRotationEffector);

        if (m_Graph.IsValid())
            m_Graph.Destroy();
    }

    void Update()
    {
        var job = m_IKPlayable.GetJobData<FullBodyIKJob>();
        job.stiffness = stiffness;
        job.maxPullIteration = maxPullIteration;
        m_IKPlayable.SetJobData(job);
    }

    void LateUpdate()
    {
        // Synchronize on LateUpdate to sync goal on current frame
        if (syncGoal)
        {
            SyncIKFromPose();
            syncGoal = false;
        }

        // Synchronize the body position and the body effector position
        var job = m_IKPlayable.GetJobData<FullBodyIKJob>();
        m_BodyRotationEffector.transform.position = job.bodyPosition;

    }
}
using UnityEngine;
using UnityEngine.Experimental.Animations;
using Unity.Collections;

public struct FullBodyIKJob : IAnimationJob
{
    public struct EffectorHandle
    {
        public TransformSceneHandle effector;
        public PropertySceneHandle positionWeight;
        public PropertySceneHandle rotationWeight;
        public PropertySceneHandle pullWeight;
    }

    public struct HintEffectorHandle
    {
        public TransformSceneHandle hint;
        public PropertySceneHandle weight;
    }

    public struct LookEffectorHandle
    {
        public TransformSceneHandle lookAt;
        public PropertySceneHandle eyesWeight;
        public PropertySceneHandle headWeight;
        public PropertySceneHandle bodyWeight;
        public PropertySceneHandle clampWeight;
    }

    public struct BodyEffectorHandle
    {
        public TransformSceneHandle body;
      //  public PropertySceneHandle positionWeight;


    }
    public struct ChestEffectorHandle
    {
        public TransformSceneHandle chest;
      //  public PropertySceneHandle positionWeight;
        public TransformStreamHandle chestBoneStream;

    }
    public EffectorHandle leftFootEffector;
    public EffectorHandle rightFootEffector;
    public EffectorHandle leftHandEffector;
    public EffectorHandle rightHandEffector;

    public HintEffectorHandle leftKneeHintEffector;
    public HintEffectorHandle rightKneeHintEffector;
    public HintEffectorHandle leftElbowHintEffector;
    public HintEffectorHandle rightElbowHintEffector;

    public LookEffectorHandle lookAtEffector;

    public BodyEffectorHandle bodyEffector;
    public ChestEffectorHandle chestEffector;
    public Vector3 bodyPosition;

    public struct IKLimbHandle
    {
        public TransformStreamHandle top;
        public TransformStreamHandle middle;
        public TransformStreamHandle end;
        public float maximumExtension;
    }

    public IKLimbHandle leftArm;
    public IKLimbHandle rightArm;
    public IKLimbHandle leftLeg;
    public IKLimbHandle rightLeg;

    public float stiffness;
    public int maxPullIteration;

    private EffectorHandle GetEffectorHandle(AvatarIKGoal goal)
    {
        switch (goal)
        {
            default:
            case AvatarIKGoal.LeftFoot: return leftFootEffector;
            case AvatarIKGoal.RightFoot: return rightFootEffector;
            case AvatarIKGoal.LeftHand: return leftHandEffector;
            case AvatarIKGoal.RightHand: return rightHandEffector;
        }
    }

    private IKLimbHandle GetIKLimbHandle(AvatarIKGoal goal)
    {
        switch (goal)
        {
            default:
            case AvatarIKGoal.LeftFoot: return leftLeg;
            case AvatarIKGoal.RightFoot: return rightLeg;
            case AvatarIKGoal.LeftHand: return leftArm;
            case AvatarIKGoal.RightHand: return rightArm;
        }
    }

    private void SetEffector(AnimationStream stream, AvatarIKGoal goal, ref EffectorHandle handle)
    {
        if (handle.effector.IsValid(stream) && handle.positionWeight.IsValid(stream) && handle.rotationWeight.IsValid(stream))
        {
            AnimationHumanStream humanStream = stream.AsHuman();
            humanStream.SetGoalPosition(goal, handle.effector.GetPosition(stream));
            humanStream.SetGoalRotation(goal, handle.effector.GetRotation(stream));
            humanStream.SetGoalWeightPosition(goal, handle.positionWeight.GetFloat(stream));
            humanStream.SetGoalWeightRotation(goal, handle.rotationWeight.GetFloat(stream));
        }
    }

    private void SetHintEffector(AnimationStream stream, AvatarIKHint goal, ref HintEffectorHandle handle)
    {
        if (handle.hint.IsValid(stream) && handle.weight.IsValid(stream))
        {
            AnimationHumanStream humanStream = stream.AsHuman();
            humanStream.SetHintPosition(goal, handle.hint.GetPosition(stream));
            humanStream.SetHintWeightPosition(goal, handle.weight.GetFloat(stream));
        }
    }

    private void SetLookAtEffector(AnimationStream stream, ref LookEffectorHandle handle)
    {
        if (handle.lookAt.IsValid(stream))
        {
            AnimationHumanStream humanStream = stream.AsHuman();
            humanStream.SetLookAtPosition(handle.lookAt.GetPosition(stream));
            humanStream.SetLookAtEyesWeight(handle.eyesWeight.GetFloat(stream));
            humanStream.SetLookAtHeadWeight(handle.headWeight.GetFloat(stream));
            humanStream.SetLookAtBodyWeight(handle.bodyWeight.GetFloat(stream));
            humanStream.SetLookAtClampWeight(handle.clampWeight.GetFloat(stream));
        }
    }

    private void SetBodyEffector(AnimationStream stream, ref BodyEffectorHandle handle)
    {
        if (handle.body.IsValid(stream))
        {
            AnimationHumanStream humanStream = stream.AsHuman();
            humanStream.bodyRotation = handle.body.GetRotation(stream);
            humanStream.bodyPosition = handle.body.GetPosition(stream);

        }
    }
    private void SetChestEffector(AnimationStream stream,  ref ChestEffectorHandle handle)
    {
        if (handle.chest.IsValid(stream))
        {
            // AnimationHumanStream humanStream = stream.AsHuman();

            // humanStream. = handle.chest.GetRotation(stream);
            // stream.(goal, handle.chest.GetRotation(stream));
            handle.chestBoneStream.SetLocalRotation(stream,handle.chest.GetLocalRotation(stream));
           // handle.chestBoneStream.SetRotation(stream, handle.chest.GetRotation(stream));

            handle.chestBoneStream.SetPosition(stream,handle.chest.GetPosition(stream));

        }
    }
    private void SetMaximumExtension(AnimationStream stream, ref IKLimbHandle handle)
    {
        if (handle.maximumExtension == 0)
        {
            Vector3 top = handle.top.GetPosition(stream);
            Vector3 middle = handle.middle.GetPosition(stream);
            Vector3 end = handle.end.GetPosition(stream);

            Vector3 localMiddle = middle - top;
            Vector3 localEnd = end - middle;

            handle.maximumExtension = localMiddle.magnitude + localEnd.magnitude;
        }
    }

    struct LimbPart
    {
        public Vector3 localPosition;    // local position of this limb relative to body position
        public Vector3 goalPosition;
        public float   goalWeight;
        public float   goalPullWeight;
        public float   maximumExtension; // maximum extension of the limb which define when the pull solver start to pull on the body (spring rest lenght)
        public float   stiffness;        // stiffness of the limb, at 0 the limb is loosen, at 1 the limb is really stiff
    }

    private void PrepareSolvePull(AnimationStream stream, NativeArray<LimbPart> limbParts)
    {
        AnimationHumanStream humanStream = stream.AsHuman();

        Vector3 bodyPosition = humanStream.bodyPosition;

        for (int goalIter = 0; goalIter < 4; goalIter++)
        {
            var effector = GetEffectorHandle((AvatarIKGoal)goalIter);
            var limbHandle = GetIKLimbHandle((AvatarIKGoal)goalIter);
            Vector3 top = limbHandle.top.GetPosition(stream);

            limbParts[goalIter] = new LimbPart {
                localPosition = top - bodyPosition,
                goalPosition = humanStream.GetGoalPosition((AvatarIKGoal)goalIter),
                goalWeight = humanStream.GetGoalWeightPosition((AvatarIKGoal)goalIter),
                goalPullWeight = effector.pullWeight.GetFloat(stream),
                maximumExtension = limbHandle.maximumExtension,
                stiffness = stiffness
            };
        }
    }

    private Vector3 SolvePull(AnimationStream stream)
    {
        AnimationHumanStream humanStream = stream.AsHuman();

        Vector3 originalBodyPosition = humanStream.bodyPosition;
        Vector3 bodyPosition = originalBodyPosition;

        NativeArray<LimbPart> limbParts = new NativeArray<LimbPart>(4, Allocator.Temp);
        PrepareSolvePull(stream, limbParts);
       
        for (int iter = 0; iter < maxPullIteration; iter++)
        {
            Vector3 deltaPosition = Vector3.zero;
            for (int goalIter = 0; goalIter < 4; goalIter++)
            {
                Vector3 top = bodyPosition + limbParts[goalIter].localPosition;
                Vector3 localForce = limbParts[goalIter].goalPosition - top;
                float restLenght = limbParts[goalIter].maximumExtension;
                float currentLenght = localForce.magnitude;

                localForce.Normalize();

                var force = Mathf.Max( limbParts[goalIter].stiffness * (currentLenght - restLenght), 0.0f);

                deltaPosition += (localForce * force * limbParts[goalIter].goalPullWeight * limbParts[goalIter].goalWeight);
            }

            deltaPosition /= (maxPullIteration - iter);
            bodyPosition += deltaPosition;
        }

        limbParts.Dispose();

        return bodyPosition - originalBodyPosition;
    }

    private void Solve(AnimationStream stream)
    {
        AnimationHumanStream humanStream = stream.AsHuman();

        bodyPosition = humanStream.bodyPosition;
        Vector3 bodyPositionDelta = SolvePull(stream);

        bodyPosition += bodyPositionDelta;
        humanStream.bodyPosition = bodyPosition;
 

        humanStream.SolveIK();
    }

    public void ProcessRootMotion(AnimationStream stream) { }

    public void ProcessAnimation(AnimationStream stream)
    {
       SetChestEffector(stream, ref chestEffector);

        SetMaximumExtension(stream, ref leftArm);
        SetMaximumExtension(stream, ref rightArm);
        SetMaximumExtension(stream, ref leftLeg);
        SetMaximumExtension(stream, ref rightLeg);

        SetEffector(stream, AvatarIKGoal.LeftFoot, ref leftFootEffector);
        SetEffector(stream, AvatarIKGoal.RightFoot, ref rightFootEffector);
        SetEffector(stream, AvatarIKGoal.LeftHand, ref leftHandEffector);
        SetEffector(stream, AvatarIKGoal.RightHand, ref rightHandEffector);

        SetHintEffector(stream, AvatarIKHint.LeftKnee, ref leftKneeHintEffector);
        SetHintEffector(stream, AvatarIKHint.RightKnee, ref rightKneeHintEffector);
        SetHintEffector(stream, AvatarIKHint.LeftElbow, ref leftElbowHintEffector);
        SetHintEffector(stream, AvatarIKHint.RightElbow, ref rightElbowHintEffector);

        SetLookAtEffector(stream, ref lookAtEffector);

        SetBodyEffector(stream, ref bodyEffector);

        Solve(stream);

    }
}
1 Like

Hi, I have been struggling with this script since last day. The major problem I am facing is that, as soon as I start updating IK, it resets the rotation of my character to Zero with respect to global axis and does not take care of my model rotations. I found this was some thing related to FullBodyIKJob script where rotations are set. Second thing, if my model character has some other scale than 1, then the affectors are not auto updated according to the scale and their initial default positions are as if the avatar is having scale of 1 which obviously distorts my model. If the scale of the model is 1 and the rotations are zero then it works perfect. Can any body help me in this? If some pictures are needed let me know I will share. I am using Unity 2018.4.10f but Now I am downloading unity 2019 hoping that the new Rigging Package may have full body IK support.

PS : The scripts I am using, I took from git hub page below

Hi, I finally got it working.
Regarding rotation,
I added a line in FullBodyIK script. Where new animation stream is defined, i.e.

AnimationHumanStream humanStream = stream.AsHuman();

I added below line after this and it solved the rotation problem that is now when I hit play, the rotation of the player is in matching the original rotation of the player before hitting play button.

humanStream.bodyRotation = transform.rotation;

And regarding scale, what I did Instead of changing scale in the inspector, I changed the scale in model settings because in this way, the scale of the Avatar is also changed and when I hit play, there is not more problem of the scale. But in this way, I can use the model only for the one values of scale. But this is not an issue for me as I am using this script only for my one main character.

Regards,