• Unity动画系统Animator动态添加事件


    之前一直都是手动给模型动画添加事件,最近在做项目的时候,感觉很麻烦,而且经常要改,就变的更麻烦了。于是就在网上查了下,事件是可以在运行时自动添加的,在此记录一下,免得自己以后忘了。

    现在有一个模型和动画控制器如下:

    很简单,没有什么骚操作。并在模型上挂了一个 Test 脚本,我在 Test 脚本里,分别在动画的开始,结束,和播放一半的时候添加事件。运行打印如下:

    截图没办法很好的表示动态效果,大家可以自己尝试一下,代码如下,逻辑很简单,就不多说了:

     1 using UnityEngine;
     2 
     3 public class Test : MonoBehaviour
     4 {
     5     #region --变量定义
     6     private Animator animator;
     7     private AnimationClip[] clips;
     8     #endregion
     9 
    10     #region --系统函数
    11     private void Start()
    12     {
    13         animator = this.GetComponent<Animator>();
    14         clips = animator.runtimeAnimatorController.animationClips;
    15 
    16         AnimationClip _clip = clips[0];
    17         AddAnimationEvent(animator, _clip.name, "StartEvent", 0);
    18         AddAnimationEvent(animator, _clip.name, "HalfEvent", _clip.length * 0.5f);
    19         AddAnimationEvent(animator, _clip.name, "EndEvent", _clip.length);
    20     }
    21     private void OnDestroy()
    22     {
    23         CleanAllEvent();
    24     }
    25     #endregion
    26 
    27     #region --自定义函数
    28     private void StartEvent()
    29     {
    30         Debug.Log("开始播放动画");
    31     }
    32     private void HalfEvent()
    33     {
    34         Debug.Log("动画播放了一半");
    35     }
    36     private void EndEvent()
    37     {
    38         Debug.Log("播放动画完毕");
    39     }
    40 
    41     /// <summary>
    42     /// 添加动画事件
    43     /// </summary>
    44     /// <param name="_animator"></param>
    45     /// <param name="_clipName">动画名称</param>
    46     /// <param name="_eventFunctionName">事件方法名称</param>
    47     /// <param name="_time">添加事件时间。单位:秒</param>
    48     private void AddAnimationEvent(Animator _animator, string _clipName, string _eventFunctionName, float _time)
    49     {
    50         AnimationClip[] _clips = _animator.runtimeAnimatorController.animationClips;
    51         for (int i = 0; i < _clips.Length; i++)
    52         {
    53             if (_clips[i].name == _clipName)
    54             {
    55                 AnimationEvent _event = new AnimationEvent();
    56                 _event.functionName = _eventFunctionName;
    57                 _event.time = _time;
    58                 _clips[i].AddEvent(_event);
    59                 break;
    60             }
    61         }
    62         _animator.Rebind();
    63     }
    64     /// <summary>
    65     /// 清除所有事件
    66     /// </summary>
    67     private void CleanAllEvent()
    68     {
    69         for (int i = 0; i < clips.Length; i++)
    70         {
    71             clips[i].events = default(AnimationEvent[]);
    72         }
    73         Debug.Log("清除所有事件");
    74     }
    75     #endregion
    76 }

    有一点需要注意,事件添加过一次后,就会一直存在,除非关闭程序。也就是说,如果你实例化一个模型,并且在 Start 函数里执行添加 事件的逻辑,如果这个模型被实例化了两次,事件就会被添加两次。所以我建议大家像我这样,在 OnDestroy 函数里对事件进行清空处理。

  • 相关阅读:
    javascript学习随笔《四》
    google卫星地图地图矫正
    sharpmap v2学习研究(二)
    c#中的位运算,逻辑非~,逻辑与&,逻辑或|,逻辑异或^,逻辑左移<<,逻辑右移>>
    如何判断一个form是否被关闭
    List转DataTable(反射)
    c#位运算
    解决ASP.NET中的各种乱码问题 转自 Fish Li
    IHE自测MESA环境搭建详解
    HTTP协议请求 转
  • 原文地址:https://www.cnblogs.com/xiaoyulong/p/10853287.html
Copyright © 2020-2023  润新知