• 为 ngui TweenPosition 添加 pingpongone


    //----------------------------------------------
    //            NGUI: Next-Gen UI kit
    // Copyright © 2011-2015 Tasharen Entertainment
    //----------------------------------------------
    
    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    
    /// <summary>
    /// Base class for all tweening operations.
    /// </summary>
    
    public abstract class UITweener : MonoBehaviour
    {
    	/// <summary>
    	/// Current tween that triggered the callback function.
    	/// </summary>
    
    	static public UITweener current;
    
    	public enum Method
    	{
    		Linear,
    		EaseIn,
    		EaseOut,
    		EaseInOut,
    		BounceIn,
    		BounceOut,
    	}
    
    	public enum Style
    	{
    		Once,
    		Loop,
    		PingPong,
    		PingPongOne  // by tin
    	}
    
    	/// <summary>
    	/// Tweening method used.
    	/// </summary>
    
    	[HideInInspector]
    	public Method method = Method.Linear;
    
    	/// <summary>
    	/// Does it play once? Does it loop?
    	/// </summary>
    
    	[HideInInspector]
    	public Style style = Style.Once;
    
    	/// <summary>
    	/// Optional curve to apply to the tween's time factor value.
    	/// </summary>
    
    	[HideInInspector]
    	public AnimationCurve animationCurve = new AnimationCurve(new Keyframe(0f, 0f, 0f, 1f), new Keyframe(1f, 1f, 1f, 0f));
    
    	/// <summary>
    	/// Whether the tween will ignore the timescale, making it work while the game is paused.
    	/// </summary>
    	
    	[HideInInspector]
    	public bool ignoreTimeScale = true;
    
    	/// <summary>
    	/// How long will the tweener wait before starting the tween?
    	/// </summary>
    
    	[HideInInspector]
    	public float delay = 0f;
    
    	/// <summary>
    	/// How long is the duration of the tween?
    	/// </summary>
    
    	[HideInInspector]
    	public float duration = 1f;
    
    	/// <summary>
    	/// Whether the tweener will use steeper curves for ease in / out style interpolation.
    	/// </summary>
    
    	[HideInInspector]
    	public bool steeperCurves = false;
    
    	/// <summary>
    	/// Used by buttons and tween sequences. Group of '0' means not in a sequence.
    	/// </summary>
    
    	[HideInInspector]
    	public int tweenGroup = 0;
    
    	/// <summary>
    	/// Event delegates called when the animation finishes.
    	/// </summary>
    
    	[HideInInspector]
    	public List<EventDelegate> onFinished = new List<EventDelegate>();
    
    	// Deprecated functionality, kept for backwards compatibility
    	[HideInInspector] public GameObject eventReceiver;
    	[HideInInspector] public string callWhenFinished;
    
    	bool mStarted = false;
    	float mStartTime = 0f;
    	float mDuration = 0f;
    	float mAmountPerDelta = 1000f;
    	float mFactor = 0f;
    
    	/// <summary>
    	/// Amount advanced per delta time.
    	/// </summary>
    
    	public float amountPerDelta
    	{
    		get
    		{
    			if (mDuration != duration)
    			{
    				mDuration = duration;
    				mAmountPerDelta = Mathf.Abs((duration > 0f) ? 1f / duration : 1000f) * Mathf.Sign(mAmountPerDelta);
    			}
    			return mAmountPerDelta;
    		}
    	}
    
    	/// <summary>
    	/// Tween factor, 0-1 range.
    	/// </summary>
    
    	public float tweenFactor { get { return mFactor; } set { mFactor = Mathf.Clamp01(value); } }
    
    	/// <summary>
    	/// Direction that the tween is currently playing in.
    	/// </summary>
    
    	public AnimationOrTween.Direction direction { get { return amountPerDelta < 0f ? AnimationOrTween.Direction.Reverse : AnimationOrTween.Direction.Forward; } }
    
    	/// <summary>
    	/// This function is called by Unity when you add a component. Automatically set the starting values for convenience.
    	/// </summary>
    
    	void Reset ()
    	{
    		if (!mStarted)
    		{
    			SetStartToCurrentValue();
    			SetEndToCurrentValue();
    		}
    	}
    
    	/// <summary>
    	/// Update as soon as it's started so that there is no delay.
    	/// </summary>
    
    	protected virtual void Start () { Update(); }
    
    	/// <summary>
    	/// Update the tweening factor and call the virtual update function.
    	/// </summary>
     
    
    	void Update ()
    	{
    		float delta = ignoreTimeScale ? RealTime.deltaTime : Time.deltaTime;
    		float time = ignoreTimeScale ? RealTime.time : Time.time;
    
    		if (!mStarted)
    		{
    			mStarted = true;
    			mStartTime = time + delay;
    		}
    
    		if (time < mStartTime) return;
    
    		// Advance the sampling factor
    		mFactor += amountPerDelta * delta;
    
    		// Loop style simply resets the play factor after it exceeds 1.
    		if (style == Style.Loop)
    		{
    			if (mFactor > 1f)
    			{
    				mFactor -= Mathf.Floor(mFactor);
    			}
    		}
    		else if (style == Style.PingPong)
    		{
    			// Ping-pong style reverses the direction
    			if (mFactor > 1f)
    			{
    				mFactor = 1f - (mFactor - Mathf.Floor(mFactor));
    				mAmountPerDelta = -mAmountPerDelta; 
    			}
    			else if (mFactor < 0f)
    			{
    				mFactor = -mFactor;
    				mFactor -= Mathf.Floor(mFactor);
    				mAmountPerDelta = -mAmountPerDelta; 
    			}
    		}else if (style == Style.PingPongOne)  //  by  tin
    		{
    			// Ping-pong style reverses the direction
    			if (mFactor > 1f)
    			{
    				mFactor = 1f - (mFactor - Mathf.Floor(mFactor));
    				mAmountPerDelta = -mAmountPerDelta;
     
    			}
    			else if (mFactor < 0f)
    			{
    				mFactor = -mFactor;
    				mFactor -= Mathf.Floor(mFactor);
    				mAmountPerDelta = -mAmountPerDelta; 
    			 
    				enabled = false; 
    				if (onFinished != null)
    				{
    					mTemp = onFinished;
    					onFinished = new List<EventDelegate>();
    					
    					// Notify the listener delegates
    					EventDelegate.Execute(mTemp);
    					
    					// Re-add the previous persistent delegates
    					for (int i = 0; i < mTemp.Count; ++i)
    					{
    						EventDelegate ed = mTemp[i];
    						if (ed != null && !ed.oneShot) EventDelegate.Add(onFinished, ed, ed.oneShot);
    					}
    					mTemp = null;
    				}
     
    			}
    
    
    
    
    		}
    
    		// If the factor goes out of range and this is a one-time tweening operation, disable the script
    		if ((style == Style.Once) && (duration == 0f || mFactor > 1f || mFactor < 0f))
    		{
    			mFactor = Mathf.Clamp01(mFactor);
    			Sample(mFactor, true);
    			enabled = false;
    
    			if (current == null)
    			{
    				UITweener before = current;
    				current = this;
    
    				if (onFinished != null)
    				{
    					mTemp = onFinished;
    					onFinished = new List<EventDelegate>();
    
    					// Notify the listener delegates
    					EventDelegate.Execute(mTemp);
    
    					// Re-add the previous persistent delegates
    					for (int i = 0; i < mTemp.Count; ++i)
    					{
    						EventDelegate ed = mTemp[i];
    						if (ed != null && !ed.oneShot) EventDelegate.Add(onFinished, ed, ed.oneShot);
    					}
    					mTemp = null;
    				}
    
    				// Deprecated legacy functionality support
    				if (eventReceiver != null && !string.IsNullOrEmpty(callWhenFinished))
    					eventReceiver.SendMessage(callWhenFinished, this, SendMessageOptions.DontRequireReceiver);
    
    				current = before;
    			}
    		}
    		else Sample(mFactor, false);
    	}
    
    	List<EventDelegate> mTemp = null;
    
    	/// <summary>
    	/// Convenience function -- set a new OnFinished event delegate (here for to be consistent with RemoveOnFinished).
    	/// </summary>
    
    	public void SetOnFinished (EventDelegate.Callback del) { EventDelegate.Set(onFinished, del); }
    
    	/// <summary>
    	/// Convenience function -- set a new OnFinished event delegate (here for to be consistent with RemoveOnFinished).
    	/// </summary>
    
    	public void SetOnFinished (EventDelegate del) { EventDelegate.Set(onFinished, del); }
    
    	/// <summary>
    	/// Convenience function -- add a new OnFinished event delegate (here for to be consistent with RemoveOnFinished).
    	/// </summary>
    
    	public void AddOnFinished (EventDelegate.Callback del) { EventDelegate.Add(onFinished, del); }
    
    	/// <summary>
    	/// Convenience function -- add a new OnFinished event delegate (here for to be consistent with RemoveOnFinished).
    	/// </summary>
    
    	public void AddOnFinished (EventDelegate del) { EventDelegate.Add(onFinished, del); }
    
    	/// <summary>
    	/// Remove an OnFinished delegate. Will work even while iterating through the list when the tweener has finished its operation.
    	/// </summary>
    
    	public void RemoveOnFinished (EventDelegate del)
    	{
    		if (onFinished != null) onFinished.Remove(del);
    		if (mTemp != null) mTemp.Remove(del);
    	}
    
    	/// <summary>
    	/// Mark as not started when finished to enable delay on next play.
    	/// </summary>
    
    	void OnDisable () { mStarted = false; }
    
    	/// <summary>
    	/// Sample the tween at the specified factor.
    	/// </summary>
    
    	public void Sample (float factor, bool isFinished)
    	{
    		// Calculate the sampling value
    		float val = Mathf.Clamp01(factor);
    
    		if (method == Method.EaseIn)
    		{
    			val = 1f - Mathf.Sin(0.5f * Mathf.PI * (1f - val));
    			if (steeperCurves) val *= val;
    		}
    		else if (method == Method.EaseOut)
    		{
    			val = Mathf.Sin(0.5f * Mathf.PI * val);
    
    			if (steeperCurves)
    			{
    				val = 1f - val;
    				val = 1f - val * val;
    			}
    		}
    		else if (method == Method.EaseInOut)
    		{
    			const float pi2 = Mathf.PI * 2f;
    			val = val - Mathf.Sin(val * pi2) / pi2;
    
    			if (steeperCurves)
    			{
    				val = val * 2f - 1f;
    				float sign = Mathf.Sign(val);
    				val = 1f - Mathf.Abs(val);
    				val = 1f - val * val;
    				val = sign * val * 0.5f + 0.5f;
    			}
    		}
    		else if (method == Method.BounceIn)
    		{
    			val = BounceLogic(val);
    		}
    		else if (method == Method.BounceOut)
    		{
    			val = 1f - BounceLogic(1f - val);
    		}
    
    		// Call the virtual update
    		OnUpdate((animationCurve != null) ? animationCurve.Evaluate(val) : val, isFinished);
    	}
    
    	/// <summary>
    	/// Main Bounce logic to simplify the Sample function
    	/// </summary>
    	
    	float BounceLogic (float val)
    	{
    		if (val < 0.363636f) // 0.363636 = (1/ 2.75)
    		{
    			val = 7.5685f * val * val;
    		}
    		else if (val < 0.727272f) // 0.727272 = (2 / 2.75)
    		{
    			val = 7.5625f * (val -= 0.545454f) * val + 0.75f; // 0.545454f = (1.5 / 2.75) 
    		}
    		else if (val < 0.909090f) // 0.909090 = (2.5 / 2.75) 
    		{
    			val = 7.5625f * (val -= 0.818181f) * val + 0.9375f; // 0.818181 = (2.25 / 2.75) 
    		}
    		else
    		{
    			val = 7.5625f * (val -= 0.9545454f) * val + 0.984375f; // 0.9545454 = (2.625 / 2.75) 
    		}
    		return val;
    	}
    
    	/// <summary>
    	/// Play the tween.
    	/// </summary>
    
    	[System.Obsolete("Use PlayForward() instead")]
    	public void Play () { Play(true); }
    
    	/// <summary>
    	/// Play the tween forward.
    	/// </summary>
    
    	public void PlayForward () { Play(true); }
    
    	/// <summary>
    	/// Play the tween in reverse.
    	/// </summary>
    	
    	public void PlayReverse () { Play(false); }
    
    	/// <summary>
    	/// Manually activate the tweening process, reversing it if necessary.
    	/// </summary>
    
    	public void Play (bool forward)
    	{
    		mAmountPerDelta = Mathf.Abs(amountPerDelta);
    		if (!forward) mAmountPerDelta = -mAmountPerDelta;
    		enabled = true;
    		Update();
    	}
    
    	/// <summary>
    	/// Manually reset the tweener's state to the beginning.
    	/// If the tween is playing forward, this means the tween's start.
    	/// If the tween is playing in reverse, this means the tween's end.
    	/// </summary>
    
    	public void ResetToBeginning ()
    	{ 
    		mStarted = false;
    		mFactor = (amountPerDelta < 0f) ? 1f : 0f;
    		Sample(mFactor, false);
    	}
    
    	/// <summary>
    	/// Manually start the tweening process, reversing its direction.
    	/// </summary>
    
    	public void Toggle ()
    	{
    		if (mFactor > 0f)
    		{
    			mAmountPerDelta = -amountPerDelta;
    		}
    		else
    		{
    			mAmountPerDelta = Mathf.Abs(amountPerDelta);
    		}
    		enabled = true;
    	}
    
    	/// <summary>
    	/// Actual tweening logic should go here.
    	/// </summary>
    
    	abstract protected void OnUpdate (float factor, bool isFinished);
    
    	/// <summary>
    	/// Starts the tweening operation.
    	/// </summary>
    
    	static public T Begin<T> (GameObject go, float duration) where T : UITweener
    	{
    		T comp = go.GetComponent<T>();
    #if UNITY_FLASH
    		if ((object)comp == null) comp = (T)go.AddComponent<T>();
    #else
    		// Find the tween with an unset group ID (group ID of 0).
    		if (comp != null && comp.tweenGroup != 0)
    		{
    			comp = null;
    			T[] comps = go.GetComponents<T>();
    			for (int i = 0, imax = comps.Length; i < imax; ++i)
    			{
    				comp = comps[i];
    				if (comp != null && comp.tweenGroup == 0) break;
    				comp = null;
    			}
    		}
    
    		if (comp == null)
    		{
    			comp = go.AddComponent<T>();
    
    			if (comp == null)
    			{
    				Debug.LogError("Unable to add " + typeof(T) + " to " + NGUITools.GetHierarchy(go), go);
    				return null;
    			}
    		}
    #endif
    		comp.mStarted = false;
    		comp.duration = duration;
    		comp.mFactor = 0f;
    		comp.mAmountPerDelta = Mathf.Abs(comp.amountPerDelta);
    		comp.style = Style.Once;
    		comp.animationCurve = new AnimationCurve(new Keyframe(0f, 0f, 0f, 1f), new Keyframe(1f, 1f, 1f, 0f));
    		comp.eventReceiver = null;
    		comp.callWhenFinished = null;
    		comp.enabled = true;
    		return comp;
    	}
    
    	/// <summary>
    	/// Set the 'from' value to the current one.
    	/// </summary>
    
    	public virtual void SetStartToCurrentValue () { }
    
    	/// <summary>
    	/// Set the 'to' value to the current one.
    	/// </summary>
    
    	public virtual void SetEndToCurrentValue () { }
    }
    
  • 相关阅读:
    [转载]分治算法详解
    数值的三种表示--C语言
    [转载]位运算操作
    递归--基于位运算的八皇后问题求解
    递归--基于回溯和递归的八皇后问题解法
    关于C/C++中数组元素的初始化
    递归的使用方法及说明
    递归--基于排列的八皇后问题解法
    Android笔记(二十) Activity中的跳转和值传递
    Android笔记(十九) Android中的Fragment
  • 原文地址:https://www.cnblogs.com/didiaodexi/p/4876851.html
Copyright © 2020-2023  润新知