• 大福彩票官网

  • 大福彩票官网

  • 大福彩票官网

  • 大福彩票官网

大福彩票官网

作者︰伊利丹·怒風  發布(bu)日期︰2020-02-18 11:50:49
  •  

    背(bei)景

    前有xin)mu)容小匹夫的一篇《解(jie)構C#游戲(xi)框架uFrame兼談游戲(xi)架構設計(ji)》,引用文中xin)諶/p>

    uFrame是提供給3D開發者使(shi)用的一個框架插件(jian),它(ta)本身模仿(fang)了(liao)MVVM這種架構模式(事實上並不包含(han)Model部分(fen),且多出(chu)了(liao)Controller部分(fen))。因為(wei)用于Unity3D,所以它(ta)向(xiang)開發者提供了(liao)一套基于Editor的可視(shi)化編(bian)輯工具,可以用來管理代(dai)碼結構等(deng)。需要指出(chu)的是它(ta)的一個重要的理念,同時也是軟(ruan)件(jian)工程tao)械囊桓鮒匾﹫砟罹褪槍刈zhu)分(fen)離(Separation of concern,SoC)。uFrame借助控制反轉(zhuan)(IoC)/依賴注(zhu)入(DI)實現了(liao)這種分(fen)離,從而進(jin)一步實現了(liao)MVVM這種模式。且在1.5版本之後,引入了(liao)UniRx庫,引進(jin)了(liao)響應式編(bian)程的思想。

    讀(du)起來高大上,本文主(zhu)要想從實際(ji)出(chu)發,著手最後一句“且在1.5版本之後,引入了(liao)UniRx庫,引進(jin)了(liao)響應式編(bian)程的思想。”,在Unity中如何使(shi)用響應式編(bian)程,如何使(shi)用UniRx庫。

    當bi)灰幌鋁lie)出(chu)這麼多新概念性的東西(xi),作為(wei)新手必(bi)然理解(jie)起來有困難的,當bi)晃乙蠶Mni)是天(tian)賦迥異(yi)的人(ren)。這里列(lie)出(chu)幾點,如果(guo)你(ni)不了(liao)解(jie),請自行去學習或者復習,回來在看也不遲(chi)。

    1、Linq基礎,Linq的本質及與傳統命令式編(bian)程的區別和優點

    2、聲明式編(bian)程和命令式編(bian)程的概念和區別

    3、什麼是響應式編(bian)程

    4、什麼是觀(guan)察者模式

    5、軟(ruan)件(jian)編(bian)程tao)tream的概念

    好了(liao)裝(zhuang)b時間過去了(liao),讓我們簡單(dan)的說下什麼是響應式編(bian)程。這里也不廢(fei)話,引用一huan)duan),看的懂得自然明白,不huan) 沒huai)是不明白

    什麼是反應式編(bian)程︰反應式編(bian)程(Reactive programming)簡稱Rx,他是一個使(shi)用LINQ風格編(bian)寫(xie)基于觀(guan)察者模式的異(yi)步編(bian)程模型。簡單(dan)點說Rx = Observables + LINQ + Schedulers。

    這里為(wei)什麼要在游戲(xi)開發中引入響應式編(bian)程Rx,答案是游戲(xi)特別適(shi)合RX編(bian)程,因為(wei)在游戲(xi)fen)泄惴fan)應用了(liao)時間(幀)和事件(jian)(UI)的概念,時間本身是一種流,而事件(jian)也是基于時間的一種信號(並不是特別準確,意會),而這正是RX所擅長(chang)的。

    600216-20151118151734936-2055036453

    實現

    本文以系列(lie)文章中的精靈鼠標(biao)移動和序(xu)列(lie)幀動畫為(wei)基礎,沒有基礎的先(xian)參考下傳統實現方式一下兩篇文章

    時光煮雨 Unity3D實現2D人(ren)物動畫? UGUI&Native2D序(xu)列(lie)幀動畫

    時光煮雨 Unity3D實現2D人(ren)物動畫? Unity2D 動畫系統&資源效率

    這里引入了(liao)UniRx庫,來實現基于響應式編(bian)程及聲明式編(bian)程代(dai)碼重構,代(dai)碼如下︰

    using UnityEngine;
    using UniRx;

    public class PlayerController : MonoBehaviour
    {
        public float speed;
        private Vector3 moveDirection;

        private int currentTexture = 0;
        public Sprite[] textureArray;
        // Use this for initialization
        void Start()
        {
            //鼠標(biao)控制移動,每幀更新
            Observable.EveryUpdate()
             .Subscribe(_ =>
             {
                 //1、獲(huo)得當前位置
                 Vector3 curenPosition = this.transform.position;
                 //2、獲(huo)得方向(xiang)
                 if (Input.GetButton('Fire1'))
                 {
                     Vector3 moveToward = Camera.main.ScreenToWorldPoint(Input.mousePosition);

                     moveDirection = moveToward - curenPosition;
                     moveDirection.z = 0;
                     moveDirection.Normalize();
                 }
                 //3、插值移動
                 Vector3 target = moveDirection * speed + curenPosition;
                 transform.position = Vector3.Lerp(curenPosition, target, Time.deltaTime);
             });

            //幀動畫
            SpriteRenderer spriteRenderer = GetComponent<SpriteRenderer>();
            //定時器每隔5幀
            Observable.IntervalFrame(5).Subscribe(_ =>
            {
                currentTexture++;
                if (currentTexture >= textureArray.Length)
                {
                    currentTexture = 0;
                }
                spriteRenderer.sprite = textureArray[currentTexture];
            });
        }

    }
    是的沒有看錯,你(ni)沒有發現熟悉(xi)的Update函數,如果(guo)說以上函數讓你(ni)看到就是把所有xie)dai)碼就放在了(liao)Start里面而已,我們再重構一下代(dai)碼,使(shi)用提取方法(fa),看看效果(guo),這就是聲明式編(bian)程的魅力,程序(xu)可讀(du)性增強(qiang),更適(shi)合xian)死嗟乃嘉 絞/p>

    using UnityEngine;
    using UniRx;

    public class PlayerController : MonoBehaviour
    {
        public float speed;
        private Vector3 moveDirection;

        private int currentTexture = 0;
        public Sprite[] textureArray;
        // Use this for initialization
        void Start()
        {
            //鼠標(biao)控制移動,每幀更新
            PlayerMove();

            //角色 幀動畫
            PlayerAnimation();
        }

        /// <summary>
        /// 角色 幀動畫控制
        /// </summary>
        private void PlayerAnimation()
        {
            SpriteRenderer spriteRenderer = GetComponent<SpriteRenderer>();
            //定時器每隔5幀
            Observable.IntervalFrame(5).Subscribe(_ =>
            {
                currentTexture++;
                if (currentTexture >= textureArray.Length)
                {
                    currentTexture = 0;
                }
                spriteRenderer.sprite = textureArray[currentTexture];
            });
        }

        /// <summary>
        /// 鼠標(biao)控制移動,每幀更新
        /// </summary>
        private void PlayerMove()
        {
            Observable.EveryUpdate()
                .Subscribe(_ =>
                {
                    //1、獲(huo)得當前位置
                    Vector3 curenPosition = this.transform.position;
                    //2、獲(huo)得方向(xiang)
                    if (Input.GetButton('Fire1'))
                    {
                        Vector3 moveToward = Camera.main.ScreenToWorldPoint(Input.mousePosition);

                        moveDirection = moveToward - curenPosition;
                        moveDirection.z = 0;
                        moveDirection.Normalize();
                    }
                    //3、插值移動
                    Vector3 target = moveDirection*speed + curenPosition;
                    transform.position = Vector3.Lerp(curenPosition, target, Time.deltaTime);
                });
        }
    }

    總結

    這里記住UniRx兩個方法(fa) Observable.EveryUpdate,Observable.IntervalFrame(這里還(huai)記得以前文章里提的定時器嗎,這個定時器怎(zen)麼樣簡單(dan)吧),還(huai)有ObservableWWW.GetWWW(上一篇的一個異(yi)步加載資源的函數),采(cai)用聲明式編(bian)程的方式,看看函數名就知道是干(gan)什麼的了(liao)吧,還(huai)用看文檔或者解(jie)釋什麼嗎?

    文章內容比(bi)較簡單(dan),實現的功(gong)能也bu)虻dan),函數也bu)虻dan),希望你(ni)們喜歡(huan)。

大福彩票官网

About IT165 -廣告(gao)服務(wu) -隱私(si)聲明 -版權申明 -免(mian)責條款 -網站地(di)圖(tu) -網友投稿(gao) -聯系方式
本站內容來自于互聯網,僅供用于網絡(luo)ke)際(ji)躚 學習中請遵循相關法(fa)律法(fa)規
大福彩票官网 | 下一页