在 Unity 中为 Animator 动画动态添加事件的原理主要涉及到利用 Unity 提供的动画事件系统和相关 API,下面从动画事件系统的工作机制、动态添加事件的步骤和原理详细展开:
动画事件系统工作机制
Unity 的动画事件系统允许开发者在动画播放的特定时间点触发自定义的函数。当动画播放到设置了动画事件的关键帧时,Unity 会自动调用与之关联的函数。这些事件可以用于触发音效、改变游戏状态、执行特定的逻辑等。动画事件本质上是将动画的播放过程与脚本中的函数进行关联,从而实现动画与游戏逻辑的交互。
动态添加事件的步骤及原理
- 获取动画剪辑(AnimationClip)
要为动画添加事件,首先需要获取对应的动画剪辑对象。动画剪辑是包含动画数据的资源,存储了动画的关键帧、运动轨迹等信息。可以通过以下方式获取动画剪辑:
废话不多说了,直接上代码哦,代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AnimatorEc : MonoBehaviour {
public Animator ani;//人物的动画状态机
public TrailRenderer trail; //拖尾效果
private AnimationClip[] clips; //动画的集合
// Use this for initialization
void Start () {
clips = ani.runtimeAnimatorController.animationClips;
AnimationClip clip = clips[1]; //因为我的是在第二个,用的话需要自己设定clip[int]
AddAnimationEvent(ani, clip.name, "StartEvent", 0);
AddAnimationEvent(ani, clip.name, "HalfEvent", clip.length * 0.5f);
AddAnimationEvent(ani, clip.name, "EndEvent", clip.length);
}
private void Update()
{
if (Input.GetMouseButtonDown (0))
{
ani.SetBool("fack", true);
}
else
{
ani.SetBool("fack", false);
}
}
/// <summary>
/// 给动画添加新的事件
/// </summary>
/// <param name="_Animator"> 人物的状态机</param>
/// <param name="_ClipName">动画的名称</param>
/// <param name="_EventFunctionName">时间/秒</param>
/// <param name="_time"></param>
private void AddAnimationEvent(Animator _Animator, string _ClipName, string _EventFunctionName, float _time)
{
AnimationClip[] _clips = _Animator.runtimeAnimatorController.animationClips;
for (int i = 0; i<_clips.Length; i++)
{
if (_clips[i].name == _ClipName)
{
AnimationEvent _event = new AnimationEvent();
_event.functionName = _EventFunctionName;
_event.time = _time;
_clips[i].AddEvent(_event);
break;
}
}
_Animator.Rebind();
}
private void StartEvent()
{
Debug.Log("开始播放动画");
}
private void HalfEvent()
{
trail.emitting = true;
Debug.Log("动画放到一半的时候");
}
private void EndEvent()
{
trail.emitting = false;
Debug.Log("动画结束的时候");
}
/// <summary>
/// 清除所有的事件
/// </summary>
private void ClearAllEvent()
{
for (int i = 0; i<clips.Length; i++)
{
clips[i].events = default(AnimationEvent[]);
}
Debug.Log("清除所有事件");
}
private void OnDestroy()
{
ClearAllEvent();
}
}
最后自行测试即可