[Unity 3d] 如何在自己寫的動效中加入漂亮的緩動嘞?

筆者覺得一個好緩動效果的使用墨缘,往往會讓人覺得這個游戲對象瞬間活潑起來就像有了生命一般星虹,Easing 就是這般神奇。在本文镊讼,筆者帶大家寫一個具有緩動效果的 PingPong 動效宽涌。

EasingCore

巧婦難為無米之炊,我們要先整理一些 Ease 算法先蝶棋,沒想人家早早的就整理了一份放到 GitHub 上咯~(其實 Itween里面也有一套 Ease 算法哈)
EasingCore-GitHub

怎么用 EasingCore:

怎么用EasingCore卸亮,超簡單:

float value = EasingFunction.Get(easetype).Invoke(progress);

這樣獲得的值就是被算法修正的值啦。

PingPong

用上了這個EasingCore 的 PingPong動效模塊玩裙,:

using EasingCore;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using zFrame.Extend;
using Ease = EasingCore.Ease;

public class PingPong : MonoBehaviour
{
    #region SelfField
    float progress = 0;
    bool addition = true;
    private CoroutineHandler coroutine;
    #endregion
    #region Configration Parameter
    private event Action<float> action;
    private Ease ease = Ease.Linear;
    private float delay = 0;
    #endregion
    #region 單例
    static PingPong driver;
    static PingPong Driver
    {
        get
        {
            if (null == driver)
            {
                GameObject go = new GameObject("[PingPongDriver]");
                driver = go.AddComponent<PingPong>();
                GameObject.DontDestroyOnLoad(go);
                go.hideFlags = HideFlags.HideAndDontSave;
            }
            return driver;
        }
    }
    private void Awake()
    {
        driver = this;
    }
    #endregion
    #region PingPongBehaviours
    public static PingPong OnUpdate(Action<float> action)
    {
        if (null == Driver.action) 
        {
            Driver.action = action; 
        }
        else
        {
            List<Delegate> list = new List<Delegate>(Driver.action.GetInvocationList());
            if (!list.Contains(action))
            {
                Driver.action += action;
            }
        }
        return Driver;
    }
    public PingPong SetEase(Ease ease)
    {
        this.ease = ease;
        return Driver;
    }
    public PingPong SetDelay(float delay)
    {
        this.delay = delay;
        return Driver;
    }
    public void Play()
    {
        if (null == coroutine)
        {
            coroutine = Handler().Start();
        }
    }
    private void Finish()
    {
        coroutine.Stop();
        coroutine = null;
        action = null;
    }
    public static void Stop()
    {
        Driver.Finish();
    }
    #endregion
    IEnumerator Handler()
    {
        yield return new WaitForSeconds(delay);
        while (true)
        {
            progress += (addition ? 1 : -1) * Time.deltaTime ;
            progress = Mathf.Clamp01(progress);
            addition = progress == 1 ? false : progress == 0 ? true : addition;
            float value = EasingFunction.Get(ease).Invoke(progress);
            action?.Invoke(value);
            yield return 0;
        }
    }
}

這個實現(xiàn)比較無聊嫡良,僅僅是做的好玩,所以居然使用了單例献酗,哈哈寝受。
然后,使用了鏈式編程風格以配置參數(shù):

怎么使用:

演示代碼罕偎,應該沒有什么復雜需要特別注解的地方了

using UnityEngine;

public class TestBreath : MonoBehaviour
{
    public EasingCore.Ease ease = EasingCore.Ease.InExpo;
    public Transform endPoint;
    public float delay = 2;
    public float factor = 0.5f;
    Vector3 v3; //緩存起點
    Vector3 ve; //終點

    void Start()
    {
        v3 = transform.position;
        Play();
    }
    [EditorButton]
    public void Restart()
    {
        PingPong.Stop();
        transform.position = v3;
        Play();
    }
    private void Play()
    {
        ve = endPoint.position;
        Vector3 dr = ve - v3; //獲得起點指向終點的向量
        float dis = Vector3.Distance(v3, ve); //獲得向量距離很澄,

        PingPong.OnUpdate(v =>
        {
            Vector3? pos = v3 + dr.normalized * dis * v; // 使用可空值接這個數(shù)據(jù)
            transform.position = pos.HasValue ? pos.Value : transform.position;
        }).SetEase(ease) //設置 Ease 模式
          .SetDelay(delay) //設置延時多久后播放動畫
          .SetFactor(factor) //等效于設置動畫時長
          .Play();
    }
}

動畫演示:

Pingpong + EasingCore

總共有30個緩動,動畫中幾個動效為隨機測試颜及。

擴展閱讀:

Unity EditorButton - GitHub
[Unity3D] 協(xié)程管理CoroutineManager - 簡書
[Unity 3d] 如何優(yōu)雅的寫一個PingPong效果 - 簡書

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末甩苛,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子俏站,更是在濱河造成了極大的恐慌讯蒲,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肄扎,死亡現(xiàn)場離奇詭異墨林,居然都是意外死亡赁酝,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門旭等,熙熙樓的掌柜王于貴愁眉苦臉地迎上來酌呆,“玉大人,你說我怎么就攤上這事搔耕∠对” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵弃榨,是天一觀的道長菩收。 經常有香客問我,道長鲸睛,這世上最難降的妖魔是什么娜饵? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮腊凶,結果婚禮上划咐,老公的妹妹穿的比我還像新娘拴念。我一直安慰自己钧萍,他們只是感情好,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布政鼠。 她就那樣靜靜地躺著风瘦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪公般。 梳的紋絲不亂的頭發(fā)上万搔,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天,我揣著相機與錄音官帘,去河邊找鬼瞬雹。 笑死,一個胖子當著我的面吹牛刽虹,可吹牛的內容都是我干的酗捌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼涌哲,長吁一口氣:“原來是場噩夢啊……” “哼胖缤!你這毒婦竟也來了?” 一聲冷哼從身側響起阀圾,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤哪廓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后初烘,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涡真,經...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡分俯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了综膀。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片澳迫。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖剧劝,靈堂內的尸體忽然破棺而出橄登,到底是詐尸還是另有隱情,我是刑警寧澤讥此,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布拢锹,位于F島的核電站,受9級特大地震影響萄喳,放射性物質發(fā)生泄漏卒稳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一他巨、第九天 我趴在偏房一處隱蔽的房頂上張望充坑。 院中可真熱鬧,春花似錦染突、人聲如沸捻爷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽也榄。三九已至,卻和暖如春司志,著一層夾襖步出監(jiān)牢的瞬間甜紫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工骂远, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留囚霸,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓激才,卻偏偏與公主長得像拓型,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子贸营,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內容