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);
			}
			
		}
	}
}

目录结构

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Prosper Lee

您的赏赐将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值