質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

3回答

1422閲覧

Unityでドラッグ移動が可能なUIパネルを作りたいです。

Picasso

総合スコア11

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2017/08/01 02:35

編集2017/08/01 02:52

###実現したいこと
UIのパネルを使って、ステータス表示ウィンドウ的なものを作ろうとしています。

パネルをドラッグで自由に移動させたいのですが、方法が思いつきません。

###発生している問題

同じスクリプトをアタッチしている複数のパネルが、ドラッグで同時に動いてしまいます。

###該当のソースコード

C#

1 2using System.Collections; 3using System.Collections.Generic; 4using UnityEngine; 5using UnityEngine.EventSystems; 6 7public class PanelDragCtrl : MonoBehaviour{ 8 Vector3 mousePos; 9 Vector3 clickPos; 10 Vector3 offSet; 11 12 bool dragMode = false; 13 14 void Start () { 15 } 16 17 void Update () { 18 19 // UIの上にカーソルがある時だけ実行 20 if (EventSystem.current.IsPointerOverGameObject() == false) 21 { 22 return; 23 } 24 25 26 if (Input.GetMouseButtonDown(0)) //クリック開始時に 27 { 28 clickPos = Input.mousePosition; //ドラッグ開始位置を取得して、 29 offSet = transform.position - clickPos; //UIの中心とドラッグ開始位置のズレを取得 30 31 dragMode = true; //ドラッグ処理を開始 32 } 33 else if (Input.GetMouseButtonUp(0)) //クリック終了時に 34 { 35 dragMode = false; //ドラッグ処理を終了 36 } 37 38 39 if (dragMode) 40 PanelDrag(); 41 } 42 43 44 void PanelDrag() 45 { 46 mousePos = Input.mousePosition; //ドラッグ中のカーソル位置 47 48 transform.position = mousePos + offSet; //UIをドラッグさせる 49 } 50}

上記のスクリプトを、UIのパネルにアタッチしていました。
ですが、このままだと、同じスクリプトをアタッチしているパネルが同時に動いてしまいます。

###試したこと
まずパネル自体にスクリプトをアタッチするのを止めました。

そして、
『どのパネルをドラッグしているかを認識するために、Rayを飛ばして、RaycastHitを取得。

そして、取得したRaycastHitの座標を移動させる』みたいなスクリプトを書こうとしました。
(書いたスクリプトはメインカメラにアタッチ)

……ですが、RayがUIパネルに当たらないっぽいんです……。

###補足情報
Unityのバージョンは、5.6.1f1です。
プログラムは、つい最近始めたばかりの素人です。よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

簡単に調べてみたところ、EventSystem.current.IsPointerOverGameObject()はEventSystemオブジェクト上にあるかどうかをチェックするものだと書かれていました。
https://docs.unity3d.com/ja/540/ScriptReference/EventSystems.EventSystem.IsPointerOverGameObject.html
なので、パネルが同時に動いてしまう点については、EventSystem.current.IsPointerOverGameObject()によって、すべてのパネルが反応して動いてしまっていることが原因だと思われます。

また、RayがUIパネルに当たらないとのことですが、通常のRaycastHitではなく、EventSystem.current.RaycastAll()を使えば、反応しました。
こちらを参考に書いてみたところ、こうなりました。
このスクリプトでは、パネル上にポインタがあるだけで反応してしまいますが、これをドラッグ時のみに反応するようにすれば大丈夫でしょう。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.EventSystems; 5 6public class UGuiRaycast : MonoBehaviour 7{ 8 void Update() 9 { 10 PointerEventData pointer = new PointerEventData(EventSystem.current); 11 pointer.position = Input.mousePosition; 12 List<RaycastResult> result = new List<RaycastResult>(); 13 EventSystem.current.RaycastAll(pointer, result); 14 15 foreach (RaycastResult raycastResult in result) 16 { 17 // 反応したパネルの名前を表示 18 Debug.Log(raycastResult.gameObject.name); 19 } 20 } 21}

補足ですが、このUnityのデフォルトのGUIは「uGUI」と呼ばれております。
Googleで「uGUI ドラッグ」と検索すれば、いくつか実装例が見つかるので、一度確認してみるとよいと思います。

投稿2017/08/01 04:37

fiveHundred

総合スコア9796

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

IPointerUpHandler、IPointerDragHandler、IPointerDownHanderあたりを継承して、そちらに処理を書くと楽です。
手抜きで作ると↓みたいな感じ

C#

1using UnityEngine; 2using System.Collections; 3using UnityEngine.UI; 4using UnityEngine.EventSystems; 5 6public class ExampleClass : MonoBehaviour, IPointerDownHandler, IPointerDragHandler 7{ 8 void OnPointerDrag(PointerEventData ev) 9 { 10 this.GetComponent<RectTransform>().anchoredPosition += ev.delta; 11 } 12}

投稿2017/08/02 02:40

ShiroKuroShiro

総合スコア134

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

私も初心者なので、見当違いでしたらごめんなさい。
とりあえず、複数のパネルを個別にドラッグさせたいなら、こんな方法はどうでしょうか。

c#

1 public void OnDrag () 2 { 3 //マウスの座標を取得 4 Vector3 mousePos = Camera.main.ScreenToWorldPoint (Input.mousePosition); 5 //取得したマウスのz座標をゲームオブジェクトに合わせる(Z座標を固定する) 6 mousePos.z = gameObject.transform.position.z; 7 //ゲームオブジェクトのワールド座標をマウスのワールド座標に合わせる 8 gameObject.transform.position = mousePos; 9 }

上記のコードを、Event TriggerのDragにアタッチ。
これで、複数のパネルに同じスクリプトをアタッチしても個別でドラッグできると思います。

UIの上にカーソルがある時だけ実行

当たり判定でhitしていたらOnDrag()を実行するとか、どうでしょう?

投稿2017/08/01 05:03

nico29

総合スコア76

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問