Как отфильтровать одну наблюдаемую с другой наблюдаемой?

С помощью 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);
        });

Я думаю, что, возможно, я иду в неправильном направлении.


person Evgeni Petrov    schedule 22.11.2016    source источник
comment
Может быть, не очевидно, что я использую UniRx? github.com/neuecc/UniRx   -  person Evgeni Petrov    schedule 22.11.2016
comment
Что означает выполнение только тогда, когда B не является потоковым?   -  person Enigmativity    schedule 23.11.2016


Ответы (3)


Трудно только комбинировать операторы.

Два потока не синхронизированы. Когда сообщение OnNext приходит из потока B, как долго отключается поток A? Сообщение следующего потока B? или Следующий поток А?

Если вы хотите остановить только один кадр, как насчет этого?

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 об уничтоженном игровом объекте.

person torisoup    schedule 22.11.2016
comment
Я пытаюсь сделать это исключительно с потоками. Я хочу ноль логических значений. - person Evgeni Petrov; 23.11.2016
comment
@EvgeniPetrov - Что вы подразумеваете под чисто потоками? - person Enigmativity; 23.11.2016
comment
Я не хочу иметь никакого государства. Логические значения являются состоянием. Я хочу, чтобы все было получено из событий и ввода. - person Evgeni Petrov; 23.11.2016
comment
Я думаю, что это слишком сложно сделать только с потоками. - person torisoup; 23.11.2016
comment
Другой способ — создать оператора самостоятельно. - person torisoup; 23.11.2016

Я просто придумал другой способ.

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

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

Можете ли вы предоставить немного больше информации о фактическом поведении игры, которое вы пытаетесь реализовать?

Я предполагаю, что есть какой-то другой подход к тому, что вы пытаетесь сделать, не полагаясь на EveryUpdate (например, используя OnTriggerStay и/или OnTriggerExit).

Просто угадаю, что вы подразумеваете под «отрицательным» в образце оператора: вы можете взглянуть на pausable< /а>. Однако вам придется сгенерировать правильные логические значения, и то, как это сделать, действительно зависит от того, какое игровое поведение вы на самом деле пытаетесь реализовать здесь.

person Urs Hanselmann    schedule 22.11.2016
comment
Я не могу найти паузу в UniRx. :( - person Evgeni Petrov; 23.11.2016
comment
Может быть, я могу как-то реализовать это сам? Я изучу его, когда у меня будет время. - person Evgeni Petrov; 23.11.2016