ささみのメモ帳

ゲーム会社で働く、無能プログラマーが自分のためのメモ帳として利用しています。

R3についてのメモ

R3とは

UniRxと同様に、Rx機能をより幅広いプラットフォームで利用できるようにし、 async/awatiとの連携強化、一部機能更新等が行われたライブラリ。

UniRxについては、こちらに雑にまとめてる。 shiromisasami.hatenablog.com

具体的な利用パターン

一定時間内に来る同様の処理では初回だけ処理して他は無視する
using R3;
using System;
using UnityEngine;

public class R3Test : MonoBehaviour
{
    private Subject<(int, float)> _subject = new Subject<(int, float)>();

    private int _index = 1;
    private float _value = 1.0f;

    void Start()
    {
        //Subjectの内容設定
        _subject
        // _subjectのNextで10秒間区切りの連続のうち最初だけを通過させる
        .ThrottleFirst(TimeSpan.FromSeconds(10))
        .Subscribe(tuple =>
        {
            var (index, Value) = tuple;
            Debug.Log("Index:" + index + " float:" + Value + " Time:" + Time.time);
        })
        .AddTo(this);
    }

    void Update()
    {
        _subject.OnNext((_index, _value));
        ++_index;
        _value += 10.0f;
    }
}

Observable内で一定時間内に来る同じ処理の初回だけ処理して他は無視する
using R3;
using Cysharp.Threading.Tasks;
using System;
using UnityEngine;

public class R3Test : MonoBehaviour
{
    private int _index = 1;
    private float _value = 1.0f;

    void Start()
    {
        Observable.Create<(int, float)>(async (observer, ct) =>
        {
            observer.OnNext((_index, _value));
            ++_index;
            _value += 10.0f;
            //5秒待機
            await UniTask.Delay(TimeSpan.FromSeconds(5), cancellationToken: ct);
            observer.OnNext((_index, _value));
            ++_index;
            _value += 10.0f;
            //5秒待機
            await UniTask.Delay(TimeSpan.FromSeconds(5), cancellationToken: ct);
            observer.OnNext((_index, _value));
            observer.OnCompleted();
        })
        // Observable内のOnNextを10秒間区切りの連続のうち最初だけを通過させる
        .ThrottleFirst(TimeSpan.FromSeconds(10))
        .Subscribe(tuple =>
        {
            var (index, Value) = tuple;
            Debug.Log("Index:" + index + " float:" + Value + " Time:" + Time.time);
        })
        .AddTo(this);
    }
}

入力処理とそれに伴う値変化の通知
using R3;
using R3.Triggers;
using UnityEngine;

public class R3Test : MonoBehaviour
{
    private R3.ReactiveProperty<int> _rpInt = new(0);

    void Start()
    {
        //入力で値加算/減算
        this.UpdateAsObservable()
        .Where(_ => Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.D))
        .Subscribe(_ =>
        {
            if (Input.GetKeyDown(KeyCode.A))
            {
                _rpInt.Value++;
            }
            else if (Input.GetKeyDown(KeyCode.D))
            {
                _rpInt.Value--;
            }
        })
        .AddTo(this);
        //値変化による通知取得
        _rpInt.Subscribe(value =>
        {
            Debug.Log("ChangeValue:" + value);
        })
        .AddTo(this);
    }
}

入力処理とそれに伴う配列値変化の通知
using R3;
using R3.Triggers;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;

public class R3Test : MonoBehaviour
{
    private R3.ReactiveProperty<List<int>> _rpIntList = new(new List<int>(Enumerable.Repeat(0, 10)));
    private int _index = 0;

    void Start()
    {
        this.UpdateAsObservable()
        .Where(_ => Input.GetKeyDown(KeyCode.A)|| 
                    Input.GetKeyDown(KeyCode.D)||
                    Input.GetKeyDown(KeyCode.W)||
                    Input.GetKeyDown(KeyCode.S))
        .Subscribe(_ =>
        {
            //入力によりIndexのシフトまたは値の変更
            if(Input.GetKeyDown(KeyCode.W))
            {
                _index = Mathf.Min(++_index, _rpIntList.Value.Count - 1);
            }
            if (Input.GetKeyDown(KeyCode.S))
            {
                _index = Mathf.Max(--_index, 0);
            }
            if (Input.GetKeyDown(KeyCode.A))
            {
                _rpIntList.Value[_index]++;
            }
            if (Input.GetKeyDown(KeyCode.D))
            {
                _rpIntList.Value[_index]--;
            }
            //Listの中の要素変更では通知されない ※List自体の操作は通知される
            //通知を強制発行
            _rpIntList.ForceNotify();
        })
        .AddTo(this);

        _rpIntList.Subscribe(value =>
        {
            Debug.Log("ChangeValue:" + value[_index] + " Index:" + _index);
        })
        .AddTo(this);
    }
}