using System; using System.Collections; using UnityEngine; public class MecanimSceneBase : UIBase { public const string SCENE_FIRST_START = "FirstStart"; public const string SCENE_OPEN = "Open"; public const string SCENE_CLOSE = "Close"; protected Animator m_animator; protected MecanimStateBase m_state; protected MecanimStateBase m_nextState; private Coroutine m_waitCoroutine; private Action m_callback; public MecanimStateBase CurrentState => m_state; public void ChangeState(MecanimStateBase state, bool skipCloseAnim = false, bool skipOpenAnim = false) { Action nextFunc = delegate { if ((bool)(m_state = m_nextState)) { m_state.onOpen(); PlayAndCallback(m_state.OpenStateName, m_state.onUpdateOpenAnim, delegate { if ((bool)m_state) { m_state.onFinishOpenAnim(); if (m_state.NextState != null) { ChangeState(m_state.NextState); } } }, skipOpenAnim); } }; if ((bool)state && !state.onOpenRequest(m_state, m_callback != null)) { return; } if ((bool)m_state) { if (!m_state.onCloseRequest(state, m_callback != null)) { return; } m_nextState = state; m_state.onClose(); PlayAndCallback(m_state.CloseStateName, m_state.onUpdateCloseAnim, delegate { if ((bool)m_state) { m_state.onFinishCloseAnim(); nextFunc(); } }, skipCloseAnim); } else { m_nextState = state; nextFunc(); } } private bool Play(string state, bool isSkip = false) { if (!m_animator) { return false; } if (m_waitCoroutine != null) { StopCoroutine(m_waitCoroutine); m_waitCoroutine = null; AnimatorStateInfo currentAnimatorStateInfo = m_animator.GetCurrentAnimatorStateInfo(0); m_animator.Play(currentAnimatorStateInfo.fullPathHash, 0, 1f); if (m_callback != null) { Action callback = m_callback; m_callback = null; callback(); } } if (state != null && state.Length > 0) { m_animator.Play(state, 0, isSkip ? 1f : 0f); return true; } return false; } private bool PlayAndCallback(string state, Action update, Action callback, bool isSkip = false) { bool num = Play(state, isSkip); if (num && !isSkip) { m_callback = callback; m_waitCoroutine = StartCoroutine(PlayAndCallback_Coroutine(state, update)); return num; } callback?.Invoke(); return num; } private IEnumerator PlayAndCallback_Coroutine(string state, Action update) { if ((bool)m_animator) { AnimatorStateInfo info; while (true) { AnimatorStateInfo currentAnimatorStateInfo; info = (currentAnimatorStateInfo = m_animator.GetCurrentAnimatorStateInfo(0)); currentAnimatorStateInfo = currentAnimatorStateInfo; if (currentAnimatorStateInfo.IsName(state)) { break; } yield return null; } float time = 0f - Time.deltaTime; while (true) { float num; time = (num = time + Time.deltaTime); if (!(num < info.length)) { break; } update?.Invoke(); yield return null; } } m_waitCoroutine = null; if (m_callback != null) { Action callback = m_callback; m_callback = null; callback(); } } public override void onFirstStart() { base.onFirstStart(); if ((bool)(m_animator = GetComponent())) { Play("FirstStart"); } } protected override void onOpen() { base.onOpen(); if ((bool)m_animator) { PlayAndCallback("Open", onUpdateOpenAnim, delegate { onFinishOpenAnim(); }); } else { onFinishOpenAnim(); } } protected virtual void onUpdateOpenAnim() { } protected virtual void onFinishOpenAnim() { } protected override void onClose() { m_state = null; if ((bool)m_animator) { PlayAndCallback("Close", onUpdateCloseAnim, delegate { onFinishCloseAnim(); }); } else { onFinishCloseAnim(); } } protected virtual void onUpdateCloseAnim() { } protected virtual void onFinishCloseAnim() { base.onClose(); } public override void onMove() { base.onMove(); if ((bool)m_state && !m_state.DontMove) { m_state.onMove(); } } protected void CreateLoading(bool notBlack) { UIManager.GetInstance().createInSceneLoading(notBlack); } protected void CloseLoading() { UIManager.GetInstance().closeInSceneLoading(); } protected void onNotify(int value) { if ((bool)m_state) { m_state.onNotify(value); } } }