在游戏开发中,角色的动画状态管理是非常重要的一部分。Unity 的 Mecanim 状态机系统 提供了强大的功能来控制和切换角色动画。本文将通过一篇完整的 C# 脚本示例,讲解如何使用 Unity 的 Animator 实现一个简单的“随机播放待机动画”的逻辑。
我们希望实现以下功能:
SiteIDE
)。Site_JiaoTan
, Site_JiaoTan2
等)。Animator.CrossFade
实现平滑过渡,并保证动画切换流畅自然。using UnityEngine;
[RequireComponent(typeof(Animator))]
public class MecanimRandomAnimation : MonoBehaviour
{
public string idleStateName = "SiteIDE";
public string[] otherAnimationNames = {
"Site_JiaoTan",
"Site_JiaoTan2",
"Site_JiaoTan3",
"Site_JiaoTan4",
"Site_DongZhangXiWang2"
};
[Tooltip("过渡时间(秒)")]
public float transitionDuration = 0.5f;
private Animator animator;
private int idleHash;
void Start()
{
// 初始化 Animator 和动画状态哈希值
}
void Update()
{
CheckIfIdleFinished();
}
void CheckIfIdleFinished()
{
// 检测当前动画是否播放完毕
}
void PlayRandomAnimation()
{
// 随机播放其他动画
}
private string GetAnimatorStateName(AnimatorStateInfo stateInfo)
{
// 获取当前动画名称用于调试
}
}
Start()
)我们首先获取组件并初始化相关变量:
void Start()
{
animator = GetComponent();
if (animator == null)
{
Debug.LogError("未找到 Animator 组件!");
return;
}
idleHash = Animator.StringToHash(idleStateName);
animator.Play(idleHash, 0, 0f); // 初始播放待机动画
}
⚠️ 注意:确保挂载脚本的对象上确实有
Animator
组件。
Update()
)每帧调用 CheckIfIdleFinished()
方法,用于判断当前动画是否播放完成:
void Update()
{
CheckIfIdleFinished();
}
CheckIfIdleFinished()
)这是整个逻辑的核心部分,我们通过 AnimatorStateInfo
来获取当前动画的状态信息:
void CheckIfIdleFinished()
{
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
bool isIdle = stateInfo.shortNameHash == idleHash;
bool isFinished = stateInfo.normalizedTime >= 1.0f;
bool notInTransition = !animator.IsInTransition(0);
if (isIdle && isFinished && notInTransition)
{
PlayRandomAnimation();
}
}
stateInfo.normalizedTime
: 归一化的播放进度,当其 ≥ 1 表示该动画已播放完一遍。animator.IsInTransition(0)
: 判断当前是否处于动画过渡状态,避免重复触发切换。stateInfo.shortNameHash
: 动画状态的唯一标识符,用于高效比较。PlayRandomAnimation()
)该方法会从 otherAnimationNames
中随机选择一个动画进行播放:
void PlayRandomAnimation()
{
int randomIndex = Random.Range(0, otherAnimationNames.Length);
string nextAnimName = otherAnimationNames[randomIndex];
int nextAnimHash = Animator.StringToHash(nextAnimName);
animator.CrossFade(nextAnimHash, transitionDuration, 0);
animator.Play(nextAnimHash, 0, 0f); // 强制跳转
}
使用
CrossFade
可以实现平滑过渡,而Play
则强制开始播放新动画。
GetAnimatorStateName()
)方便查看当前正在播放的动画名称,用于调试输出:
private string GetAnimatorStateName(AnimatorStateInfo stateInfo)
{
foreach (string name in otherAnimationNames)
{
if (stateInfo.shortNameHash == Animator.StringToHash(name))
{
return name;
}
}
if (stateInfo.shortNameHash == idleHash)
{
return idleStateName;
}
return "未知状态";
}
AnimatorController
管理状态之间的过渡逻辑。Update()
,减少性能消耗。本文通过一个完整的 Unity 脚本示例,演示了如何利用 Mecanim 系统实现一个基于播放完成的随机动画切换机制。这个思路可以广泛应用于 NPC 角色行为、角色空闲动作、AI 动作序列等场景中。
如果你正在制作 RPG、模拟类或休闲类游戏,这样的小技巧能大大提升角色表现力和真实感!
如果你觉得这篇文章对你有帮助,欢迎点赞、收藏或分享给更多开发者朋友!如果你对 Unity 动画系统还有其他疑问,也欢迎留言讨论