如何用另一个observable过滤一个observable?

时间:2016-11-22 11:20:27

标签: unity3d reactive-programming reactive

使用https://github.com/neuecc/UniRx

我有两个可观察的A和B.

我希望A按B过滤。Sample似乎就像我想要的那样,但却是负面的。

IObservable<long> A = Observable.EveryUpdate();            
IObservable<Collider2D> B = this.OnTriggerEnter2DAsObservable()
                .Where( x => x.gameObject.tag == "Wall");

我想要某种像这样的伪代码:

A.filterBy(B)
 .Subscribe(x => Debug.Log(x)); //executed only when B is not streaming

(UPDATE1) 这是实际的代码。我试图用冲突流取消输入流。

    var isCollidingWithWall = this.OnTriggerEnter2DAsObservable()
        .Where(collider => collider.gameObject.tag == "Wall");

    Func<long, float> displaceCalculate = (_) => this.Speed * Time.deltaTime;

    var moveLeft = Observable.EveryUpdate()
        .Where(_ => Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow));
    var moveRight = Observable.EveryUpdate()
        .Where(_ => Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow));

    var movement1 = moveLeft
        .Select(displaceCalculate)
        .Select(f => -f);

    var movement2 = moveRight
        .Select(displaceCalculate);

    movement2
        .Merge(movement1)
        .Subscribe(f =>
        {
            this.transform.position = new Vector2(this.transform.position.x + f, this.transform.position.y);
        });

我想我可能会走错方向。

3 个答案:

答案 0 :(得分:1)

很难只合并运营商。

两个流未同步。 当OnNext消息来自流B时,关闭流A多长时间? 下一个B流消息?或下一个流A?

如果你想只停一帧,那怎么样?

void Start()
{
    var isCollisionEntered = false;

    this.OnCollisionEnter2DAsObservable()
        .Where(x => x.gameObject.tag == "Wall")
        .Subscribe(_ => isCollisionEntered = true);

    this.LateUpdateAsObservable()
        .Where(_ => isCollisionEntered)
        .Subscribe(_ => isCollisionEntered = false);

    this.UpdateAsObservable()
        .Where(_ => !isCollisionEntered)
        .Subscribe(_ => Debug.Log("Do here"));
}

并且,我不建议Observable.EveryUpdate。管理生命周期是必要的。

我建议改用this.UpdateAsObservable(UniRx.Triggers)。 它会自动在被破坏的游戏对象上发布OnCompleted消息。

答案 1 :(得分:1)

我想出了另一种方式。

    var streamB = this.OnTriggerEnter2DAsObservable().AsUnitObservable();

    this.UpdateAsObservable()
        .TakeUntil(streamB)
        .RepeatUntilDestroy(this)
        .Subscribe(_ =>
        {
            Debug.Log(Time.frameCount);
        });

答案 2 :(得分:0)

您能否提供一些关于您尝试实施的实际游戏行为的更多背景信息?

我的猜测是,您可以尝试做其他方法,而不必依赖EveryUpdate(例如,使用OnTriggerStay和/或OnTriggerExit)。

只是猜测你的意思&#34;否定&#34;示例运算符:您可能需要查看pausable。您必须生成正确的布尔值,并且如何做到这一点实际上取决于您实际尝试在此处实现的游戏行为。