Unity(三十七):3D模型动画、脚本控制模型骨骼IK动画

效果(左侧模型动画,右侧模型IK控制)

在这里插入图片描述

模型动画下载及导入

推荐模型动画下载链接地址
https://actorcore.reallusion.com/
Unity导入教程参见以下链接地址(需要科学上网)
https://actorcore.reallusion.com/learn-and-support/my-software/unity/getting-started
在这里插入图片描述
导入完成后模型相关查看
在这里插入图片描述
在这里插入图片描述

配置模型动画控制器

  • 拖拽模型预设到视图中
    在这里插入图片描述
  • 配置动画控制器(可自定义动画控制器)
    • 创建新的控制器状态,向Motion属性中添加模型中的动画
      在这里插入图片描述
  • 通过修改Status属性来改变播放的动画

监听动画状态的脚本

using UnityEngine;

public class DanceAnimStateMachine : StateMachineBehaviour
{
    
    
    // 进入当前状态时
    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
    
    
        Debug.Log($"进入当前状态时");
    }

    // 当前状态更新时,每帧都会被调用
    override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
    
    
       Debug.Log($"当前状态更新时,每帧都会被调用");
    }

    // 离开当前状态时
    override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
    
    
       Debug.Log($"离开当前状态时");
    }

    // 在Animator.OnAnimatorMove()之后调用,这里可以处理动画根节点的位移
    override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
    
    
       Debug.Log($"在Animator.OnAnimatorMove()之后调用,这里可以处理动画根节点的位移");
    }

    // 在Animator.OnAnimatorIK()之后调用,这里可以处理IK(反向运动学)动画
    override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
    
    
       Debug.Log($"在Animator.OnAnimatorIK()之后调用,这里可以处理IK(反向运动学)动画");
    }
}

脚本控制模型骨骼IK动画

创建自己的动画控制器
添加 T-Pose 动画到控制器
启用 IK Pass
在这里插入图片描述

模型骨骼IK控制脚本

using UnityEngine;

namespace Example_01.Scripts
{
    
    
	public class ModelAnimByIK : MonoBehaviour
	{
    
    
		private Animator _animator;
		public Transform leftHandObj;
		public Transform leftFootObj;
		public Transform rightHandObj;
		public Transform rightFootObj;

		private void Awake()
		{
    
    
			_animator = GetComponent<Animator>();
		}

		private void OnAnimatorIK(int layerIndex)
		{
    
    
			if (!_animator) return;

			// 设置动画权重
			_animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1f);
			_animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1f);
			
			_animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 1f);
			_animator.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 1f);

			_animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1f);
			_animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1f);
			
			_animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, 1f);
			_animator.SetIKRotationWeight(AvatarIKGoal.RightFoot, 1f);

			if (leftHandObj != null)
			{
    
    
				// 设置左手根据目标点而旋转移动父骨骼节点
				_animator.SetIKPosition(AvatarIKGoal.LeftHand, leftHandObj.position);
				_animator.SetIKRotation(AvatarIKGoal.LeftHand, leftHandObj.rotation);
			}

			if (leftFootObj != null)
			{
    
    
				// 设置左脚根据目标点而旋转移动父骨骼节点
				_animator.SetIKPosition(AvatarIKGoal.LeftFoot, leftFootObj.position);
				_animator.SetIKRotation(AvatarIKGoal.LeftFoot, leftFootObj.rotation);
			}

			if (rightHandObj != null)
			{
    
    
				// 设置右手根据目标点而旋转移动父骨骼节点
				_animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandObj.position);
				_animator.SetIKRotation(AvatarIKGoal.RightHand, rightHandObj.rotation);
			}

			if (rightFootObj != null)
			{
    
    
				// 设置右脚根据目标点而旋转移动父骨骼节点
				_animator.SetIKPosition(AvatarIKGoal.RightFoot, rightFootObj.position);
				_animator.SetIKRotation(AvatarIKGoal.RightFoot, rightFootObj.rotation);
			}
			
		}
	}
}

目录结构

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43526371/article/details/123636537