facebook twitter hatena line email

Unity/UniRx/複数イベント

提供: 初心者エンジニアの簡易メモ
移動: 案内検索

単純にトリガーをforeachで処理する場合

using UnityEngine;
using UniRx;
using UniRx.Triggers;
public class MultiAddComponentScene : MonoBehaviour
{
    void Start()
    {
        ObservableEventTriggers();
    }
    // 単純にトリガーをforeachで処理する場合
    public List<ObservableEventTrigger> observableEventTriggers;
    void ObservableEventTriggers()
    {
        foreach (var eventTrigger in observableEventTriggers) {
            eventTrigger
                .OnPointerEnterAsObservable()
                .Subscribe(pointerEventData => Debug.Log("PointerEnter " + pointerEventData.position)) // 触れた時 PointerExit (666.0, 1013.0)
                .AddTo(gameObject);
        }
    }
}
  1. オブジェクトを複数(とりあえず2つ)用意して、ObservableEventTriggerをAddComponentしておく。
  2. observableEventTriggersにトリガーとなるオブジェクトを、Inspectorから、ドラッグする

1つのObservableに複数イベントを統合して処理する場合

単純にトリガーをforeachで処理する場合

using UnityEngine;
using UniRx;
using UniRx.Triggers;
public class MultiAddComponentScene : MonoBehaviour
{
    void Start()
    {
        ObservableEventTriggers();
    }
    // 単純にトリガーをforeachで処理する場合
    public List<ObservableEventTrigger> observableEventTriggers;
    void ObservableEventTriggers()
    {
        foreach (var eventTrigger in observableEventTriggers) {
            eventTrigger
                .OnPointerEnterAsObservable()
                .Subscribe(pointerEventData => Debug.Log("PointerEnter " + pointerEventData.position)) // 触れた時 PointerExit (666.0, 1013.0)
                .AddTo(gameObject);
        }
    }
}
  1. オブジェクトを複数(とりあえず2つ)用意して、ObservableEventTriggerをAddComponentしておく。
  2. observableEventTriggersにトリガーとなるオブジェクトを、Inspectorから、ドラッグする

1つのObservableに複数イベントを統合して処理する場合

Unitを使い、引数を使わない場合

using UnityEngine;
using UniRx;
using UniRx.Triggers;
using System;
using UnityEngine.EventSystems;
public class MultiAddComponentScene : MonoBehaviour
{
    void Start()
    {
        OneObservableTriggers();
    }
    // 1つのObservableに複数イベントを統合して処理する場合
    public List<EventTrigger> eventTriggers;
    void OneObservableTriggers()
    {
        IObservable<Unit> triggerOnPointerEnterAsObservable;
        triggerOnPointerEnterAsObservable = Observable.Create<Unit>(observer =>
        {
            Debug.Log("eventTriggers.Count=" + eventTriggers.Count);
            foreach (var trigger in eventTriggers)
            {
                if (trigger == null) {
                    Debug.Log("trigger is null");
                }
                var pointerEnter = new EventTrigger.Entry
                {
                    eventID = EventTriggerType.PointerEnter
                };
                pointerEnter.callback.AddListener(data =>
                {
                    observer.OnNext(Unit.Default);
                });
                trigger.triggers.Add(pointerEnter);
            }
            return Disposable.Empty;
        });
        triggerOnPointerEnterAsObservable
            .Subscribe(pointerEventData => Debug.Log("PointerEnter"))
            .AddTo(gameObject);
    }
}
  1. オブジェクトを複数(とりあえず2つ)用意して、EventTriggerをAddComponentしておく。
  2. eventTriggersにトリガーとなるオブジェクトを、Inspectorから、ドラッグする

参考:https://www.hanachiru-blog.com/entry/2018/09/21/151426

PointerEventDataを引数として渡す場合

using UnityEngine;
using UniRx;
using UniRx.Triggers;
using System;
using UnityEngine.Eventsystems;
public class MultiAddComponentScene : MonoBehaviour
{
    void Start()
    {
        OnePointerEventDataObservableTriggers();
    }
    // 1つのObservableに複数イベントを統合して処理し、PointerEventDataを引数として渡す場合
    public List<EventTrigger> eventTriggers;
    void OnePointerEventDataObservableTriggers()
    {
        IObservable<PointerEventData> triggerOnPointerEnterAsObservable;
        triggerOnPointerEnterAsObservable = Observable.Create<PointerEventData>(observer =>
        {
            foreach (var trigger in eventTriggers)
            {
                var pointerEnter = new EventTrigger.Entry
                {
                    eventID = EventTriggerType.PointerEnter
                };
                pointerEnter.callback.AddListener(data =>
                {
                    observer.OnNext((PointerEventData)data);
                });
                trigger.triggers.Add(pointerEnter);
            }
            return Disposable.Empty;
        });
        triggerOnPointerEnterAsObservable
            .Subscribe(pointerEventData => Debug.Log("PointerEnter " + pointerEventData.position))
            .AddTo(gameObject);
    }
}

参考:https://docs.unity3d.com/ja/2018.4/ScriptReference/Eventsystems.EventTrigger.html

GameObjectを引数として渡す場合

public class MultiAddComponentScene : MonoBehaviour
{
    void Start()
    {
        OneGameObjectObservableTriggers();
    }
    public List<EventTrigger> eventTriggers;
    // 1つのObservableに複数イベントを統合して処理し、GameObjectを引数として渡す場合
    void OneGameObjectObservableTriggers()
    {
        IObservable<GameObject> triggerOnPointerEnterAsObservable;
        triggerOnPointerEnterAsObservable = Observable.Create<GameObject>(observer =>
        {
            foreach (var trigger in eventTriggers)
            {
                var pointerEnter = new EventTrigger.Entry
                {
                    eventID = EventTriggerType.PointerEnter
                };
                pointerEnter.callback.AddListener(data =>
                {
                    observer.OnNext(trigger.gameObject);
                });
                trigger.triggers.Add(pointerEnter);
            }
            return Disposable.Empty;
        });
        triggerOnPointerEnterAsObservable
            .Subscribe(obj => Debug.Log("PointerEnter " + obj.name))
            .AddTo(gameObject);
    }
}

PointerEventDataを引数として渡す場合

using UnityEngine;
using UniRx;
using UniRx.Triggers;
using System;
using UnityEngine.Multiystems;
public class MultiAddComponentScene : MonoBehaviour
{
    void Start()
    {
        OnePointerEventDataObservableTriggers();
    }
    // 1つのObservableに複数イベントを統合して処理し、PointerEventDataを引数として渡す場合
    public List<EventTrigger> eventTriggers;
    void OnePointerEventDataObservableTriggers()
    {
        IObservable<PointerEventData> triggerOnPointerEnterAsObservable;
        triggerOnPointerEnterAsObservable = Observable.Create<PointerEventData>(observer =>
        {
            foreach (var trigger in eventTriggers)
            {
                var pointerEnter = new EventTrigger.Entry
                {
                    eventID = EventTriggerType.PointerEnter
                };
                pointerEnter.callback.AddListener(data =>
                {
                    observer.OnNext((PointerEventData)data);
                });
                trigger.triggers.Add(pointerEnter);
            }
            return Disposable.Empty;
        });
        triggerOnPointerEnterAsObservable
            .Subscribe(pointerEventData => Debug.Log("PointerEnter " + pointerEventData.position))
            .AddTo(gameObject);
    }
}

参考:https://docs.unity3d.com/ja/2018.4/ScriptReference/Multiystems.EventTrigger.html

GameObjectを引数として渡す場合

public class MultiAddComponentScene : MonoBehaviour
{
    void Start()
    {
        OneGameObjectObservableTriggers();
    }
    public List<EventTrigger> eventTriggers;
    // 1つのObservableに複数イベントを統合して処理し、GameObjectを引数として渡す場合
    void OneGameObjectObservableTriggers()
    {
        IObservable<GameObject> triggerOnPointerEnterAsObservable;
        triggerOnPointerEnterAsObservable = Observable.Create<GameObject>(observer =>
        {
            foreach (var trigger in eventTriggers)
            {
                var pointerEnter = new EventTrigger.Entry
                {
                    eventID = EventTriggerType.PointerEnter
                };
                pointerEnter.callback.AddListener(data =>
                {
                    observer.OnNext(trigger.gameObject);
                });
                trigger.triggers.Add(pointerEnter);
            }
            return Disposable.Empty;
        });
        triggerOnPointerEnterAsObservable
            .Subscribe(obj => Debug.Log("PointerEnter " + obj.name))
            .AddTo(gameObject);
    }
}

ボタンで行う場合(引数button)

public class MultiAddComponentScene : MonoBehaviour
{
    void Start()
    {
        OneClickObservableButtons();
    }
    // 1つのObservableに複数イベントを統合して処理し、Buttonを引数として渡す場合
    public List<Button> buttons;
    void OneClickObservableButtons()
    {
        IObservable<Button> onClickAsObservable;
        onClickAsObservable = Observable.Create<Button>(observer =>
        {
            foreach (var button in buttons)
            {
                button.onClick.AddListener(() =>
                {
                    observer.OnNext(button);
                });
            }
            return Disposable.Empty;
        });
        onClickAsObservable
            .Subscribe(button => Debug.Log("click " + button.name))
            .AddTo(gameObject);
    }
}
  1. ボタンオブジェクトを、Inspectorから、buttonsへドラッグする

ボタンで行う場合(引数id)

public class MultiAddComponentScene : MonoBehaviour
{
    void Start()
    {
        OneClickObservableButtons();
    }
    // 1つのObservableに複数イベントを統合して処理し、intを引数として渡す場合
    public List<int> buttons;
    void OneClickObservableButtons()
    {
        IObservable<int> onClickAsObservable;
        onClickAsObservable = Observable.Create<int>(observer =>
        {
            int i = 0;
            foreach (var button in buttons)
            {
                int id = i;
                button.onClick.AddListener(() =>
                {
                    observer.OnNext(id);
                });
                i++;
            }
            return Disposable.Empty;
        });
        onClickAsObservable
            .Subscribe(id => Debug.Log("click " + id))
            .AddTo(gameObject);
    }
}
  1. ボタンオブジェクトを、Inspectorから、buttonsへドラッグする

Toggleで行う場合

public class MultiAddComponentScene : MonoBehaviour
{
    void Start()
    {
        OneClickObservableToggles();
    }
    // 1つのObservableに複数イベントを統合して処理し、Toggleを引数として渡す場合
    public List<Toggle> toggles;
    void OneClickObservableToggles()
    {
        IObservable<Toggle> onValueChangedAsObservable;
        onValueChangedAsObservable = Observable.Create<Toggle>(observer =>
        {
            foreach (var toggle in toggles)
            {
                toggle.onValueChanged.AddListener(data =>
                {
                    observer.OnNext(toggle);
                });
            }
            return Disposable.Empty;
        });
        onValueChangedAsObservable
            .Subscribe(toggle => Debug.Log("change " + toggle.name))
            .AddTo(gameObject);
    }
}

Toggleでboolを返す場合

public class MultiAddComponentScene : MonoBehaviour
{
    void Start()
    {
        OneClickObservableToggles();
    }
    // 1つのObservableに複数イベントを統合して処理し、Toggleを引数として渡す場合
    public List<Toggle> toggles;
    void OneClickObservableToggles()
    {
        IObservable<bool> onValueChangedAsObservable;
        onValueChangedAsObservable = Observable.Create<bool>(observer =>
        {
            foreach (var toggle in toggles)
            {
                toggle.onValueChanged.AddListener(data =>
                {
                    observer.OnNext(toggle.isOn);
                });
            }
            return Disposable.Empty;
        });
        onValueChangedAsObservable
            .Subscribe(flag => Debug.Log("change " + flag))
            .AddTo(gameObject);
    }
}

複数GameObjectでUpdate()を一つのオブザーバーで処理する場合

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

public class MultiObjectScene : MonoBehaviour
{
    void Start()
    {
        GameObjectObservable();
    }
    [SerializeField] List<EventTrigger> eventTriggers;
    void GameObjectObservable()
    {
        IObservable<GameObject> triggerOnUpdateAsObservable;
        triggerOnUpdateAsObservable = Observable.Create<GameObject>(observer =>
        {
            foreach (var trigger in eventTriggers)
            {
                trigger.UpdateAsObservable()
                    .Subscribe(_ => observer.OnNext(trigger.gameObject));
                    .AddTo(gameObject);
            }
            return Disposable.Empty;
        });
        triggerOnUpdateAsObservable
            .Subscribe(obj =>
            {
                Debug.Log("update " + obj.name);
                obj.transform.localPosition = new Vector3(
                    obj.transform.localPosition.x,
                    obj.transform.localPosition.y + UnityEngine.Random.Range(-5f, 5f),
                    obj.transform.localPosition.z);
            })
            .AddTo(gameObject);
    }
}