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中的一些简单工具函数,可以实现一个高性能和简洁的体系结构。
这些属性均派生自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元起,快前往官网查看详情吧