Unity 动态为AnimationClip 注入事件的小工具类

来源:互联网 发布:博雅大数据学院 官网 编辑:程序博客网 时间:2024/06/01 09:36

需求来源:美术每次改动画,程序都要重新把AnimEvent加入AnimationClip一遍,这不科学。(其实这事情也可以给策划做,但是策划太蠢了。)


于是我写了一个小工具类,可以动态注入Anim事件,只要AnimClip的名字不改,一切都会是那么的美好。


配置图:




代码如下:


using System.Collections;using System.Collections.Generic;using UnityEngine;public class AnimationEventInjector : MonoBehaviour{    [System.Serializable]    public class InjectEvent    {        public string TargetClip;        public string FunctionName;        public string stringParam;        public int intParam;        public float floatParam;        [Space]        [Range(0.0f, 1.0f)]        public float InjectPosition;                public UnityEngine.AnimationEvent GetAnimEvent(float total_length)        {            UnityEngine.AnimationEvent AnimEvent = new UnityEngine.AnimationEvent();            AnimEvent.time = total_length * InjectPosition;            AnimEvent.functionName = FunctionName;            AnimEvent.intParameter = intParam;            AnimEvent.stringParameter = stringParam;            AnimEvent.floatParameter = floatParam;            return AnimEvent;        }    }    [SerializeField]    InjectEvent[] inject_events;    Dictionary<string, AnimationClip> clip_index = new Dictionary<string, AnimationClip>();    public void Inject( Animator target_animator )    {        clip_index.Clear();                if (target_animator != null)        {            RuntimeAnimatorController runtime_ctrl = target_animator.runtimeAnimatorController;            AnimationClip[] clips = runtime_ctrl.animationClips;            foreach (var clip in clips)            {                clip_index[clip.name] = clip;            }                                    foreach (var injectE in inject_events)            {                AnimationClip clip = null;                clip_index.TryGetValue(injectE.TargetClip, out clip);                if (clip != null)                {                                        clip.AddEvent(injectE.GetAnimEvent( clip.length ));                    Debug.Log("Event injected for command " + injectE.stringParam );                }                else                {                    Debug.Log( "<color=red> Clip with name "+ injectE.TargetClip + " is not exist! </color>");                }            }            target_animator.Rebind();        }    }}



注意1:需要手动调用Inject函数进行初始化

注意2:Inject Position 是时间百分比,程序会换算成秒,并且给AnimationEvent.time赋值,我个人认为这样做最方便,但是如果你希望填精确时间可以自己调节一下代码。