シーンビューで動作するスクリプトを作成できるようにするには、まず、作業中のクラスをエディターまたは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タイルレベルエディターの作成があります。 マップクラス用に同様のカスタムエディターを作成し、イベントをインターセプトするときに、マウスの座標を取得して、クリックされた特定の子要素を判別できます。 特定の要素を特定するには、レイキャストを作成します。レイキャストは、シーンビューではゲーム中とまったく同じように機能します。
ここで休暇を取らせてください。この記事が誰かに役立つことを願っています。