Unity3Dでのシーンビュー機能の拡張。 イベントの傍受

Unity3Dのシーンビューは、最も必要なインターフェイス要素の1つです。 Unity3Dを実行したことのある人は全員、シーンビューを使用して、ステージ上でオブジェクトを視覚的に配置したり、構成したりしています。 シーンビュー機能の拡張は、独自のレベルエディターの作成、メッシュの編集、独自のギズモの作成などに必要になる場合があります。 プロジェクトで地形を使用する場合、その編集(テクスチャの描画、高さの変更、樹木や植生の植栽)はシーンビューを使用して実行されることに注意してください。



シーンビューで動作するスクリプトを作成できるようにするには、まず、作業中のクラスをエディターまたはEditorWindowから継承する必要があります。これは、名前空間UnityEditorを接続することを意味します。 これにより、OnGUI()やOnSceneGUI()など、いくつかのUnity3Dマジックメソッドにアクセスできます。 OnSceneGUIメソッドを使用すると、エディターはシーンビューイベントを管理できます。





少し叙情的な余談。 開発者の間では、「マジック」メソッド(Update、Start、OnSceneGUIなど)はC#のSystem.Reflectionを使用して実装されているという意見がありますが、そうではないという情報があります 。 一般に、この記事は、コード内で複数のUpdate()を犯した人にとって有用です。



イベントの傍受に戻りましょう。 アイデアは、IMGUIのラベルまたはボタンと同等に、Unityインターフェイスの要素として、機能を開発するオブジェクトを指定することです。



APIには、キーストローク、マウスボタン、レンダリングイベント、UnityレイアウトなどのさまざまなGUIイベントに使用されるイベントクラスがあります。



イベントに加えて、クリックをキャッチするには、コントロールなどが必要になります。 Unityのコントロールとして、IMGUIのあらゆる要素が機能します。 たとえば、ボタンまたはラベル。 オブジェクトがクリックをインターセプトするには、コントロールでもあり、イベント処理に参加することをUnityに伝える必要があります。 これを行うには、 GUIUtilityクラスを使用します。

各コントロールには、Unityが必要なすべての情報を受け取るために、独自の一意のIDが必要です。 idはintですが、一意でなければならないことに注意してください。 乱数(0以外)を生成し、それをコントロールのIDとして読み取ることができますが、システムに同じIDのコントロールがもはやないという保証はありません。この場合、クリックは、カウントしていた間違った要素に移動します。 一意のIDを作成するには、GUIUtilityクラスのメソッドを使用します

public static int GUIUtility.GetControlID(FocusType focus)
      
      





このメソッドが受け取るパラメーターは、キーボードからの入力を受け取る制御機能を担当します。 それに関する情報はドキュメントで入手できます 。 シーンビューを使用する場合、キーボード入力は必要ないため、値FocusType.Passiveが適切です。

  int controlId = GUIUtility.GetControlID(FocusType.Passive); //  id    .
      
      





IDを取得できたので、次はイベントフックについて説明します。 Event.currentプロパティを使用して、現在のイベントに関する情報を取得できます。 Unityで発生したイベントのタイプを取得するには、以下を実行する必要があります

 int controlId = GUIUtility.GetControlID(FocusType.Passive); Event.current.GetTypeForControl(controlId)
      
      





この呼び出しは、コントロールのEventType型の値を返します。 次に、必要なイベントの種類を決定してインターセプトするだけです。 イベントは次のように直接インターセプトされます

 GUIUtility.hotControl = controlId;
      
      





マウスクリックの場合、コントロールは「ホット」であると言います。つまり、主にマウスイベントに応答し、他のコントロールに移動しません。

この側面については、 ドキュメントで詳しく説明しています 。 マウスイベントへのアクセスを他のコントロールに戻すには、以下を行う必要があります

 GUIUtility.hotControl = 0;
      
      





これにより、他のコントロールが次のマウスイベントをインターセプトできることがわかります。 イベントは、使用しない場合、他のコントロールにも使用できます。 つまり、 使用済みとしてマークしないでください

 Event.current.Use();
      
      





シーンビューのクリックを処理するスクリプトの完全な例を示します

 using UnityEngine; using UnityEditor; [CustomEditor(typeof(MyCustomComponent))] public class MyCustomEditor : Editor { void OnSceneGUI() { int controlId = GUIUtility.GetControlID(FocusType.Passive); switch (Event.current.GetTypeForControl(controlId)) { case EventType.MouseDown: GUIUtility.hotControl = controlId; //    MouseDown //   if(Event.current.button == 0) { // . . . } //   if(Event.current.button == 1) { // . . . } //  Event.current.Use(); break; case EventType.MouseUp: //  control     GUIUtility.hotControl = 0; Event.current.Use(); break; } }
      
      





上記の資料の必要性について誰かが質問するかもしれません。 例として、2Dタイルレベルエディターの作成があります。 マップクラス用に同様のカスタムエディターを作成し、イベントをインターセプトするときに、マウスの座標を取得して、クリックされた特定の子要素を判別できます。 特定の要素を特定するには、レイキャストを作成します。レイキャストは、シーンビューではゲーム中とまったく同じように機能します。



ここで休暇を取らせてください。この記事が誰かに役立つことを願っています。



All Articles