UniRx + MessagePipe で、マウス操作をメッセージ化する
13381 ワード
解説
マウス操作をメッセージ化
IPublisher <- マウスクリック時にMouseEventを通知 ※マウスクリックについては省略しています
IPublisher <- マウスドラッグ中にDragEventを通知-
ドラッグ中の間、UpdateAsObservable から Drag 先の座標をIPublisher へ流す
// ドラッグ中マウス座標をストリームし続ける mouseDrag = this.UpdateAsObservable () .SkipUntil (mouseDown) .TakeUntil (mouseUp) .Repeat () .Select (_ => { return GetMouseEvent (); }); // 購読して通知させる // .AddTo(this) をしない理由は後述 dragDisposable = mouseDrag.Subscribe (d => { drag.Publish (new DragEvent { position = d.position, time = d.time }); });
AddTo() をしない理由について
Repeatをしているため、依存しているObservableが存在していることが影響しています。
AddTo(this) してもいいんですが、破棄される際に関係するObservable を確認できず 必ずエラーを起こします。
そのため明示的に OnDestroy() で事前に破棄させる手順を踏んでいます。
今回は同一のオブジェクト内で完結しているのでわかりやすいのですが、Repeatを持ったObservableを公開する場合注意が必要です。
ソース
public class MouseEventManager : MonoBehaviour {
[Inject] private IPublisher<MouseEvent> mouse { get; set; }
[Inject] private IPublisher<DragEvent> drag { get; set; }
private IObservable<MouseEvent> mouseDown { get; set; }
private IObservable<MouseEvent> mouseUp { get; set; }
private IObservable<MouseEvent> mouseDrag { get; set; }
private Camera mainCamera;
private IDisposable dragDisposable;
private void Start () {
mainCamera = Camera.main;
// Stream の作成
mouseDown = this.UpdateAsObservable ()
.Where (_ => Input.GetMouseButtonDown (0))
.Select (_ => { return GetMouseEvent (); });
mouseUp = this.UpdateAsObservable ()
.Where (_ => Input.GetMouseButtonUp (0))
.Select (_ => { return GetMouseEvent (); });
// ドラッグ中マウス座標をストリームし続ける
mouseDrag = this.UpdateAsObservable ()
.SkipUntil (mouseDown)
.TakeUntil (mouseUp)
.Repeat ()
.Select (_ => { return GetMouseEvent (); });
// SubScribe
mouseDown.Subscribe (_ => {
mouse.Publish (GetMouseEvent ());
}).AddTo (this);
dragDisposable = mouseDrag.Subscribe (d => {
drag.Publish (new DragEvent {
position = d.position, time = d.time
});
});
}
private MouseEvent GetMouseEvent () {
var p = new Vector3 (
Input.mousePosition.x,
Input.mousePosition.y,
12
);
return new MouseEvent {
position = mainCamera.ScreenToWorldPoint (p), time = Time.time
};
}
private void OnDestroy () {
dragDisposable?.Dispose ();
}
}
public class MouseEvent : IMouseEvent {
public Vector3 position { get; set; }
public float time { get; set; }
}
// MonoBehavior に取り付けて LifetimeScope へ登録するだけでマウスドラッグ先にくっつく
public class Player : MonoBehaviour {
[Inject] private ISubscriber<DragEvent> drag { get; set; }
void Start () {
drag.Subscribe (d => {
this.transform.position = d.position;
});
}
}
記事について
ソースに関しては、抜粋のため動作しない可能性があります。
コメント、補足大歓迎です。
次回、フリック入力をメッセージ化するに続きます。
少し予告と違いますが、更新しました
参考にさせていただいた記事
Author And Source
この問題について(UniRx + MessagePipe で、マウス操作をメッセージ化する), 我々は、より多くの情報をここで見つけました https://qiita.com/nobu-tri/items/4715020abfdfdb186ac5著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .