🌟

UniRxでマウス操作を検出する

2023/09/24に公開

はじめに

Unityに置けるマウスクリック時の処理はエディタのEventTriggerにイベントハンドラを登録するのが一般的だと思いますが、コード側に処理を寄せたかったので、UniRxを使って実現します。現在は以下のようなコードを用いて実現しています。

マウスダウンの検出

以下のコードでマウスのボタンが押されたタイミングで通知します。通知する際に現在のマウスの位置を渡しています。渡されたマウスの位置を用いて、対象の座標を取得したり更新したりします。

using UniRx;
using UniRx.Triggers;

public class MouseEvents : MonoBehavior {
    // マウスボタンダウンの検出用Subject
    private Subject<Vector3> MouseDownSubject = new Subject<Vector3>();
    public IObservable<Vector3> MouseDownObservable => MouseDownSubject;

    // マウスドラッグの検出用Subject
    private Subject<Vector3> MouseDragSubject = new Subject<Vector3>();
    public IObservable<Vector3> MouseDragObservable => MouseDragSubject;

    // マウスボタンアップの検出用Subject
    private Subject<Vector3> MouseUpSubject = new Subject<Vector3>();
    public IObservable<Vector3> MouseUpObservable => MouseUpSubject;

    void Start()
    {
        // マウスボタンダウンの検出
        this.UpdateAsObservable()
            .Where(_ => Input.GetMouseButtonDown(0))
            .Select(_ => Input.mousePosition)
            .Subscribe(pos => MouseDownSubject.OnNext(pos))
            .AddTo(this);

        // マウスドラッグの検出
        this.UpdateAsObservable()
            .Where(_ => Input.GetMouseButton(0))
            .Select(_ => Input.mousePosition)
            .Subscribe(pos => MouseDragSubject.OnNext(pos))
            .AddTo(this);

        // マウスボタンアップの検出
        this.UpdateAsObservable()
            .Where(_ => Input.GetMouseButtonUp(0))
            .Select(_ => Input.mousePosition)
            .Subscribe(pos => MouseUpSubject.OnNext(pos))
            .AddTo(this);
            }
    }

呼び出し側のコード

通知を元に処理を実装する側は以下のようにしています。

    void Start() {
        // mouseDownEventはエディタからGameObjectを設定しておく
        MouseEvents mde = mouseDownEvent.GetComponent<MouseEvents>();
        mde.MouseUpObservable.Subscribe(pos => {
            // OnmouseUpCardで何らかの処理を実装する
            OnMouseUpCard(pos);
        });
        mde.MouseDragObservable.Subscribe(pos => {
            // OnMouseDragCardで何らかの処理を実装する
            OnMouseDragCard(pos);
        });
        mde.MouseDownObservable.Subscribe(pos => {
            // OnMouseDownCardで何らかの処理を実装する
            OnMouseDownCard(pos);
        });
    }
    

まとめ

カードゲーム等でカードをクリックしたり、ドラッグしたりする処理を実装する際に、イベントの発火からその後の処理までをコードに寄せたい場合、UniRxを使って実現することも可能です。他にもいい方法があれば教えてください。

Discussion