Unity 代码实现Animator开始和结束播放动画回调

Unity 代码实现Animator开始和结束播放动画回调

码农世界 2024-05-27 后端 68 次浏览 0个评论

文章目录

  • 1.代码
  • 2.使用方式
  • 3.注意事项

    1.代码

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    // 播放Animator并加入播放完成回调。
    [RequireComponent(typeof(Animator))]
    public class AnimatorCallback : MonoBehaviour
    {
        private string startFunName = "StartCallBack";
        private string endFunName = "EndCallBack";
        private Animator mAnim;
        private AnimatorOverrideController mController;
        private Dictionary mClipDic = new Dictionary();
        private Action endCallBack;             // 动画结束回调
        private Action startCallBack;           // 动画开始回调
        private AnimationEvent endEvt;          // 结束帧
        private AnimationEvent startEvt;        // 结束帧
        public void Awake()
        {
            mController = new AnimatorOverrideController();
            mAnim = transform.GetComponent();
            ResetEvent();
            mController.runtimeAnimatorController = mAnim.runtimeAnimatorController;
        }
        public void Play(string animName, Action beginAction = null, Action endAction = null)
        {
            startCallBack = beginAction;
            endCallBack = endAction;
            if (!mClipDic.ContainsKey(animName))
            {
                mClipDic.Add(animName, mController[animName]);
                endEvt = new AnimationEvent();
                endEvt.time = mClipDic[animName].length;
                startEvt = new AnimationEvent();
                startEvt.time = 0;
                endEvt.functionName = endFunName;
                startEvt.functionName = startFunName;
                mClipDic[animName].AddEvent(endEvt);
                mClipDic[animName].AddEvent(startEvt);
            }
            if (!mAnim.enabled) mAnim.enabled = true;
            mAnim.Play(animName, 0, 0);
        }
        private void EndCallBack()
        {
            if (endCallBack != null)
                endCallBack.Invoke();
        }
        private void StartCallBack()
        {
            if (startCallBack != null)
                startCallBack.Invoke();
        }
        #region help
        // 主要是为了防止已用的动画帧事件被移除
        private void ResetEvent()
        {
            foreach (var clip in mAnim.runtimeAnimatorController.animationClips)
            {
                List evts = new List();
                foreach (var curEvt in clip.events)
                {
                    var newEvt = new AnimationEvent();
                    if (curEvt.functionName.Equals(startFunName) || curEvt.functionName.Equals(endFunName))
                        continue;
                    CloneEvent(newEvt, curEvt);
                    evts.Add(newEvt);
                }
                clip.events = null;
                foreach (var evt in evts)
                {
                    clip.AddEvent(evt);
                }
                evts = null;
            }
        }
        private void CloneEvent(AnimationEvent newEvt, AnimationEvent oldEvt)
        {
            newEvt.functionName = oldEvt.functionName;
            newEvt.floatParameter = oldEvt.floatParameter;
            newEvt.intParameter = oldEvt.intParameter;
            newEvt.objectReferenceParameter = oldEvt.objectReferenceParameter;
            newEvt.time = oldEvt.time;
        }
        #endregion
    }
    

    2.使用方式

    1. 在需要调用事件的Animator物体上添加上面的脚本
    2. 调用Play方法

    3.注意事项

    如果你将Animator的某个AnimationClip的Speed设置为了-1(即倒播),动画的开始播放事件和结束播放事件任然是对应的开始帧和结束帧。

转载请注明来自码农世界,本文标题:《Unity 代码实现Animator开始和结束播放动画回调》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,68人围观)参与讨论

还没有评论,来说两句吧...

Top