Unity基于响应式编程(Reactive programming)入门

发表于2017-07-19
评论0 1.5k浏览
本篇文章给大家主要介绍的是基于响应式编程(Reactive programming)入门,那么在Unity中如何使用响应式编程,如何使用UniRx库呢?想知道的话就继续往下看。

当然一下列出这么多新概念性的东西,作为新手必然理解起来有困难的,当然我也希望你是天赋迥异的人。这里列出几点,如果你不了解,请自行去学习或者复习,回来在看也不迟。

1、Linq基础,Linq的本质及与传统命令式编程的区别和优点

2、声明式编程和命令式编程的概念和区别

3、什么是响应式编程

4、什么是观察者模式

5、软件编程中Stream的概念

好了装b时间过去了,让我们简单的说下什么是响应式编程。这里也不废话,引用一段,看的懂得自然明白,不懂得还是不明白

什么是反应式编程:反应式编程(Reactive programming)简称Rx,他是一个使用LINQ风格编写基于观察者模式的异步编程模型。简单点说Rx = Observables LINQ Schedulers。

这里为什么要在游戏开发中引入响应式编程Rx,答案是游戏特别适合RX编程,因为在游戏中广泛应用了时间(帧)和事件(UI)的概念,时间本身是一种流,而事件也是基于时间的一种信号(并不是特别准确,意会),而这正是RX所擅长的。

实现

本文以系列文章中的精灵鼠标移动和序列帧动画为基础,没有基础的先参考下传统实现方式一下两篇文章

Unity3D实现2D人物动画(一): UGUI&Native2D序列帧动画

Unity3D实现2D人物动画(二):Unity2D 动画系统&资源效

这里引入了UniRx库,来实现基于响应式编程及声明式编程代码重构,代码如下:

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()
    {
        //鼠标控制移动,每帧更新
        Observable.EveryUpdate()
         .Subscribe(_ =>
         {
             //1、获得当前位置
             Vector3 curenPosition = this.transform.position;
             //2、获得方向
             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();
        //定时器每隔5帧
        Observable.IntervalFrame(5).Subscribe(_ =>
        {
            currentTexture ;
            if (currentTexture >= textureArray.Length)
            {
                currentTexture = 0;
            }
            spriteRenderer.sprite = textureArray[currentTexture];
        });
    }

}
是的没有看错,你没有发现熟悉的Update函数,如果说以上函数让你看到就是把所有代码就放在了Start里面而已,我们再重构一下代码,使用提取方法,看看效果,这就是声明式编程的魅力,程序可读性增强,更适合人类的思维方式

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()
    {
        //鼠标控制移动,每帧更新
        PlayerMove();

        //角色 帧动画
        PlayerAnimation();
    }

    ///


    /// 角色 帧动画控制
    ///

    private void PlayerAnimation()
    {
        SpriteRenderer spriteRenderer = GetComponent();
        //定时器每隔5帧
        Observable.IntervalFrame(5).Subscribe(_ =>
        {
            currentTexture ;
            if (currentTexture >= textureArray.Length)
            {
                currentTexture = 0;
            }
            spriteRenderer.sprite = textureArray[currentTexture];
        });
    }

    ///


    /// 鼠标控制移动,每帧更新
    ///

    private void PlayerMove()
    {
        Observable.EveryUpdate()
            .Subscribe(_ =>
            {
                //1、获得当前位置
                Vector3 curenPosition = this.transform.position;
                //2、获得方向
                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两个方法 Observable.EveryUpdate,Observable.IntervalFrame(这里还记得以前文章里提的定时器吗,这个定时器怎么样简单吧),还有ObservableWWW.GetWWW,采用声明式编程的方式,看看函数名就知道是干什么的了吧,还用看文档或者解释什么吗?

文章内容比较简单,实现的功能也简单,函数也简单,希望你们喜欢。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

标签:

0个评论