当前位置: 首页 > 工具软件 > BS.Play > 使用案例 >

人物骨骼的BS操作

狄宇
2023-12-01

将两个Avatar做lerp操作


public class BlendSkeleton : MonoBehaviour
{
    public Animator animator;
    private Avatar sourceAvatar;
    public Avatar targetAvatar;
    private Vector3 posForReset;
    private Quaternion rotForReset;
    public float Alpha
    {
        get => alpha;
        set
        {
            alpha = value;
            ResetAvatar();
        }
    }
    private float alpha = 0f;

    private void Awake()
    {
        if (animator == null)
        {
            bool found = TryGetComponent(out animator);
            if (!found)
            {
                Debug.LogError("No animator found!");
            }
        }
        sourceAvatar = animator.avatar;
    }

    void ResetAvatar()
    {
        float time = animator.GetCurrentAnimatorStateInfo(0).normalizedTime;
        posForReset = transform.localPosition;
        rotForReset = transform.localRotation;
        Avatar avatar = LerpAvatars(gameObject, sourceAvatar, targetAvatar, alpha);
        animator.avatar = avatar;
        animator.Play("Idle", -1, time);
        transform.localPosition = posForReset;
        transform.localRotation = rotForReset;
    }


    public static Avatar LerpAvatars(GameObject root, Avatar a, Avatar b, float t)
    {
        HumanDescription aH = a.humanDescription;
        HumanDescription bH = b.humanDescription;
        var humanDescription = aH;
        humanDescription.armStretch = Mathf.Lerp(aH.armStretch, bH.armStretch, t);
        humanDescription.feetSpacing = Mathf.Lerp(aH.feetSpacing, bH.feetSpacing, t);
        humanDescription.hasTranslationDoF = t > 0.5f ? bH.hasTranslationDoF : aH.hasTranslationDoF;
        humanDescription.legStretch = Mathf.Lerp(aH.legStretch, bH.legStretch, t);
        humanDescription.lowerArmTwist = Mathf.Lerp(aH.lowerArmTwist, bH.lowerArmTwist, t);
        humanDescription.upperArmTwist = Mathf.Lerp(aH.upperArmTwist, bH.upperArmTwist, t);
        humanDescription.lowerLegTwist = Mathf.Lerp(aH.lowerLegTwist, bH.lowerLegTwist, t);
        humanDescription.upperLegTwist = Mathf.Lerp(aH.upperLegTwist, bH.upperLegTwist, t);
        var aHSkeleton = aH.skeleton;
        var aHHuman = aH.human;
        var bHSkeleton = bH.skeleton;
        var bHHuman = bH.human;
        var skeletonBones = new SkeletonBone[aHSkeleton.Length];
        humanDescription.skeleton = skeletonBones;
        var humanBones = new HumanBone[aHHuman.Length];
        humanDescription.human = humanBones;
        for (int i = 0; i < humanDescription.skeleton.Length; i++)
        {
            float alpha = (aHSkeleton[i].name == bHSkeleton[i].name) ? t : 0f;
            var skelement = new SkeletonBone
            {
                rotation = Quaternion.Slerp(aHSkeleton[i].rotation, bHSkeleton[i].rotation, alpha),
                position = Vector3.Lerp(aHSkeleton[i].position, bHSkeleton[i].position, alpha),
                scale = Vector3.Lerp(aHSkeleton[i].scale, bHSkeleton[i].scale, alpha),
                name = aHSkeleton[i].name
            };
            skeletonBones[i] = skelement;
        }
        for (int i = 0; i < humanDescription.human.Length; i++)
        {
            if (aHHuman[i].boneName != bHHuman[i].boneName)
            {
                throw new InvalidOperationException("Skeleton arrays do not match, were these produced from the same original skeleton?");
            }
            var bone = new HumanBone
            {
                boneName = aHHuman[i].boneName,
                humanName = aHHuman[i].humanName,
                limit = new HumanLimit
                {
                    max = Vector3.Lerp(aHHuman[i].limit.max, bHHuman[i].limit.max, t),
                    axisLength = Mathf.Lerp(aHHuman[i].limit.axisLength, bHHuman[i].limit.axisLength, t),
                    center = Vector3.Lerp(aHHuman[i].limit.center, bHHuman[i].limit.center, t),
                    min = Vector3.Lerp(aHHuman[i].limit.min, bHHuman[i].limit.min, t),
                    useDefaultValues = t > 0.5f ? aHHuman[i].limit.useDefaultValues : bHHuman[i].limit.useDefaultValues
                }
            };
            humanBones[i] = bone;
        }
        humanDescription.skeleton = skeletonBones;
        humanDescription.human = humanBones;
        return AvatarBuilder.BuildHumanAvatar(root, humanDescription);
    }
}

 类似资料: