Unity で UI をドラッグ移動させる
※ これは 2020/10/30 時点の Unity 2020.1.11f1 の情報です
最新版では動作が異なる可能性がありますのでご注意ください
Blender の v2.90 の新機能の気になるものを確認できたので、Unity のお試しに戻り
今回は 新しい InputSystem を使って UI をマウスドラッグで移動できるようにしてみたい
新しい InputSystem は、Paclage Manager からインポートしたあと・・・
Player Settings の Active Input Handling
から選択できる(Unity Editor が再起動する)
InputSystem の切り替えが終わったら、こんな感じで Main Camera
、Event System
、UI
の GameObject
とドラッグ移動させる Item
の GameObject
を追加する
UI
は上記のように Canvas
と Canvas Scaler
と Graphic Raycaster
を追加した
Graphic Raycaster
がないとドラッグが無視されるの注意!
Item
は Draggable
というあとで記述する Script と、Event Trigger
、Canvas Group
、Image
を追加
Event Trigger
の部分はこんな感じで追加する
「Add New Event Type」ボタン押下後、追加するトリガーを選択する感じ
Draggable.cs
は下記のように記述
using UnityEngine; using UnityEngine.EventSystems; [RequireComponent(typeof(CanvasGroup))] public class Draggable : MonoBehaviour { private Transform root; private Transform self; private CanvasGroup canvasGroup = null; public void Awake() { this.self = this.transform; this.root = this.self.parent; this.canvasGroup = this.GetComponent<CanvasGroup>(); } public void OnBeginDrag(BaseEventData eventData) { // UI 機能を一時的無効化 this.canvasGroup.blocksRaycasts = false; } public void OnDrag(BaseEventData eventData) { this.self.localPosition = GetLocalPosition(((PointerEventData)eventData).position, this.transform); } private static Vector3 GetLocalPosition(Vector3 position, Transform transform) { // 画面上の座標 (Screen Point) を RectTransform 上のローカル座標に変換 RectTransformUtility.ScreenPointToLocalPointInRectangle( transform.parent.GetComponent<RectTransform>(), position, Camera.main, out var result); return new Vector3(result.x, result.y, 0); } public void OnEndDrag(BaseEventData eventData) { // UI 機能を復元 this.canvasGroup.blocksRaycasts = true; } }
重要なのは GetLocalPosition()
で、Event Trigger
から渡される座標を UI 用のローカル座標に変換するところ・・・transform.parent.GetComponent<RectTransform>()
のところを transform.GetComponent<RectTransform>()
にしてしまうとおかしくなる
これをやらないと思い通りの場所にならないので必須
さてお試し
するっとドラッグ移動できた
こういうコンポーネントは Unity 標準で用意しておいてほしい・・・入力座標の変換とかわかりにくすぎる