LoginSignup
12
14

More than 5 years have passed since last update.

UnityのuGUIとUniRxでドラッグアンドドロップ

Last updated at Posted at 2017-01-21

UnityのuGUIとUniRxを使ってドラッグアンドドロップを実装してみました。

Sampleコード

DragAndDrop.cs
using UnityEngine;
using UniRx;
using UniRx.Triggers;
using System.Linq;


public class DragAndDrop : MonoBehaviour {
    void Start () {
        // 親CanvasのRectTransformを基準に利用する
        var rectTransform = transform.root.gameObject.GetComponent<RectTransform>();

        // RectTransformUtility.ScreenPointToLocalPointInRectangle用使い捨て変数
        var tmpPosition = Vector2.zero;

        // ObservableEventTriggerをオブジェクトに追加
        ObservableEventTrigger trigger = gameObject.AddComponent<ObservableEventTrigger>();

        // Dragイベントの登録
        trigger.OnDragAsObservable()
               // 発生するたびにマウスポジションを取得する。 
               .Select(_ => Input.mousePosition)
               // ただしInput.mousePositionはWorld座標なのでそのままでは使えない。親CanvasのUI座標に変換する。
               .Select(mousePosition => {
                   // ※注: 親CanvasのRender ModeをScreen Space Cameraにしている場合はこれでよいが、Screen Space Overlayの場合はまた別の記述になる。
                   //   http://tsubakit1.hateblo.jp/entry/2016/03/01/020510 を参照。
                   RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, mousePosition, Camera.main, out tmpPosition);
                   return tmpPosition;
               })
               // ついでにログを取ってみる
               .Do(position => Debug.Log(string.Format("[Drag]Input.mousePosition.x: {0}, Input.mousePosition.y: {1}, Canvas.LocalPosition.x: {2}, Canvas.LocalPosition.y: {3}",
                                                       Input.mousePosition.x, Input.mousePosition.y, position.x, position.y)))
               // 自分の位置をマウスのUI座標に。 
               .Subscribe(position => transform.localPosition = position)
               // 自分が破壊されたらイベントも終了。
               .AddTo(this);

        // Drag終了イベント(つまりDrop)の登録
        trigger.OnEndDragAsObservable()
               // 発生したらマウスポジションを取得する。 
               .Select(_ => Input.mousePosition)
               .Select(mousePosition => {
                   RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, mousePosition, Camera.main, out tmpPosition);
                   return tmpPosition;
               })
               // ドロップされたらログを追加
               .Subscribe(position => Debug.Log(string.Format("[Drop]Input.mousePosition.x: {0}, Input.mousePosition.y: {1}, Canvas.LocalPosition.x: {2}, Canvas.LocalPosition.y: {3}",
                                                Input.mousePosition.x, Input.mousePosition.y, position.x, position.y)))
               // 自分が破壊されたらイベントも終了。
               .AddTo(this);

    }
}

利用方法

  1. 親となるCanvasを用意し、Render Modeを"Screen Space - Camera"に設定します。
  2. ドラッグ&ドロップしたいUI系のgameObjectをCanvasの子オブジェクトに設定します。
  3. 上記のスクリプトをアタッチします。
  4. 起動して心行くまでグリグリします。

※ Render Modeの場所
image.png

ドラッグ&ドロップが驚くほど簡単に実装できます。UniRx素晴らしすぎますね。

12
14
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
14