UniRx第一季学习(四) ------ UGUI事件支持/ReactiveProperty/MVP 实现

课程地址 : http://www.sikiedu.com/course/271

凉鞋大大的,可以的话大家多支持一波~


一.UGUI事件支持

UGUI 增强的原理很简单,就是对 UnityEvent 提供了 AsObservable ⽅法。
代码如下:

public Button mButton;
mButton.onClick.AsObservable().Subscribe(_ => Debug.Log("clicked"));

1.按钮点击事件

mButton.OnClickAsObservable()
.Subscribe(_ => 
{
// do something
});

2.Toggle

mToggle.OnValueChangedAsObservable()
.Subscribe(on =>
{
if (on)
{
// do some thing
}
});

同时支持操作符

mButton.OnClickAsObservable()
.First()
.Subscribe(_ => 
{
// do something
});

不⽌如此,还⽀持 EventSystem 的各种 Trigger 接⼝的监听。

3.Image 的拖拽

mImage.OnBeginDragAsObservable().Subscribe(_=>{});
mImage.OnDragAsObservable().Subscribe(eventArgs=>{});
mImage.OnEndDragAsObservable().Subscribe(_=>{});

4.Event

UnityEvent mEvent;
void Start()
{
   mEvent.AsObservable()
   .Subscribe(_ => 
   {
     // process event
   });
}

二.响应式属性ReactiveProperty

可以替代⼀切变量,给变量创造了很多功能。
假如我们想监听⼀个值是否发⽣了改变。

public int Age
{
   get
   {
     ...
   }
  set
  {
      if (mAge != value)
      {
        mAge = value;
        // send event
        OnAgeChanged();
        // call delegate
      }
  }
}
public void OnAgeChanged()
{
}

这样在类的内部,写⼀次 OnAgeChanged 是没问题的。但是我想在这个类的外部监听这个值的改变,
那就要声明⼀个委托来搞定了。委托的维护成本⽐较低,是可以接受的,直到发现了 UniRx 的ReactiveProperty。就再也不想⽤委托来做这种⼯作了

public class ReactivePropertyExample : MonoBehaviour
    {
        public IntReactiveProperty Age = new IntReactiveProperty(0);

        void Start()
        {
            Age.Subscribe(age =>
            {
                Debug.Log("inner received age changed");
            });

            Age.Value = 10;
        }
    }


    public class PersonView
    {
        ReactivePropertyExample mReactiveProeprtyExample;

        void Init()
        {
            mReactiveProeprtyExample.Age.Subscribe((age) =>
            {
                Debug.Log(age);
            });
        }
    }

当任何时候,Age 的值被设置,就会通知所有 Subscribe 的回调函数。
⽽ Age 可以被 Subscribe 多次的。
并且同样⽀持 First、Where 等操作符。

 三.MVP 实现

MVP 设计模式 : Model-View-(Reactive)Presenter Pattern

在 Ctrl 中,进⾏ Model 和 View 的绑定。Model 的所有属性都是⽤ ReactiveProperty,然后在 Ctrl 中进⾏订阅。
通过 View 更改 Model 的属性值。形成⼀个 View->Ctrl->Model->Ctrl->View 这么⼀个事件响应环。

扫描二维码关注公众号,回复: 4710066 查看本文章

参考以下案例,可以看出UniRx可以迎送实现MVC模式:

 public class EnemyExample : MonoBehaviour
    {
        [SerializeField] EnemyModel mEnemy = new EnemyModel(200);

        void Start()
        {
            var attackBtn = transform.Find("Button").GetComponent<Button>();
            var HPText = transform.Find("Text").GetComponent<Text>();

            attackBtn.OnClickAsObservable()
                     .Subscribe(_ =>
                     {
                         mEnemy.HP.Value -= 99;
                     });

            mEnemy.HP.SubscribeToText(HPText);

            mEnemy.IsDead
                  .Where(isDead => isDead)
                  .Select(isDead => !isDead)
                  .SubscribeToInteractable(attackBtn);
        }
    }

    // Model
    public class EnemyModel
    {
        public ReactiveProperty<long> HP;

        public IReadOnlyReactiveProperty<bool> IsDead;

        public EnemyModel(long initialHP)
        {
            HP = new ReactiveProperty<long>(initialHP);

            IsDead = HP.Select(hp => hp <= 0).ToReactiveProperty();
        }
    }

在 Unity ⾥,序列化是⼀个很重要的功能,如果不可序列化,则在编辑器上就看不到参数。⽽ReactiveProperty 是泛型的,序列化起来⽐较麻烦。为了解决这个问题,UniRx ⽀持了可序列化的ReactiveProperty 类型,⽐如 Int/LongReactivePropety、Float/DoubleReactiveProperty、StringReactiveProperty、BoolReactiveProperty,还有更多,请参见InspectableReactiveProperty.cs。

如果你需要 [Multiline] 或者[Range] 添加到 ReactiveProperty 上,你可以使⽤MultilineReactivePropertyAttribute 和 RangeReactivePropertyAttribute 替换 Multiline 和 Range。

这些 InspectableReactiveProperties 可以在 inspector ⾯板显示,并且当他们的值发⽣变化时发出通知,甚⾄在编辑器⾥变化也可以。

这里提一下MVVM :

MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。当然这些事 ViewModel 已经帮我们做了,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑。

这里没有实现MVVM的原因是Unity 没有提供 UI 绑定机制,创建⼀个绑定层过于复杂并且会对性能造成影响(使⽤反射)。尽管如此,视图还是需要更新。Presenters 层知道 View 组件并且能更新它们

猜你喜欢

转载自blog.csdn.net/dengshunhao/article/details/85376438