游戏蛮牛学习群(纯技术交流,不闲聊):539178957
游戏蛮牛 手机端
开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

教程分享

关注:780

当前位置:游戏蛮牛 技术专区 教程分享

查看: 1177|回复: 5

[实例教程] UniRx - Unity响应式编程插件(5):消息系统 对象池

[复制链接]  [移动端链接]

31

主题

33

帖子

92

积分

Rank: 2Rank: 2

UID
24181
好友
0
蛮牛币
299
威望
0
注册时间
2014-5-7
在线时间
38 小时
最后登录
2018-8-7
发表于 2018-2-10 10:09:23 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x


本文首发于“洪流学堂”微信公众号,转载请注明。
洪流学堂,让你快人几步成为Unity大牛!
本文译者:郑洪智 - 你的技术探路者
本文翻译自UniRx(https://github.com/neuecc/UniRx)插件的ReadMe
这个插件是我特别喜欢的一个插件,希望能将这种技术思想传播给大家
UniRx是什么?
UniRx (Unity响应式编程插件) 重写了.Net的响应式扩展。.Net官方的Rx很棒,但是在Unity中无法使用,并且与IOS的IL2CPP有兼容性问题。这个库这些问题并且添加了一些Unity专属的工具类。 支持的平台有:PC/Mac//iOS/WP8/WindowsStore/等等,并且支持Unity4.6之后的所有版本。
前情回顾
在UniRx - Unity响应式编程插件(1)[http://mp.weixin.qq.com/s/jvSYTplCYHeAL1XrATOeJQ]中讲了
  • 如何让你的代码更简洁
  • 如何简化网络操作
  • 如何和协程一起使用
在UniRx - Unity响应式编程插件(2)[http://mp.weixin.qq.com/s/fzQ3fU5CwE5DZayWbclIcw]中讲了
  • 让多线程更简单
  • 使用触发器让代码更简洁
  • Observable 生命周期管理
在UniRx - Unity响应式编程插件(3)[https://mp.weixin.qq.com/s/H7TIqbdtp5l2wTL-thwKIw]中讲了
  • 将Unity回调转为IObservable
  • 调试Debugging
  • 子线程转到主线程执行
  • 基于帧数的时间操作
  • 微协程
在UniRx - Unity响应式编程插件(4)[https://mp.weixin.qq.com/s/ev4BqWTKBvT0qb-Sthhv_g]中讲了
  • uGUI集成
  • MVP设计模式
ReactiveCommand, AsyncReactiveCommand
ReactiveCommand 抽象了按钮的interactable属性。
public class Player{          public ReactiveProperty<int> Hp;          public ReactiveCommand Resurrect;           public Player()   {                Hp = new ReactiveProperty<int>(1000);             // If dead, can not execute.                Resurrect = Hp.Select(x => x <= 0).ToReactiveCommand();               // Execute when clicked             Resurrect.Subscribe(_ =>             {                    Hp.Value = 1000;               });             }       }       public class Presenter : MonoBehaviour      {           public Button resurrectButton;          Player player;          void Start()    {             player = new Player();              // If Hp <= 0, can't press button.           player.Resurrect.BindTo(resurrectButton);         }       }      
AsyncReactiveCommand是ReactiveCommand的变种,它的 CanExecute (通常绑定到button的interactable) 在异步操作完成后变为false。  
public class Presenter : MonoBehaviour      {           public UnityEngine.UI.Button button;            void Start()    {               var command = new AsyncReactiveCommand();               command.Subscribe(_ =>               {                   // heavy, heavy, heavy method....                   return Observable.Timer(TimeSpan.FromSeconds(3)).AsUnitObservable();                });             // after clicked, button shows disable for 3 seconds                command.BindTo(button);             // Note:shortcut extension, bind aync onclick directly              button.BindToOnClick(_ =>                {                   return Observable.Timer(TimeSpan.FromSeconds(3)).AsUnitObservable();                });         }       }      
AsyncReactiveCommand 有三个构造方法。
  • () - CanExecute is changed to false until async execution finished
  • (IObservable<bool> canExecuteSource) - 当 canExecuteSource 变为 true 并且没有在执行的时候 CanExecute 变为true 。
  • (IReactiveProperty<bool> sharedCanExecute) - 在多个AsyncReactiveCommands之间共享运行状态,如果一个 AsyncReactiveCommand 在执行,那么其他的 AsyncReactiveCommands(拥有相同 sharedCanExecute 属性) 的 CanExecute 变为 false 直到异步操作完成。
public class Presenter : MonoBehaviour{    public UnityEngine.UI.Button button1;    public UnityEngine.UI.Button button2;    void Start()    {        // share canExecute status.        // when clicked button1, button1 and button2 was disabled for 3 seconds.        var sharedCanExecute = new ReactiveProperty<bool>();        button1.BindToOnClick(sharedCanExecute, _ =>        {            return Observable.Timer(TimeSpan.FromSeconds(3)).AsUnitObservable();        });        button2.BindToOnClick(sharedCanExecute, _ =>        {            return Observable.Timer(TimeSpan.FromSeconds(3)).AsUnitObservable();        });    }}MessageBroker, AsyncMessageBroker(消息代理,异步消息代理)
MessageBroker 是基于 Rx 的内存发布订阅(pubsub)系统,基于类型筛选。
public class TestArgs{    public int Value { get; set; }}---// Subscribe message on global-scope.MessageBroker.Default.Receive<TestArgs>().Subscribe(x => UnityEngine.Debug.Log(x));// Publish messageMessageBroker.Default.Publish(new TestArgs { Value = 1000 });
AsyncMessageBroker 是 MessageBroker 的一个变种, 可以处理异步的 Publish 调用。
AsyncMessageBroker.Default.Subscribe<TestArgs>(x =>{    // show after 3 seconds.    return Observable.Timer(TimeSpan.FromSeconds(3))        .ForEachAsync(_ =>        {            UnityEngine.Debug.Log(x);        });});AsyncMessageBroker.Default.PublishAsync(new TestArgs { Value = 3000 })    .Subscribe(_ =>    {        UnityEngine.Debug.Log("called all subscriber completed");    });UniRx.Toolkit
UniRx.Toolkit 包含了一些Rx风格的工具。目前报错 ObjectPool 和 AsyncObjectPool。可以 Rent, Return and PreloadAsync (在rent操作之前预加载对象池)。
// sample classpublic class Foobar : MonoBehaviour{    public IObservable<Unit> ActionAsync()    {        // heavy, heavy, action...        return Observable.Timer(TimeSpan.FromSeconds(3)).AsUnitObservable();    }}public class FoobarPool : ObjectPool<Foobar>{    readonly Foobar prefab;    readonly Transform hierarchyParent;    public FoobarPool(Foobar prefab, Transform hierarchyParent)    {        this.prefab = prefab;        this.hierarchyParent = hierarchyParent;    }    protected override Foobar CreateInstance()    {        var foobar = GameObject.Instantiate<Foobar>(prefab);        foobar.transform.SetParent(hierarchyParent);        return foobar;    }    // You can overload OnBeforeRent, OnBeforeReturn, OnClear for customize action.    // In default, OnBeforeRent = SetActive(true), OnBeforeReturn = SetActive(false)    // protected override void OnBeforeRent(Foobar instance)    // protected override void OnBeforeReturn(Foobar instance)    // protected override void OnClear(Foobar instance)}public class Presenter : MonoBehaviour{    FoobarPool pool = null;    public Foobar prefab;    public Button rentButton;    void Start()    {        pool = new FoobarPool(prefab, this.transform);        rentButton.OnClickAsObservable().Subscribe(_ =>        {            var foobar = pool.Rent();            foobar.ActionAsync().Subscribe(__ =>            {                // if action completed, return to pool                pool.Return(foobar);            });        });    }}UniRx插件系列已完结,关注“洪流学堂”公众号获取全部内容

回复

使用道具 举报

7日久生情
2536/5000
排名
3502
昨日变化
3

2

主题

1780

帖子

2536

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
241666
好友
0
蛮牛币
10199
威望
0
注册时间
2017-9-6
在线时间
362 小时
最后登录
2018-6-7
发表于 2018-2-12 13:28:10 来自Mobile--- | 显示全部楼层
感谢分享

回复

使用道具 举报

7日久生情
3143/5000
排名
2232
昨日变化
6

0

主题

2099

帖子

3143

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
219676
好友
1
蛮牛币
2441
威望
0
注册时间
2017-7-12
在线时间
464 小时
最后登录
2018-8-16

活力之星

发表于 2018-2-12 18:13:10 来自Mobile--- | 显示全部楼层
谢谢分享

回复

使用道具 举报

7日久生情
3143/5000
排名
2232
昨日变化
6

0

主题

2099

帖子

3143

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
219676
好友
1
蛮牛币
2441
威望
0
注册时间
2017-7-12
在线时间
464 小时
最后登录
2018-8-16

活力之星

发表于 2018-2-12 18:14:15 来自Mobile--- | 显示全部楼层
谢谢分享

回复

使用道具 举报

5熟悉之中
837/1000
排名
5376
昨日变化
7

0

主题

433

帖子

837

积分

Rank: 5Rank: 5

UID
146677
好友
9
蛮牛币
2720
威望
0
注册时间
2016-4-25
在线时间
164 小时
最后登录
2018-8-9
QQ
发表于 2018-2-26 14:25:06 | 显示全部楼层
这是个好东西,谢谢

回复 支持 反对

使用道具 举报

3偶尔光临
208/300
排名
17600
昨日变化
7

0

主题

123

帖子

208

积分

Rank: 3Rank: 3Rank: 3

UID
266755
好友
0
蛮牛币
12
威望
0
注册时间
2018-1-29
在线时间
53 小时
最后登录
2018-5-2
发表于 2018-3-5 22:11:03 | 显示全部楼层
涂涂画画的开发插件 Drawing & Coloring (Extra Edition) 1.09

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 返回顶部 返回列表