animation的封装

闻人花蜂
2023-12-01

项目需要,对animation进行了一次简单封装使用。

代码如下:

using System;
using UnityEngine;

namespace Module
{
    public class ZyPlayAnimtion : MonoBehaviour
    {
        private Animation m_animation;
        //private Animator m_animator;
        private bool m_isPlaying;
        private Action m_finCall;
        private Action<float> m_progressCall;
        private string m_stateName;
        private bool m_isDefault = false;
        private bool m_isinit = false;
        private bool m_endenable;
        private bool m_playInFixTime;
        private bool m_isTimescale0Loop = false;//是否需要在timescale为零的时候循环播放

        private Action m_delayplay;
        private Action m_Timescale0LoopPlay;

        public bool getIsPlaying()
        {
            return m_isPlaying;
        }

        public override void _Awake()
        {
            base._Awake();
            _init();
        }

        public void setAnimatorEnable(bool value)
        {
            if (!m_isinit)
            {
                _init();
            }

            m_animation.enabled = value;
        }

        private void _init()
        {
            m_animation = GetComponent<Animation>();
            m_isinit = true;
        }

        public void SetDefaultFinCall(Action finCall)
        {
            m_finCall = finCall;
            m_isPlaying = true;
            m_isDefault = true;
        }

        public void Stop()
        {
            if (!gameObject.activeSelf)
                return;
            m_stateName = string.Empty;
            m_isPlaying = false;
            if (!m_endenable)
            {
                m_animation.enabled = false;
            }
            if (null != m_finCall)
            {
                m_isDefault = false;
                m_finCall();
                m_finCall = null;
            }

            if (m_lockScreen)
            {
                Global.loadingMgr.HideLoading(LoadingDefine.LoadingType.WIAIACTION);
                m_lockScreen = false;
            }
            if (Time.timeScale == 0 && m_isTimescale0Loop && m_Timescale0LoopPlay != null)
            {
                m_Timescale0LoopPlay();
                m_Timescale0LoopPlay = null;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="stateName"></param>
        /// <param name="finCall"></param>
        /// <param name="progressCall"></param>
        /// <param name="updateMode"></param>
        /// <param name="canReset"></param>
        /// <param name="playInFixTime"></param>
        /// <param name="playInReverse"></param>
        /// <param name="endenable"></param>
        /// <param name="lockScreen"></param>
        /// <param name="isTimescale0Loop">是否需要在timescale为零的时候循环播放</param>
        public void Play(string stateName = "", Action finCall = null, Action<float> progressCall = null,
            AnimatorUpdateMode updateMode = AnimatorUpdateMode.UnscaledTime, bool canReset = false,
            bool playInFixTime = false, bool playInReverse = false, bool endenable = true, bool lockScreen = false, bool isTimescale0Loop = false)
        {
            if (this.isActiveAndEnabled == false)
            {
                m_delayplay = () => { Play(stateName, finCall, progressCall, updateMode, canReset, playInFixTime, playInReverse, endenable, lockScreen, isTimescale0Loop); };
                return;
            }
            if (!m_isinit)
            {
                _init();
            }
            if (!canReset && m_stateName == stateName)
            {
                return;
            }
            m_finCall = finCall;
            m_progressCall = progressCall;
            m_stateName = stateName;
            m_endenable = endenable;
            m_isTimescale0Loop = isTimescale0Loop;
            if (m_isTimescale0Loop)
            {
                m_Timescale0LoopPlay = () => { Play(stateName, finCall, progressCall, updateMode, canReset, playInFixTime, playInReverse, endenable, lockScreen, isTimescale0Loop); };
            }
            if (!m_animation.enabled)
            {
                m_animation.enabled = true;
            }
            if (!string.IsNullOrEmpty(m_stateName))
            {
                m_playingTime = 0;
                m_playInFixTime = playInFixTime;

                try
                {
                    m_animation[m_stateName].enabled = true;
                }
                catch { LoggerHelper.Error("Can not find animationclip name:"+ m_stateName); }
                if (playInReverse)
                {
                    m_animation[m_stateName].time = m_animation[m_stateName].length;
                    m_animation[m_stateName].speed = -1f;
                    AnimationEvent finevent = new AnimationEvent();
                    finevent.time = 0;
                    finevent.functionName = "Stop";
                    m_animation.GetClip(m_stateName).AddEvent(finevent);
                }
                else
                {
                    m_animation[m_stateName].speed = 1f;
                    AnimationEvent finevent = new AnimationEvent();
                    finevent.time = m_animation.GetClip(m_stateName).length;
                    finevent.functionName = "Stop";
                    m_animation.GetClip(m_stateName).AddEvent(finevent);
                }
                m_animation.Play(m_stateName);
            }
            m_lockScreen = lockScreen;
            if (m_lockScreen)
            {
                Global.loadingMgr.ShowLoading(LoadingDefine.LoadingType.WIAIACTION);
            }
            m_isPlaying = true;
            Update();
        }

        float m_playingTime;
        private bool m_lockScreen;

        void Update()
        {
            if (!m_isPlaying) return;

            float progress = 0;
            if (!m_playInFixTime)
            {
                if (string.IsNullOrEmpty(m_stateName))
                {
                    foreach (AnimationState item in m_animation)
                    {
                        if (m_animation.IsPlaying(item.name))
                        {
                            m_stateName = item.name;
                            break;
                        }
                    }
                }
                m_animation[m_stateName].enabled = true;
                progress = m_animation[m_stateName].normalizedTime;
            }
            else
            {
                AnimationState animState = m_animation[m_stateName]; // 当前动画状态
                animState.enabled = true;
                m_playingTime += GameValueDefine.TWEEN_INTERVAL;
                animState.normalizedTime = m_playingTime / animState.length; // 动画规范化时间[0-1]
                m_animation.Sample(); // 在当前状态对动画进行采样,当你想显式设置动画状态并且对它取样的时候使用
                progress = animState.normalizedTime;
            }

            if (progress == 0)
            {
                return;
            }

            if (null != m_progressCall)
            {
                m_progressCall(progress);
            }
            if (progress >= 0.99f)
            {
                Stop();
            }
        }
        void OnDisable()
        {
            if (m_isPlaying)
            {
                Stop();
            }
        }

        void OnEnable()
        {
            if (m_delayplay != null)
            {
                m_delayplay();
                m_delayplay = null;
            }
        }

        /// <summary>
        /// 停到第一帧
        /// </summary>
        public void PlayToFirstFrame(string stateName)
        {
            if (m_isinit && m_animation != null)
            {
                m_stateName = stateName;
                m_animation[m_stateName].enabled = true;
                m_animation[m_stateName].time = m_animation[m_stateName].length;
                m_animation[m_stateName].speed = -1f;
                m_animation.Play(m_stateName);
            }
        }
    }
}

若有更多需求还可在此基础上进行更多拓展。

 类似资料: