今天实现的内容:
添加shieldHandle
在人物模型合适的位置添加shieldHandle作为盾牌的位置,如图所示。
防御的IK方案
由于原本的Idle动画在装上盾牌以后看上去就像举着盾牌,这里我们可以通过OnAnimatorIK方法调整手臂位置(旋转)将盾牌放下来。
在使用OnAnimatorIK之前,我们需要在动画层设置中打开IK Pass,只有打开IK Pass,OnAnimatorIK才会被系统调用。IK Pass(IK 通道?)可以当成动画机会不会真的去计算IK的开关,我们对骨骼位置的修改也要经过IK Pass才行。
接下来,在模型游戏对象上挂载脚本,代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 用于调整模型骨骼左手臂的位置
public class LeftArmIK : MonoBehaviour
{
// 存储要调整的量
public Vector3 a;
private Animator m_anim;
private void Awake()
{
m_anim = GetComponent<Animator>();
}
private void OnAnimatorIK(int layerIndex)
{
// 获取要操作的具体骨骼的Transform 在这里是左手小臂
Transform leftLowerArm = m_anim.GetBoneTransform(HumanBodyBones.LeftLowerArm);
// 将要调整的量加上去 加到local坐标
leftLowerArm.localEulerAngles += a;
// 通过IK Pass设置骨骼旋转
m_anim.SetBoneLocalRotation(HumanBodyBones.LeftLowerArm, Quaternion.Euler(leftLowerArm.localEulerAngles));
}
}
我们将a调整到合适值,就能实现将手臂骨骼放下来。
站着不动时看着还不错,游戏角色跑起来看着就很僵硬了。但是这样做以后,我们甚至可以利用代码将手臂IK调整值清零来实现举盾,这也算是一种方案了。当然我们还是要用Avator Mask和现成的动画来实现。
防御的动画状态方案
假设我们没有使用上面的IK方案,而是添加新的动画进去。我们将加入新的动画层Defense,设置Weigh和Avatar Mask,添加idle和defense_oneHand动画节点,其中idle是放下盾的动画而defense_oneHand是举起盾的动画,添加新的Bool参数defense作为转换条件。
Avator Mask设置如图,让Defense层只影响左手,我们的项目目前还没有区分装备左右手。
防御状态代码
这个就很简单了,依旧是根据是否输入来设置一个defense信号,defense信号是按压信号。然后我们可以通过defense信号进一步设置动画机参数defense。动画状态方案直接SetBool就行了。
// 触发defense
anim.SetBool("defense", current_pi.defense);
不管使用何种方案,设置动画机参数defense都很有用,下面是我的IK方案的代码。当动画机参数defense为true时将手臂旋转调整量设置为举盾时的量(在这里Vector3.zero刚刚好),为false设置为放下时的量。采用Lerp做个渐变也行。
private void OnAnimatorIK(int layerIndex)
{
// 设置手臂的旋转最终目标
tmp_target = m_anim.GetBool("defense") ? Vector3.zero : a;
// 渐变tmp_currentEulerAngle
tmp_currentEulerAngle = Vector3.Lerp(tmp_currentEulerAngle, tmp_target, 0.3f);
// 获取要操作的具体骨骼的Transform 在这里是左手小臂
Transform leftLowerArm = m_anim.GetBoneTransform(HumanBodyBones.LeftLowerArm);
// 将要调整的量加上去 加到local坐标
leftLowerArm.localEulerAngles += tmp_currentEulerAngle;
// 通过IK Pass设置骨骼旋转
m_anim.SetBoneLocalRotation(HumanBodyBones.LeftLowerArm, Quaternion.Euler(leftLowerArm.localEulerAngles));
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。