UniRx之ReactiveProperty实现MVP-创新互联

前言

ReactiveProperty:反应式属性,即可以支持Rx编程方式的属性语法。
我们一般创建的属性如:

公司主营业务:成都网站建设、做网站、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。成都创新互联公司是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。成都创新互联公司推出惠阳免费做网站回馈大家。
private int age;
private string name;
private float score;

这些游戏属性通常需要通知变化,我们可以使用事件回调,但是太麻烦了,好在UniRx为我们提供了ReactiveProperty,一个轻量级的属性代理。

示例

我们先声明一个数据模型类,它定义了一个Enemy类,里面由Hp血量,和IsDead是否死亡属性,因为两者是有一定关系的,所以可以定义IsDead为ReadOnlyReactiveProperty,然后和血量 x<=0 绑定起来。

// 反应式通知 model数据类
    public class Enemy
    {public IReactivePropertyCurrentHp {get; private set; }

        public IReadOnlyReactivePropertyIsDead {get; private set; }

        public Enemy(int initialHp)
        {// 声明属性
			CurrentHp = new ReactiveProperty(initialHp);
            IsDead = CurrentHp.Select(x =>x<= 0).ToReactiveProperty();
        }
    }

接下来我们还可以让UI和Model数据进行绑定,来达到MVP或者MVVM框架的目的

public class Sample12_ReactiveProperty : MonoBehaviour
    {// Open Sample12Scene. Set from canvas
        public Button MyButton;
        public Toggle MyToggle;
        public InputField MyInput;
        public Text MyText;
        public Slider MySlider;

		// ReactiveProperty属性可以序列化在Inspector面板, 我们可以通过序列化方式修改它
        public IntReactiveProperty IntRxProp = new IntReactiveProperty();
		//定义Enemy数据类
        Enemy enemy = new Enemy(1000);

        void Start()
        {// UnityEvent 转 Observable
            // (快捷方式, MyButton.OnClickAsObservable())
            // 点击按钮Hp-=99
            MyButton.onClick.AsObservable().Subscribe(_ =>enemy.CurrentHp.Value -= 99);

            // Toggle, 输出参数给Observable(OnValueChangedAsObservable可以广播一个bool类型value
            // SubscribeToInteractable 是 UniRx.UI扩展方法,相当于 .interactable = x)
            MyToggle.OnValueChangedAsObservable().SubscribeToInteractable(MyButton);

            // input 延迟1s 展示在myText上
            MyInput.OnValueChangeAsObservable()
                .Where(x =>x != null)
                .Delay(TimeSpan.FromSeconds(1))
                .SubscribeToText(MyText); // SubscribeToText 是UniRx.UI 扩展方法
            // 转化为可视化数据
            MySlider.OnValueChangedAsObservable()
                .SubscribeToText(MyText, x =>Math.Round(x, 2).ToString());

            // 基于RxProp的属性 CurrentHp的变化(Button Click)是可观察的
            enemy.CurrentHp.SubscribeToText(MyText);
            // 当enemy血量<0后,广播事件,让myButton和MyToggle设置为不可见
            enemy.IsDead.Where(isDead =>isDead == true)
                .Subscribe(_ =>{MyToggle.interactable = MyButton.interactable = false;
                });

            // 用IntRxProp的值初始化 text:)
            IntRxProp.SubscribeToText(MyText);
        }
    }
总结

通过这个例子,我们可以看到一些UI框架的缩影。
1.战斗时角色持续掉血,且实时刷新UI的场景。
2.设置页面开关控制全局音效,音量的功能。
3.某些特殊技能导致的掉血,延迟表现到人物血条上或者飘字上。
4.角色死亡引起不同界面,不同实体的不同变化。

我们庆幸,现在有了UniRx,我们可以省去了大量的事件回调的编写。省去了大量的MVVM高耦合代码逻辑。可以很轻量化的编写一个MVP(MVRP)架构的UI框架了。
在这里插入图片描述
我们直到Unity没有提供UI绑定机制,如果使用MVVM模式,我们需要实现复杂的绑定层,这可能会影响性能。所以我们需要使用Presenter持有视图并更新视图,虽然不是真正的绑定,但是Observables启用了对通知的订阅,这个模式我们成为ReactivePresenter模式。
在这里插入图片描述
在Unity的Hierarchy中,试图就是一个场景,试图初始化时和Presenters关联,xxxAsObservable方法使得创建事件信号变得简单,没有任何开销,再搭配UniRx.UI.Extension中的一些简单工具函数,可以实现一个高性能和简洁的体系结构。

Reactive属性

这些属性均派生自InspecetableReactiveProperty,可以在Inspector面板序列化,当值发生变化时可以通知,在Inspector中更改值时也会发出通知。

//数值型
    private IntReactiveProperty a1;
    private LongReactiveProperty a2;
    private ByteReactiveProperty a3;
    //浮点型
    private FloatReactiveProperty b1;
    private DoubleReactiveProperty b2;
    //bool型
    private BoolReactiveProperty c1;
    //string型
    private StringReactiveProperty c2;
	//向量,四元数
    private Vector2ReactiveProperty v1;
    private Vector3ReactiveProperty v2;
    private Vector4ReactiveProperty v3;
    private QuaternionReactiveProperty q1;
    //颜色
    private ColorReactiveProperty color;
    //其他
    private RectReactiveProperty rect;
    private BoundsReactiveProperty bound;
    private AnimationCurveReactiveProperty anim;
    //集合型
    private ReactiveCollectionlist;
    private ReactiveDictionarydict;

序列化功能由 InspectorDisplayDrawer提供,通过继承你可以应用你自己自定义的ReactiveProperty:

public enum Fruit
{Apple, Grape
}

[Serializable]
public class FruitReactiveProperty : ReactiveProperty{public FruitReactiveProperty()
    {}

    public FruitReactiveProperty(Fruit initialValue)
        :base(initialValue)
    {}
}

[UnityEditor.CustomPropertyDrawer(typeof(FruitReactiveProperty))]
[UnityEditor.CustomPropertyDrawer(typeof(YourSpecializedReactiveProperty2))] // and others...
public class ExtendInspectorDisplayDrawer : InspectorDisplayDrawer
{}

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


分享名称:UniRx之ReactiveProperty实现MVP-创新互联
URL标题:http://scyanting.com/article/diisop.html