imog

主にUnityとかの事を書いています

UniRX使ってOnRaycast的な処理を書く

小ネタ

OnTriggerEnterとかそういう感じで、レイにぶつかった瞬間、ぶつかっている間、レイから離れた瞬間を検知したいなという気持ち。

一案としてこのような感じ

using UnityEngine;
using System.Collections;
using UniRx;
using UniRx.Triggers;
using System.Linq;

public class OnRaycastHit : MonoBehaviour
{
    Subject<Unit> onRaycastStayStream = new Subject<Unit> ();

    public IObservable<Unit> onRaycastStayAsObservable { get { return onRaycastStayStream.AsObservable (); } }

    Subject<Unit> onRaycastExitStream = new Subject<Unit> ();

    public IObservable<Unit> onRaycastExitAsObservable { get { return onRaycastExitStream.AsObservable (); } }

    Subject<Unit> onRaycastEnterStream = new Subject<Unit> ();

    public IObservable<Unit> onRaycastEnterAsObservable { get { return onRaycastEnterStream.AsObservable (); } }

    private bool isOnNext;

    public void RaycastHit ()
    {
        isOnNext = true;
    }

    void Start ()
    {
        this.UpdateAsObservable ().
            Select (_ => isOnNext).
            Buffer (2, 1).
            Subscribe (list => {
                bool before = list.First ();
                bool current = list.Last ();
                if (!current && before) onRaycastExitStream.OnNext (default(Unit));
                if (current && !before) onRaycastEnterStream.OnNext (default(Unit));
                if (current) onRaycastStayStream.OnNext (default(Unit));
                isOnNext = false;
            });
    }
}

Raycastで引っかかった時に RaycastHit を呼ぶイメージ。 そのフレームだけisOnNextがtrueになり、Buffer(2,1)で前フレームとの値と比較してOnNextの対象を変える。

isOnNextが結構強引な気がしていて、まだ良い方法あるんじゃないかと考えてる