facebook twitter hatena line email

「Unity/UniRx/値変更検知」の版間の差分

提供: 初心者エンジニアの簡易メモ
移動: 案内検索
(ReactivePropertyを使った全体サンプル)
(例外として、配列内のデータを検知)
行88: 行88:
  
 
==例外として、配列内のデータを検知==
 
==例外として、配列内のデータを検知==
毎フレームごとにチェックするのでかなり危険。
 
 
<pre>
 
<pre>
 
using System.Collections;
 
using System.Collections;
行118: 行117:
 
         var sampleClient = new SampleClient();
 
         var sampleClient = new SampleClient();
 
         sampleClient.Request(id);
 
         sampleClient.Request(id);
 +
        sampleClient.ObserveEveryValueChanged(x => x.IsCompleteds)
 +
            .Subscribe(isCompleteds =>
 +
            {
 +
                // 配列の一部の値が変更が入ると処理される
 +
                Debug.Log("IsCompleteds.Count=" + isCompleteds.Count);
 +
                int cnt = isCompleteds.Count;
 +
                for (int tmpId = 0; tmpId < cnt; tmpId++)
 +
                {
 +
                    Debug.Log("Id=" + tmpId + " isCompleted=" + sampleClient.IsCompleteds[tmpId]);
 +
                    if (!sampleClient.IsCompleteds[tmpId]) return;
 +
                    Debug.Log("Id=" + tmpId + " sampleClient.Url=" + sampleClient.Urls[tmpId]);
 +
                }
 +
            })
 +
            .AddTo(gameObject);
 +
        /* ngパターンでボツ
 
         // 毎フレームごとに処理されるので危険かも。
 
         // 毎フレームごとに処理されるので危険かも。
 
         var observable = Observable.EveryUpdate()
 
         var observable = Observable.EveryUpdate()
行132: 行146:
 
             })
 
             })
 
             .AddTo(gameObject);
 
             .AddTo(gameObject);
 +
        */
 
     }
 
     }
 
}
 
}
 
</pre>
 
</pre>

2022年2月25日 (金) 01:37時点における版

値変更検知の方法

以下2つのやり方がある。

  • ReactiveProperty
  • ObserveEveryValueChanged

ObserveEveryValueChangedは、前フレームと今フレームの変化をフレームごとに、判断するので負荷が高いかも。あと、1フレーム内で発生した複数回の変動は検知できない。 ただ、ReactivePropertyはコードが、更新値に.valueをつけなくてはならないし、見た目が、わかりずらい。ObserveEveryValueChangedのほうが保守性が高いかも。

参考:https://qiita.com/toRisouP/items/d0d32cf674a00f3a8427

参考:https://nekogeek.jp/reactive-property-vs-observe-every-value-changed/

ObserveEveryValueChangedを使った値変更検知サンプル

IsCompletedが、trueになったときに、検知。

sampleClient.ObserveEveryValueChanged(x => x.IsCompleted)
            .Subscribe(isCompleted =>
            {
                // 値が変更が入ると処理される
                if (!isCompleted) return;
                Debug.Log("isCompleted=" + isCompleted);
                Debug.Log("sampleClient.Url=" + sampleClient.Url);
            })
            .AddTo(gameObject);

ObserveEveryValueChangedを使った全体サンプル

using UnityEngine;
using UniRx;
public class ChangeValueScene : MonoBehaviour
{
    class SampleClient
    {
        public bool IsCompleted = false;
        public string Url = "ttp://example.com";
        public void Request()
        {
            IsCompleted = true;
        }
    }
    void Start()
    {
        var sampleClient = new SampleClient();
        sampleClient.Request();
        sampleClient.ObserveEveryValueChanged(x => x.IsCompleted)
            .Subscribe(isCompleted =>
            {
                // 値が変更が入ると処理される
                if (!isCompleted) return;
                Debug.Log("isCompleted=" + isCompleted);
                Debug.Log("sampleClient.Url=" + sampleClient.Url);
            })
            .AddTo(gameObject);
    }
}

ReactivePropertyを使った全体サンプル

using UnityEngine;
using UniRx;
public class ReactivePropertyScene : MonoBehaviour
{
    class SampleClient
    {
        public ReactiveProperty<bool> IsCompleted = new ReactiveProperty<bool>(false);
        public void Request()
        {
            IsCompleted.Value = true;
        }
    }
    void Start()
    {
        var sampleClient = new SampleClient();
        sampleClient.Request();
        sampleClient.IsCompleted
            .Subscribe(value =>
            {
                if (!value) return;
                Debug.Log("Change IsCompleted : " + value);
            })
            .AddTo(gameObject);
    }
}

例外として、配列内のデータを検知

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UniRx;

public class ChangeValueListScene : MonoBehaviour
{
    class SampleClient
    {
        public List<string> Urls = new List<string>();
        public List<bool> IsCompleteds = new List<bool>();
        public SampleClient()
        {
            Urls.Add("ttp://example.com");
            Urls.Add("ttp://example2.com");
            IsCompleteds.Add(false);
            IsCompleteds.Add(false);
        }
        public void Request(int id)
        {
            IsCompleteds[id] = true;
        }
    }
    void Start()
    {
        int id = 0;
        var sampleClient = new SampleClient();
        sampleClient.Request(id);
        sampleClient.ObserveEveryValueChanged(x => x.IsCompleteds)
            .Subscribe(isCompleteds =>
            {
                // 配列の一部の値が変更が入ると処理される
                Debug.Log("IsCompleteds.Count=" + isCompleteds.Count);
                int cnt = isCompleteds.Count;
                for (int tmpId = 0; tmpId < cnt; tmpId++)
                {
                    Debug.Log("Id=" + tmpId + " isCompleted=" + sampleClient.IsCompleteds[tmpId]);
                    if (!sampleClient.IsCompleteds[tmpId]) return;
                    Debug.Log("Id=" + tmpId + " sampleClient.Url=" + sampleClient.Urls[tmpId]);
                }
            })
            .AddTo(gameObject);
        /* ngパターンでボツ
        // 毎フレームごとに処理されるので危険かも。
        var observable = Observable.EveryUpdate()
            .Subscribe(_ =>
            {
                Debug.Log("IsCompleteds.Count=" + sampleClient.IsCompleteds.Count);
                int cnt = sampleClient.IsCompleteds.Count;
                for (int tmpId = 0; tmpId < cnt; tmpId++)
                {
                    Debug.Log("Id=" + tmpId + " isCompleted=" + sampleClient.IsCompleteds[tmpId]);
                    if (!sampleClient.IsCompleteds[tmpId]) return;
                    Debug.Log("Id=" + tmpId + " sampleClient.Url=" + sampleClient.Urls[tmpId]);
                }
            })
            .AddTo(gameObject);
        */
    }
}