/Assets/NGUI/Scripts/Internal/ActiveAnimation.cs
C# | 352 lines | 241 code | 54 blank | 57 comment | 104 complexity | f586ede7eef54a54e22bbcf7d9e96162 MD5 | raw file
- //----------------------------------------------
- // NGUI: Next-Gen UI kit
- // Copyright © 2011-2014 Tasharen Entertainment
- //----------------------------------------------
- #if !UNITY_3_5 && !UNITY_4_0 && !UNITY_4_1 && !UNITY_4_2
- #define USE_MECANIM
- #endif
- using UnityEngine;
- using AnimationOrTween;
- using System.Collections.Generic;
- /// <summary>
- /// Mainly an internal script used by UIButtonPlayAnimation, but can also be used to call
- /// the specified function on the game object after it finishes animating.
- /// </summary>
- [AddComponentMenu("NGUI/Internal/Active Animation")]
- public class ActiveAnimation : MonoBehaviour
- {
- /// <summary>
- /// Active animation that resulted in the event notification.
- /// </summary>
- static public ActiveAnimation current;
- /// <summary>
- /// Event delegates called when the animation finishes.
- /// </summary>
- public List<EventDelegate> onFinished = new List<EventDelegate>();
- // Deprecated functionality, kept for backwards compatibility
- [HideInInspector] public GameObject eventReceiver;
- [HideInInspector] public string callWhenFinished;
- Animation mAnim;
- Direction mLastDirection = Direction.Toggle;
- Direction mDisableDirection = Direction.Toggle;
- bool mNotify = false;
- #if USE_MECANIM
- Animator mAnimator;
- string mClip = "";
- float playbackTime
- {
- get
- {
- AnimatorStateInfo state = mAnimator.GetCurrentAnimatorStateInfo(0);
- return Mathf.Clamp01(state.normalizedTime);
- }
- }
- #endif
- /// <summary>
- /// Whether the animation is currently playing.
- /// </summary>
- public bool isPlaying
- {
- get
- {
- if (mAnim == null)
- {
- #if USE_MECANIM
- if (mAnimator != null)
- {
- if (mLastDirection == Direction.Reverse)
- {
- if (playbackTime == 0f) return false;
- }
- else if (playbackTime == 1f) return false;
- return true;
- }
- #endif
- return false;
- }
- foreach (AnimationState state in mAnim)
- {
- if (!mAnim.IsPlaying(state.name)) continue;
- if (mLastDirection == Direction.Forward)
- {
- if (state.time < state.length) return true;
- }
- else if (mLastDirection == Direction.Reverse)
- {
- if (state.time > 0f) return true;
- }
- else return true;
- }
- return false;
- }
- }
- /// <summary>
- /// Manually reset the active animation to the beginning.
- /// </summary>
- public void Reset ()
- {
- if (mAnim != null)
- {
- foreach (AnimationState state in mAnim)
- {
- if (mLastDirection == Direction.Reverse) state.time = state.length;
- else if (mLastDirection == Direction.Forward) state.time = 0f;
- }
- }
- #if USE_MECANIM
- else if (mAnimator != null)
- {
- mAnimator.Play(mClip, 0, (mLastDirection == Direction.Reverse) ? 1f : 0f);
- }
- #endif
- }
- /// <summary>
- /// Event receiver is only kept for backwards compatibility purposes. It's removed on start if new functionality is used.
- /// </summary>
- void Start ()
- {
- if (eventReceiver != null && EventDelegate.IsValid(onFinished))
- {
- eventReceiver = null;
- callWhenFinished = null;
- }
- }
- /// <summary>
- /// Notify the target when the animation finishes playing.
- /// </summary>
- void Update ()
- {
- float delta = RealTime.deltaTime;
- if (delta == 0f) return;
- #if USE_MECANIM
- if (mAnimator != null)
- {
- mAnimator.Update((mLastDirection == Direction.Reverse) ? -delta : delta);
- if (isPlaying) return;
- mAnimator.enabled = false;
- enabled = false;
- }
- else if (mAnim != null)
- #else
- if (mAnim != null)
- #endif
- {
- bool playing = false;
- foreach (AnimationState state in mAnim)
- {
- if (!mAnim.IsPlaying(state.name)) continue;
- float movement = state.speed * delta;
- state.time += movement;
- if (movement < 0f)
- {
- if (state.time > 0f) playing = true;
- else state.time = 0f;
- }
- else
- {
- if (state.time < state.length) playing = true;
- else state.time = state.length;
- }
- }
- mAnim.Sample();
- if (playing) return;
- enabled = false;
- }
- else
- {
- enabled = false;
- return;
- }
- if (mNotify)
- {
- mNotify = false;
- current = this;
- EventDelegate.Execute(onFinished);
- // Deprecated functionality, kept for backwards compatibility
- if (eventReceiver != null && !string.IsNullOrEmpty(callWhenFinished))
- eventReceiver.SendMessage(callWhenFinished, SendMessageOptions.DontRequireReceiver);
- current = null;
- if (mDisableDirection != Direction.Toggle && mLastDirection == mDisableDirection)
- NGUITools.SetActive(gameObject, false);
- }
- }
- /// <summary>
- /// Play the specified animation.
- /// </summary>
- void Play (string clipName, Direction playDirection)
- {
- // Determine the play direction
- if (playDirection == Direction.Toggle)
- playDirection = (mLastDirection != Direction.Forward) ? Direction.Forward : Direction.Reverse;
- if (mAnim != null)
- {
- // We will sample the animation manually so that it works when the time is paused
- enabled = true;
- mAnim.enabled = false;
- bool noName = string.IsNullOrEmpty(clipName);
- // Play the animation if it's not playing already
- if (noName)
- {
- if (!mAnim.isPlaying) mAnim.Play();
- }
- else if (!mAnim.IsPlaying(clipName))
- {
- mAnim.Play(clipName);
- }
- // Update the animation speed based on direction -- forward or back
- foreach (AnimationState state in mAnim)
- {
- if (string.IsNullOrEmpty(clipName) || state.name == clipName)
- {
- float speed = Mathf.Abs(state.speed);
- state.speed = speed * (int)playDirection;
- // Automatically start the animation from the end if it's playing in reverse
- if (playDirection == Direction.Reverse && state.time == 0f) state.time = state.length;
- else if (playDirection == Direction.Forward && state.time == state.length) state.time = 0f;
- }
- }
- // Remember the direction for disable checks in Update()
- mLastDirection = playDirection;
- mNotify = true;
- mAnim.Sample();
- }
- #if USE_MECANIM
- else if (mAnimator != null)
- {
- if (enabled && isPlaying)
- {
- if (mClip == clipName)
- {
- mLastDirection = playDirection;
- return;
- }
- }
- enabled = true;
- mNotify = true;
- mLastDirection = playDirection;
- mClip = clipName;
- mAnimator.Play(mClip, 0, (playDirection == Direction.Forward) ? 0f : 1f);
- // NOTE: If you are getting a message "Animator.GotoState: HealthState could not be found"
- // it means that you chose a state name that doesn't exist in the Animator window.
- }
- #endif
- }
- /// <summary>
- /// Play the specified animation on the specified object.
- /// </summary>
- static public ActiveAnimation Play (Animation anim, string clipName, Direction playDirection,
- EnableCondition enableBeforePlay, DisableCondition disableCondition)
- {
- if (!NGUITools.GetActive(anim.gameObject))
- {
- // If the object is disabled, don't do anything
- if (enableBeforePlay != EnableCondition.EnableThenPlay) return null;
- // Enable the game object before animating it
- NGUITools.SetActive(anim.gameObject, true);
-
- // Refresh all panels right away so that there is no one frame delay
- UIPanel[] panels = anim.gameObject.GetComponentsInChildren<UIPanel>();
- for (int i = 0, imax = panels.Length; i < imax; ++i) panels[i].Refresh();
- }
- ActiveAnimation aa = anim.GetComponent<ActiveAnimation>();
- if (aa == null) aa = anim.gameObject.AddComponent<ActiveAnimation>();
- aa.mAnim = anim;
- aa.mDisableDirection = (Direction)(int)disableCondition;
- aa.onFinished.Clear();
- aa.Play(clipName, playDirection);
- return aa;
- }
- /// <summary>
- /// Play the specified animation.
- /// </summary>
- static public ActiveAnimation Play (Animation anim, string clipName, Direction playDirection)
- {
- return Play(anim, clipName, playDirection, EnableCondition.DoNothing, DisableCondition.DoNotDisable);
- }
- /// <summary>
- /// Play the specified animation.
- /// </summary>
- static public ActiveAnimation Play (Animation anim, Direction playDirection)
- {
- return Play(anim, null, playDirection, EnableCondition.DoNothing, DisableCondition.DoNotDisable);
- }
- #if USE_MECANIM
- /// <summary>
- /// Play the specified animation on the specified object.
- /// </summary>
- static public ActiveAnimation Play (Animator anim, string clipName, Direction playDirection,
- EnableCondition enableBeforePlay, DisableCondition disableCondition)
- {
- if (!NGUITools.GetActive(anim.gameObject))
- {
- // If the object is disabled, don't do anything
- if (enableBeforePlay != EnableCondition.EnableThenPlay) return null;
- // Enable the game object before animating it
- NGUITools.SetActive(anim.gameObject, true);
- // Refresh all panels right away so that there is no one frame delay
- UIPanel[] panels = anim.gameObject.GetComponentsInChildren<UIPanel>();
- for (int i = 0, imax = panels.Length; i < imax; ++i) panels[i].Refresh();
- }
- ActiveAnimation aa = anim.GetComponent<ActiveAnimation>();
- if (aa == null) aa = anim.gameObject.AddComponent<ActiveAnimation>();
- aa.mAnimator = anim;
- aa.mDisableDirection = (Direction)(int)disableCondition;
- aa.onFinished.Clear();
- aa.Play(clipName, playDirection);
- return aa;
- }
- #endif
- }