UniWb-2- Action

目的

   当用 cocos2d 的时候有 Sequence ,  Spawn, Delay , MoveTo,Event 等函数可供调用,很方便的解决一些顺序执行和同步的执行的逻辑

但是在 Unity 中并没有好用的办法,例如 写个定时器还要写个协程,当然有很多人封装了自己的 Timer 做一些简单的定时任务,调用的很方便,但是在顺序执行方面却很达到我想要的功能,由此而生 UniWb Action 。

    同时 Action 由 UniRx 封装而来,借助 UniRx 这个强大的插件。


定时

   定时是很重要的功能,我只希望调用要简单,同时能有回调接口就更好了


using Wb;
public class NewBehaviourScript : MonoBehaviour
{
    void Start()
    {
        this.Delay(2,a=> {
            Debug.Log("延迟2秒后执行");
        }).Begin(this);

        // 相同功能
        this.Delay(2, a =>
        {
            Debug.Log("延迟2秒后执行");
        }).Begin().AddTo(this);
    }
}

这里 Begin 的意思是开始执行的意思,传入this 的意思是随组件的生命周期而结束,也就是说,不管这个延时有没有走完,当组件销毁的时候也就结束了。

第二种写法

this.Delay(2)
    .Event(a =>
    {
       Debug.Log("延迟2秒后执行");
    }).Begin(this);

这里引入 Event 写法,目的就是与 Delay 任意组合,也就是你可以这么写

this.Event(a =>
{
   Debug.Log("先执行的操作");
}).Delay(2)
.Event(a=> {
   Debug.Log("延迟2秒后执行");
}).Begin(this);

嗯,有了 Delay 和 Event 其实已经能解决大部分问题

我需要这个定时器能够执行我需要的次数

this.Delay(2, 3, a =>
{
     Debug.Log("延迟2秒后执行,执行三次,现在次数 :" + a);
}).Begin(this);
 IDisposable disposable = this.Delay(2, -1, a =>
 {
    Debug.Log("延迟2秒后执行,无限循环, 当手动执行 disposable.Dispose() 时结束");
 }).Begin(this);

 // disposable.Dispose();

每一个链都会返回一个 IDisposable 对象,想手动结束的时候就 Dispose() 掉就可以了。


同步 Spawn

   有时候你的确需要这个功能,来进行同步这操作

this.Event(a =>
{
     Debug.Log("先执行");
}).Spawn(
     this.Delay(2, a => { Debug.Log("aaaa"); }),
     this.Delay(4, a => { Debug.Log("bbbb"); })
).Event(a => {
      Debug.Log("两个延时执行完毕");
}).Begin(this);

当两个定时器都执行完毕后,才会输出 “两个延时执行完毕”

你甚至会发现 Spawn 居然能跟 Event 任意组合在一起,多么美好~~~

这里有个限制,也就是 Spawn 里的参数要是同类型的,暂时没想到什么好办法~~


Complete

有时我们需要在事件流的最后有一个回调,那么写个 Complete 吧,会方便很多,如果你真的理解 UniRx 其实就是 .Subscribe(a=> {   })

调用,嗯,后面再说说。

this.Delay(2)
.Event(a =>
{
   Debug.Log("1111");
})
.Delay(2)
.Event(a =>
{
    Debug.Log("222");
})
.Delay(2)
.Complete(_ =>
{
    Debug.Log("333");
}).AddTo(this);

DOTween

要很好的让 object 执行相关的运动,那么 DOTween 将会比较好的选择,因为光靠 Unity 实在实现比较麻烦,所以在 UniWb 里集成 DOTween 。嗯,就是那个 1.0.155 DOTween Pro 版本,AssetStore 里最新版本。

当然为了让它更好的融进链式表达式中,我新建了一个接口,就是为了容纳它,谁叫它这么好用呢。。。

using DG.Tweening;
 

this.DOTween(transform.DOMoveX(2, 2)).Begin(this);

嗯,就是这么用就可了,物体就会在两秒内x 轴移动两个单位长度。

你此时可能会想,这么做不是多此一举吗,跟我直接调用有什么区别呢?

this.Delay(2)
    .Event(a =>
    {
        Debug.Log("运动前");
    })
    .DOTween(transform.DOMoveX(2, 2))
    .Event(a=> {
        Debug.Log("运动后");
    })
    .Begin(this);

我们的目的是为了让它融进链中~~~~

 this.Delay(2)
     .DOTween(transform.DOMoveX(2, 2))
     .DOTween(transform.DOMoveY(2, 2))
     .DOTween(transform.DOScale(2, 2))
     .Begin(this);

它会按照顺序执行,

好,我们要结合 Spawn 去使用了

 this.Delay(2)
     .Spawn(
         this.DOTween(transform.DOMoveY(2, 2)),
         this.DOTween(transform.DOMoveX(2, 2)) 
     )
     .Spawn(
         this.DOTween(transform.DOMoveY(0, 2)),
         this.DOTween(transform.DOMoveX(0, 2))
     )
     .Begin(this);

同时 MoveX 和 MoveY , 获取你已经猜到了,它会斜着运动, 这段代码,就是先会斜着运动两个单位长度,然后再运动回来。


与 UniRx 结合

前面介绍的其实已经足够帮助你解决很多比较麻烦的问题了,但是它们既然来自 UniRx ,那么配合着 UniRx 将会有更强大的威力

 var clickStream = Observable.EveryUpdate()
               .Where(_ => Input.GetMouseButtonDown(0));

        clickStream.Buffer(clickStream.Throttle(TimeSpan.FromMilliseconds(250)))
              .Where(xs => xs.Count >= 2)
              .FEvent(a =>
              {
                  Debug.Log("do something");
              }).
              Delay(2).
              FDOTween(transform.DOMoveX(1, 1)).
              Begin(this);

再没有比这个示例更能说明问题的了,

这段代码实现的功能就是,当鼠标双击的时候 输出 "do something" 后,延时2秒后执行 动画移动一个单位长度。

你会发现有点不一样的地方,就是 FEvent , FDOTween , 为什么要加个 F 呢,

嗯,这里其实是 Filter 的 F ,就是为了 和 Event ,DOTween 区分开来,

因为这里的流是 持续流,我想你又记起前面水管的话了,对!这里 持续流,要么我主动 Dispose 掉,要么随着 物体销毁而销毁掉。

而主要的区别是在 OnNext 和 OnComplete , 持续流在没停止前是不会调用 OnComplete 的~~~~~

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值