乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      NGUI所見即所得之UITweener

       kiki的號 2017-03-20



       NGUI所見即所得之UITweener

              一直沒有用過NGUI動畫的功能,之前的理解就是:設(shè)置始末兩個“位置”,然后就是從起始位置移到結(jié)束位置。至于中間是怎么變化的,就感覺很神奇了,變化率怎么設(shè)置才不會看起來很“傻”,這里不是看“郭靖”,動畫一定要有驚奇,摸不著猜不透的感覺。對NGUI主要的幾個腳本都已經(jīng)有點(diǎn)掌握了(猛點(diǎn)查看),一直都沒有去”膜拜“Tweening文件夾的各個大神,可能以前會覺得不就是一個動畫組件,自己都可以實現(xiàn)。但是看過里面的代碼就后悔了,因為至少結(jié)合TweenFOV和TweenOrhoSize這兩個腳本就可以實現(xiàn)很多效果,竟然輕而易舉的集成了,看來人還是不要太看得起自己的好,這樣才會走的更快更遠(yuǎn)。

              每次都覺得前面吹水很寫,也寫不好(一直都有感覺自己的寫作水平太差了),那就來看下Tweening文件夾下到底賣的是什么藥——UITweener和它的“孩子”: 

      UITweener的Fields
              看著很復(fù)雜,其實只要把UITweener琢磨透了,其它都只是重寫UITweener的OnUpdate方法和封裝了Begin方法。還是先看下主要的Field(作用看注釋):

      C#代碼 復(fù)制代碼 收藏代碼
      1.        bool mStarted = false;  //是否開始動畫  
      2. float mStartTime = 0f;   //動畫開始播放的時間, mStarted =true;mStartTime = time + delay;  
      3. float mDuration = 0f;    //動畫長度(時間)  
      4. float mAmountPerDelta = 1000f;   //單位時間動畫播放的長度,有點(diǎn)幀率的感覺  
      5. float mFactor = 0f;           //當(dāng)前動畫播放的進(jìn)度  
      6.   
      7. /// <summary>  
      8. /// Amount advanced per delta time.  
      9. /// </summary>  
      10.   
      11. public float amountPerDelta  
      12. {  
      13.     get  
      14.     {  
      15.         if (mDuration != duration)  
      16.         {  
      17.             mDuration = duration;  
      18.             mAmountPerDelta = Mathf.Abs((duration > 0f) ? 1f / duration : 1000f);  
      19.         }  
      20.         return mAmountPerDelta;  
      21.     }  
      22. }  

              通過Begin設(shè)置需要的參數(shù):

      C#代碼 復(fù)制代碼 收藏代碼
      1.        static public T Begin<T> (GameObject go, float duration) where T : UITweener  
      2. {  
      3.     T comp = go.GetComponent<T>();  
      4. if UNITY_FLASH  
      5.     if ((object)comp == null) comp = (T)go.AddComponent<T>();  
      6. else  
      7.     if (comp == null) comp = go.AddComponent<T>();  
      8. endif  
      9.     comp.mStarted = false;  
      10.     comp.duration = duration;  
      11.     comp.mFactor = 0f;  
      12.     comp.mAmountPerDelta = Mathf.Abs(comp.mAmountPerDelta);  
      13.     comp.style = Style.Once;  
      14.     comp.animationCurve = new AnimationCurve(new Keyframe(0f, 0f, 0f, 1f), new Keyframe(1f, 1f, 1f, 0f));  
      15.     comp.eventReceiver = null;  
      16.     comp.callWhenFinished = null;  
      17.     comp.enabled = true;  
      18.     return comp;  
      19. }  

      Update函數(shù)     

      然后再Update函數(shù)先計算出時間delta,進(jìn)一步計算出當(dāng)前動畫播放的mFactor,然后進(jìn)行Sample采用,執(zhí)行OnUpdate:

      C#代碼 復(fù)制代碼 收藏代碼
      1. void Update ()  
      2. {  
      3.     float delta = ignoreTimeScale ? RealTime.deltaTime : Time.deltaTime;  
      4.     float time = ignoreTimeScale ? RealTime.time : Time.time;  
      5.   
      6.     if (!mStarted)  
      7.     {  
      8.         mStarted = true;  
      9.         mStartTime = time + delay;  
      10.     }  
      11.   
      12.     if (time < mStartTime) return;  
      13.   
      14.     // Advance the sampling factor  
      15.     mFactor += amountPerDelta * delta;  
      16.   
      17.     // Loop style simply resets the play factor after it exceeds 1.  
      18.     if (style == Style.Loop)  
      19.     {  
      20.         if (mFactor > 1f)  
      21.         {  
      22.             mFactor -= Mathf.Floor(mFactor);  
      23.         }  
      24.     }  
      25.     else if (style == Style.PingPong)  
      26.     {  
      27.         // Ping-pong style reverses the direction  
      28.         if (mFactor > 1f)  
      29.         {  
      30.             mFactor = 1f - (mFactor - Mathf.Floor(mFactor));  
      31.             mAmountPerDelta = -mAmountPerDelta;  
      32.         }  
      33.         else if (mFactor < 0f)  
      34.         {  
      35.             mFactor = -mFactor;  
      36.             mFactor -= Mathf.Floor(mFactor);  
      37.             mAmountPerDelta = -mAmountPerDelta;  
      38.         }  
      39.     }  
      40.   
      41.     // If the factor goes out of range and this is a one-time tweening operation, disable the script  
      42.     if ((style == Style.Once) && (mFactor > 1f || mFactor < 0f))  
      43.     {  
      44.         mFactor = Mathf.Clamp01(mFactor);  
      45.         Sample(mFactor, true);  
      46.   
      47.         current = this;  
      48.   
      49.         // Notify the listener delegates  
      50.         EventDelegate.Execute(onFinished);  
      51.   
      52.         // Deprecated legacy functionality support  
      53.         if (eventReceiver != null && !string.IsNullOrEmpty(callWhenFinished))  
      54.             eventReceiver.SendMessage(callWhenFinished, this, SendMessageOptions.DontRequireReceiver);  
      55.   
      56.         current = null;  
      57.   
      58.         // Disable this script unless the function calls above changed something  
      59.         if (mFactor == 1f && mAmountPerDelta > 0f || mFactor == 0f && mAmountPerDelta < 0f)  
      60.             enabled = false;  
      61.     }  
      62.     else Sample(mFactor, false);  
      63. }  

       Sample采樣函數(shù)

              前面說的動畫要有摸不著猜不透的感覺,就是要考Sample的采樣函數(shù)來實現(xiàn)的,UITweener支持5種動畫曲線:

      C#代碼 復(fù)制代碼 收藏代碼
      1.        public enum Method  
      2. {  
      3.     Linear,  
      4.     EaseIn,  
      5.     EaseOut,  
      6.     EaseInOut,  
      7.     BounceIn,  
      8.     BounceOut,  
      9. }  

       采樣的函數(shù),原理很簡單:根據(jù)當(dāng)前播放的進(jìn)度mFactor,計算出實際的動畫播放刻度,然后執(zhí)行OnUpdate操作:

      C#代碼 復(fù)制代碼 收藏代碼
      1. public void Sample (float factor, bool isFinished)  
      2. {  
      3.     // Calculate the sampling value  
      4.     float val = Mathf.Clamp01(factor);  
      5.   
      6.     if (method == Method.EaseIn)  
      7.     {  
      8.         val = 1f - Mathf.Sin(0.5f * Mathf.PI * (1f - val));  
      9.         if (steeperCurves) val *= val;  
      10.     }  
      11.     else if (method == Method.EaseOut)  
      12.     {  
      13.         val = Mathf.Sin(0.5f * Mathf.PI * val);  
      14.   
      15.         if (steeperCurves)  
      16.         {  
      17.             val = 1f - val;  
      18.             val = 1f - val * val;  
      19.         }  
      20.     }  
      21.     else if (method == Method.EaseInOut)  
      22.     {  
      23.         const float pi2 = Mathf.PI * 2f;  
      24.         val = val - Mathf.Sin(val * pi2) / pi2;  
      25.   
      26.         if (steeperCurves)  
      27.         {  
      28.             val = val * 2f - 1f;  
      29.             float sign = Mathf.Sign(val);  
      30.             val = 1f - Mathf.Abs(val);  
      31.             val = 1f - val * val;  
      32.             val = sign * val * 0.5f + 0.5f;  
      33.         }  
      34.     }  
      35.     else if (method == Method.BounceIn)  
      36.     {  
      37.         val = BounceLogic(val);  
      38.     }  
      39.     else if (method == Method.BounceOut)  
      40.     {  
      41.         val = 1f - BounceLogic(1f - val);  
      42.     }  
      43.   
      44.     // Call the virtual update  
      45.     OnUpdate((animationCurve != null) ? animationCurve.Evaluate(val) : val, isFinished);  
      46. }  

       緩動函數(shù)(easing fuction)

              上面說的動畫曲線,中文叫緩動函數(shù)(曲線):

              通過上面這張圖可以很感性的認(rèn)識不同函數(shù)的具體的效果,也可以自己嘗試推導(dǎo)一邊加深理解,不過D.S.Qiu已經(jīng)有點(diǎn)“廉頗老矣”,憑著記憶“奇變偶不變,符號看象限”,慢的只能到easeInSine,要想詳細(xì)了解可以參考②和③。

       

      妙用mAmountPerDelta

               mAmountPerDelta就是動畫播放速度,只對mAmountPerData就可以有更多控制:Toggle,PlayForward,PlayResverse:

      C#代碼 復(fù)制代碼 收藏代碼
      1. /// <summary>  
      2. /// Manually activate the tweening process, reversing it if necessary.  
      3. /// </summary>  
      4.   
      5. public void Play (bool forward)  
      6. {  
      7.     mAmountPerDelta = Mathf.Abs(amountPerDelta);  
      8.     if (!forward) mAmountPerDelta = -mAmountPerDelta;  
      9.     enabled = true;  
      10.     Update();  
      11. }  
      12. /// <summary>  
      13. /// Manually start the tweening process, reversing its direction.  
      14. /// </summary>  
      15.   
      16. public void Toggle ()  
      17. {  
      18.     if (mFactor > 0f)  
      19.     {  
      20.         mAmountPerDelta = -amountPerDelta;  
      21.     }  
      22.     else  
      23.     {  
      24.         mAmountPerDelta = Mathf.Abs(amountPerDelta);  
      25.     }  
      26.     enabled = true;  
      27. }  

       

      『Bug修復(fù)和吐槽

              之前用TweenRotation這個腳本,做游戲等待轉(zhuǎn)圈等待界面,發(fā)現(xiàn)總是不能旋轉(zhuǎn)360度,總是一個小于180的角度,無論from和to如何設(shè)置:

      C#代碼 復(fù)制代碼 收藏代碼
      1. public Vector3 from;  
      2. public Vector3 to;  

       后來無奈之下,只好去看下TweenRotation的OnUpdate函數(shù),發(fā)現(xiàn)使用的是 Quaternion.Slerp這個函數(shù),發(fā)現(xiàn)確實是這樣,所以就做了下面的修改:

      C#代碼 復(fù)制代碼 收藏代碼
      1. protected override void OnUpdate (float factor, bool isFinished)  
      2. {  
      3.     //cachedTransform.localRotation = Quaternion.Slerp(Quaternion.Euler(from), Quaternion.Euler(to), factor);  
      4.     //NGUI的實現(xiàn)是上一行,有Bug,不能達(dá)到要求  
      5.     cachedTransform.localEulerAngles = Vector3.Lerp(from, to, factor);  
      6.   
      7. }  

       

             NGUI提供了UIPlayTween,這個腳本管理一組Tween腳本的Play,提供了不同的Tirgger,然后在不同的事件函數(shù)中觸發(fā)Play(true):

      C#代碼 復(fù)制代碼 收藏代碼
      1. void OnClick ()  
      2. {  
      3.     if (enabled && trigger == Trigger.OnClick)  
      4.     {  
      5.         Play(true);  
      6.     }  
      7. }  

             雖然UIPlayTween提供了很多參數(shù)都是沒有滿足要其交替地進(jìn)行PlayForward和PlayReverse,因為其都是執(zhí)行Play(true),開始的時候我想到了給其中一個UITween添加OnFinished委托,在播放結(jié)束的時候改變playDiretion的方向:

      C#代碼 復(fù)制代碼 收藏代碼
      1. public Direction playDirection = Direction.Forward;  

             但是這個控制因為動畫是有時間的,會有問題。所以我只能添加一個Trigger的類型:Trigger.None,然后自己去調(diào)用,就是自己管理動畫的播放,而不是在OnClick中觸發(fā)。』

                                                                                                 增補(bǔ)于 2013,12,23  21:50

       

       

      小結(jié):

             確實很簡單,主要是對緩動函數(shù)的理解,有了這些基礎(chǔ)可以做的事情(特效和動畫)就很多了——屏幕抖動和刀光劍影(下次自己動手嘗試下,哈哈),NGUI的ButtonScale等腳本也是通過UITweener來完成的。但是收獲蠻多的,又一點(diǎn)多了,晚安!

       

             如果您對D.S.Qiu有任何建議或意見可以在文章后面評論,或者發(fā)郵件(gd.s.qiu@gmail.com)交流,您的鼓勵和支持是我前進(jìn)的動力,希望能有更多更好的分享。

              轉(zhuǎn)載請在文首注明出處:http://dsqiu./blog/1974528

      更多精彩請關(guān)注D.S.Qiu的博客和微博(ID:靜水逐風(fēng))

       

      參考:

      ①NGUI: Next-Gen UI kit  3.0.0:http://www./ngui/docs/class_u_i_tweener.html

      ② 緩動函數(shù):http:///zh-cn

      ③Easing Equations by Robbert Penner: http://www./easing/#sin2

      ④Unity3dPack: http://www./?p=300

       

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多