質問: ### 前提・実現したいこと UIのドラッグを実装する方法は何が最適でしょうか? また、Event SystemとEvent Triggerはそれぞれ別の実装方法なのでしょうか? ### 試したこと Event Systemに関しては、このようなサイトを見つけました。 ``` using UnityEngine.EventSystems; public class TestDrag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler { ``` このように、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を比較した場合、それぞれのメリット、デメリットは何なのか? ``` 等です。 ご教授のほどお願いします。
回答: ### 機能説明 **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にアタッチすることで動作します。 ``` using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; [RequireComponent(typeof(Image))] public class DraggableImg : MonoBehaviour, IDragHandler { RectTransform Tr; void Awake() { Tr = GetComponent(); } public void OnDrag(PointerEventData eventData) { Move(eventData.position); } void Move(Vector3 pos) { Tr.position = pos; } } ``` ### 知っておくと便利なこと **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)座標の変換について