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

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

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

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

Q&A

解決済

1回答

6307閲覧

UIをドラッグする方法について。

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

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

1グッド

1クリップ

投稿2018/02/08 14:59

前提・実現したいこと

UIのドラッグを実装する方法は何が最適でしょうか?
また、Event SystemとEvent Triggerはそれぞれ別の実装方法なのでしょうか?

試したこと

Event Systemに関しては、このようなサイトを見つけました。

C#

1using UnityEngine.EventSystems; 2public class TestDrag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler 3{

このように、using UnityEngine.EventSystems;を宣言して、IBeginDragHandler, IDragHandler, IEndDragHandler
を継承しなければならないと認識しています。

Event Triggerに関しては、このようなサイトを見つけました。
このサイトを見る限り、特にusing宣言や継承するクラスはなさそうなのですが、
Event Triggerに関して、別のサイトを見てみると、
using UnityEngine.EventSystems;を宣言して、EventTriggerクラスを継承しています。

いろいろやり方があって、差異は何なのか?(それとも旧式と新方式の違いなのか?)、メリット、デメリット等あるのか、
わからない状態です。

わからないことをまとめると、

・そもそもEvent SystemとEvent Triggerは別の実装法かどうか? ・Event Triggerで実装する場合、EventTriggerクラスを継承しなきゃいけないのかどうか? ・UIのドラッグの最適(簡単)な実装はどれか? ・Event SystemとEvent Triggerを比較した場合、それぞれのメリット、デメリットは何なのか?

等です。
ご教授のほどお願いします。

capra314cabra👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

機能説明

Event System
ユーザーの入力を監視しイベントを伝える役割を果たします。

Event Trigger
Inspector上からアタッチできるコンポーネントです。Event Systemの様々なイベントを受け取る受信機の役割を果たします。Hierarchy上から手動でイベントをアタッチする他にスクリプト上からEvent Triggerを参照し実装することもできます。

IxxxxHandler
クリックやドラッグなど様々なインターフェイスが存在します。スクリプトから実装することで動作します。この場合Event Triggerは必要ありません。

Event Systemのイベントを受け取る為の条件

[送信側]
・Hierarchy上にEvent Systemがある。
・uGUI以外で使いたい場合はPhysics Raycasterをカメラにアタッチする。2Dと3Dがあるので注意

[受信側]
・uGUIの場合、Raycast TargetがオンになったuGUIオブジェクト(Image、Textなど)
・uGUI以外の場合、Clliderがアタッチされている。

Event Trigger、IxxxxHandlerの選び方

スクリプトで書きたい派の方はIxxxxHandlerを。Inspector上から手動でアタッチしたい派の方はEvent Triggerをアタッチし該当スクリプトをアタッチすると良いと思います。それ以外に、ひとつのオブジェクトに対してイベントを動的に切り替えたい時などはEvent Triggerをアタッチし、スクリプトで切り替えるといいと思います。

IxxxxHandlerをuGUIのImageに対して実装するサンプル

Imageをドラッグする最小コードです。下記のコードをAssets以下に保存してuGUIのImageにアタッチすることで動作します。

C#

1using UnityEngine; 2using UnityEngine.UI; 3using UnityEngine.EventSystems; 4 5[RequireComponent(typeof(Image))] 6public class DraggableImg : MonoBehaviour, IDragHandler 7{ 8 RectTransform Tr; 9 10 void Awake() 11 { 12 Tr = GetComponent<RectTransform>(); 13 } 14 15 public void OnDrag(PointerEventData eventData) 16 { 17 Move(eventData.position); 18 } 19 20 void Move(Vector3 pos) 21 { 22 Tr.position = pos; 23 } 24}

知っておくと便利なこと

Event SystemのDrag Threshold
どのタイミングからドラッグがスタートするかを決めることができます。ドラッグに対しての感度みたいなものです。数値が低いほど感度が高くなります。例えば、1つのボタンがクリックできる克つ移動できるとします。感度が高いほどドラッグとして見なされやすくなるので、ユーザーが少しもドラッグせずクリックしなければクリックイベントが発火しないなどの設定ができます。

オブジェクトの重なり順
Event Systemは重なり順を考慮してくれます。例えばuGUIのButtonより前にImageがある場合、Buttonにイベントが伝達されず反応しなくなります。これをうまく利用するとユーザーの動作をコントロールしやすくなります。

動くuGUI要素は結構な負荷に
Event Systemとは関係ないですが、uGUIのすべての要素は画面に対して相対的に配置されます。Imageなどを動かす場合すべての要素が再計算されるので結構な負荷になります。対策としてはCanvasをもう一つ用意しそこで動かす方法や、動くものはuGUIを使わないという選択肢もあります。内容にもよりますが重くて動きが悪い場合はご検討ください。

Unity上で使う座標の扱いを覚える
uGUIを扱う上で座標の種類を知っておくと便利です。

【Unity】【uGUI】Screenの座標とWorld(3D)座標の変換について
http://tsubakit1.hateblo.jp/entry/2016/03/01/020510

投稿2018/02/13 06:49

編集2019/03/16 14:27
IShix

総合スコア1724

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

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

退会済みユーザー

退会済みユーザー

2019/03/16 07:33

ご回答ありがとうございます。 返信が遅くなり、大変申し訳ありません。 当時、一度はご回答を確認したのですが、わからないことが多過ぎて、返信で何と質問すればよいかわからず、考えているうちに多忙になってしまい、こちらの質問を忘れていました。 ご丁寧にご回答いただいたにも関わらず、忘れてしまい、大変申し訳ございません。 すみませんでした。申し訳ないです。 そして現在、当時より知識が増えて、IShikawan様のご回答がある程度理解できるようになりました。 今更ながらで大変恐縮なのですが、ご回答に関して分からない点を質問させていただきたいです。 1点目。 Event Systemを使ったイベントの受取方法としては、下記の2パターンがあるという認識で合っていますか? ・Event SystemとEvent Triggerを使った方法(uGUI以外の場合は、Physics Raycasterも必要)。 Event Triggerはコンポーネントでアタッチできたり、スクリプトで参照して実装することもできる。 ・Event SystemとをIxxxxHandlerを使った方法(uGUI以外の場合、Physics Raycasterも必要)。  IxxxxHandlerはスクリプトで実装する。 2点目。 1点目と関係しますが、受信側を正確に書くとすれば、下記のようなことですか? [受信側] ・uGUIの場合、Imageがアタッチされている。 ・uGUI以外の場合、Clliderがアタッチされている。 ・Event TriggerかIxxxxHandlerのどちらかで受け取りを実装している。 本当に遅くなり申し訳ございませんが、宜しくお願い致します。
IShix

2019/03/16 09:40

ご連絡ありがとうございます。 >1点目 あってます。 強いて言うならPhysics RaycasterはuGUI用もあります。CanvasにアタッチされているGraphic Raycasterです。Canvasを生成すると自動的にアタッチされるのであまり意識する必要はありません。 >2点目 あってます。Clliderは正確にはColliderですね。誤字すみません。 2D、3Dがあるのでご注意ください。 強いて言えばUnityEngine.UI.ButtonもInspectorからアタッチしたりスクリプトで記述したりできるUnityEventです。 例) Btn.onClick.AddListener(ClickBtn); 以上です。
退会済みユーザー

退会済みユーザー

2019/03/16 13:08

ご回答ありがとうございます。 だいぶ遅くなってしまった返信にも関わらず、ご回答いただき誠にありがとうございます。 なるほど、uGUIにはCanvasにRaycasterがデフォルトでアタッチされていたのですね。 確認致しました。 また、UnityEngine.UI.Buttonも検証しました。 そして、UnityEngine.UI.Buttonを検証した時に気づいたのですが、 受信側のuGUIの場合、条件として、 「Imageがアタッチされている」というよりも、「ImageやText等の[Raycast Target]のtrue, falseが設定できるUIコンポーネントがアタッチされている」であればよさそうと思いました。 実際、Textコンポーネントに[Raycast Target]の項目があり、検証した所、受信できているような挙動をしたのですが、いかがでしょうか? あと、当時より知識が増えて、オブジェクトのクリックやドラッグ処理を実装する方法として、 Event Systemを使う方法以外に、MonoBehaviourクラスのOnMouseDownやOnMouseDragでも実装できることがわかりました。自分が知る限りでは、このEvent Systemを使う方法とMonoBehaviourクラスを使う方法の2つなのですが、もし他にも何か方法がご存知でしたら、教えていただけませんか?
IShix

2019/03/16 14:03

> 「ImageやText等の[Raycast Target]のtrue, falseが設定できるUIコンポーネントがアタッチされている」 おっしゃる通りです。失念しておりました。Androidの一部端末では、挙動がおかしくなることがあるのでButtonに重なるTextなどのRaycast Targetを外すよう習慣付けております。若干パフォーマンスも良くなるのでクリック処理などが必要ないものは外すことをおすすめします。 > MonoBehaviourクラスのOnMouseDownやOnMouseDragでも実装できることがわかりました。 こちらはuGUIが出る前のGUIで使われていたメソッドです。GUIエレメントやColliderに反応します。 EventSystemとは関係ありません。今後使う必要がないので忘れても良いと思います。
IShix

2019/03/16 14:29 編集

> 他にも何か方法がご存知でしたら、教えていただけませんか? もうひとつはUpdate内でInput情報を取得してRayを飛ばしオブジェクトを取得し判別する方法です。 RayはColliderに反応します。この方法はドラッグ処理で今でも使います。 https://arma-search.jp/article/unity-raycast ※この方法はEvent Systemと関係ありません。
退会済みユーザー

退会済みユーザー

2019/03/16 15:01

ご回答ありがとうございます。 なるほど、Androidではそういった対策をしたほうがよいのですね。 MonoBehaviourクラスのOnMouseDownメソッド等は旧式で非推奨だったのですね。 知らずに使用する所でした。ご教示いただきありがとうございます。 なるほど、Rayを飛ばす方法ですね。こちらは今でも使われている方法なのですね。 ありがとうございます。 最後に1点だけ質問させていただきたいのですが、 UnityEngine.UI.Buttonをアタッチする方法は、click処理のみの実装しかできないという認識で合っていますか?ドラッグ処理は実装できないですよね?
IShix

2019/03/16 18:13 編集

> OnMouseDownメソッド等は旧式で非推奨だったのですね。 非推奨にはなっておりませんが、今はEventSystemがあるので覚える必要は無いと思います。 > UnityEngine.UI.Buttonをアタッチする方法は、click処理のみの実装しかできない そうです。クリック処理しか実装できません。ドラッグ処理は自前で書く必要がありますがIDragHandlerを実装するだけなのでシンプルです。過去にドラッグ処理で回答したので良ければ見てみてください。 https://teratail.com/questions/174127
退会済みユーザー

退会済みユーザー

2019/03/17 02:42

ご回答ありがとうございます。 なるほど、非推奨というわけではないのですね。 ドラッグ処理のご提示ありがとうございます。 勉強させていただきます。 現在の疑問点が全て解決しました。 大変遅くなってしまった返信にも関わらず、ご丁寧にご教示いただき、本当にありがとうございました。
IShix

2019/03/17 06:29

解決できてよかったです。 Unityはどんどん機能が新しくなります。 改善が難しいものは新しく作り直すことも多いです。 そのひとつがuGUIです。 余談ですが、uGUIはNGUIというプラグインの作者との共同開発で完成しました。 https://assetstore.unity.com/packages/tools/gui/ngui-next-gen-ui-2413 そして、2018にはUIElementsがリリースされました。HTML+CSSのようなスクリプトからレイアウトできるものです。ランタイムで利用できるのはまだ先の話なので今は流し読み程度で良いと思いますが、その中で 新しいクリックイベント「UnityEngine.UIElements.Button.clickable.clicked」が登場しました。 https://docs.unity3d.com/2019.1/Documentation/ScriptReference/UIElements.Button.html UIElementsの開発がうまくいってメジャーバージョンがリリースされれば 来年には上記 + UIElements系イベントを意識する必要が出てくると思います。 参考 https://qiita.com/enrike3/items/286977f46d842e4a90e5
退会済みユーザー

退会済みユーザー

2019/03/17 07:23

ご回答ありがとうございます。 UIElementsというものがリリースされていたのですね、知りませんでした。 リンク先拝見しました。勉強になります。 今後は、UIElementsの動向に関してもチェックしていきたいと思います。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問