Search Unity

  1. We are migrating the Unity Forums to Unity Discussions by the end of July. Read our announcement for more information and let us know if you have any questions.
    Dismiss Notice
  2. Dismiss Notice

How do I have my editor draw in the scene view?

Discussion in 'Immediate Mode GUI (IMGUI)' started by dkoontz, Aug 31, 2009.

  1. dkoontz

    dkoontz

    Joined:
    Aug 7, 2009
    Posts:
    198
    I've got a very basic editor used for designing levels in my game. It has you pick 2 game objects and then creates a link between them. I want to visualize this so you can see the links that have been created. I was trying to accomplish this through some variant of DrawLine, either via Debug or Handles or Gizmos. So in the OnGUI method of my EditorWindow subclass I check for various things and then do my call to one of the DrawLine methods. Nothing shows up in the scene view until it receives focus. Is the scene view's camera not be rendered since the scene view doesn't have focus?
     
  2. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Editor functionality only works in the editor.

    If you want an editor thats deliveried with the game you must write your own editor functioanlity.
     
  3. dkoontz

    dkoontz

    Joined:
    Aug 7, 2009
    Posts:
    198
    I don't want to deliver this editor with the game, I just want to be able to visualize the settings being made in the editor window, so you can click a link in the editor and see it visually on the screen.
     
  4. dkoontz

    dkoontz

    Joined:
    Aug 7, 2009
    Posts:
    198
    Well, after quite a bit of testing and experimentation I settled in on a solution I can live with. I switched the editor over from an EditorWindow to a Custom Editor targeting the script that holds my level data. That way when you click on the "Level" prefab in the scene you get the editor in the inspector. This prefab is totally blank except for my script and I drop it into each level to control the loading of the level data my editor produces.

    My final solution to make the scene view update nicely was simply to add this to my OnInspectorGUI method:

    Code (csharp):
    1.  
    2. target.gameObject.transform.position.x += 0.1;
    3. target.gameObject.transform.position.x -= 0.1;
    4.  
    Then I do all of my overlay drawing in the OnSceneGUI method which gets called because something in the scene moved. This means that anytime you change an option in the editor you immediately see the results but you're not spamming a redraw of the scene as the OnInspectorGUI events happen only when you're active in the editor. I felt this was a pretty nice compromise as far as dirty hacks go. Here is the full code, most of the editor stuff is totally useless for any other project but hopefully there's some useful code in there for others with a similar problem.

    Code (csharp):
    1.  
    2. @CustomEditor(LevelData)
    3. class LevelEditorComponent extends Editor {
    4.     private static var startPickedObject : GameObject;
    5.     private static var endPickedObject : GameObject;
    6.     private static var selectedEdge : int = 0;
    7.     private static var selectedShape : int = 0;
    8.    
    9.     function OnInspectorGUI() {
    10.         GUILayout.Label("Create link", "BoldLabel");
    11.  
    12.         startPickedObject = EditorGUILayout.ObjectField("Start dot", startPickedObject, GameObject);
    13.         endPickedObject = EditorGUILayout.ObjectField("End dot", endPickedObject, GameObject);
    14.         var edgeLabels = new Array();
    15.         var shapeLabels = new Array();
    16.  
    17.         if(GUILayout.Button("Create New Edge", GUILayout.Width(150))) {
    18.             if(startPickedObject != null  endPickedObject != null) {
    19.                 target.AddEdge(new Edge(startPickedObject, endPickedObject));
    20.                 startPickedObject = null;
    21.                 endPickedObject = null;
    22.             }
    23.         }
    24.        
    25.         for(var i = 0; i < target.GetEdges().length; i++) {
    26.             edgeLabels.Add("Edge " + i);
    27.         }
    28.         selectedEdge = GUILayout.SelectionGrid(selectedEdge, edgeLabels.ToBuiltin(String), 1);
    29.        
    30.         if(GUILayout.Button("Create New Shape", GUILayout.Width(150))) {
    31.             target.AddShape(new Shape());
    32.         }
    33.        
    34.         for(i = 0; i < target.GetShapes().length; i++) {
    35.             shapeLabels.Add("Shape " + i);
    36.         }
    37.         selectedShape = GUILayout.SelectionGrid(selectedShape, shapeLabels.ToBuiltin(String), 1);
    38.  
    39.         ForceSceneRedraw();
    40.     }
    41.    
    42.     function OnSceneGUI() {
    43.         if(startPickedObject) {
    44.             Handles.Label(startPickedObject.transform.position, "Start");
    45.         }
    46.  
    47.         if(endPickedObject) {
    48.             Handles.Label(endPickedObject.transform.position, "End");
    49.         }
    50.        
    51.         for(var dot : GameObject in GetAllDots()) {
    52.             Handles.Label(dot.transform.position + Vector3(0, 200, 0), dot.name);
    53.         }
    54.        
    55.         var edges = target.GetEdges();
    56.         for(var i = 0; i < edges.length; i++) {
    57.             if(selectedEdge == i) {
    58.                 Handles.color = Color.white;
    59.             }
    60.             else {
    61.                 Handles.color = edges[i].GetGizmoColor();
    62.             }
    63.  
    64.             Handles.DrawLine(edges[i].GetStart().transform.position, edges[i].GetEnd().transform.position);
    65.             Handles.Label(Vector3.Lerp(edges[i].GetStart().transform.position, edges[i].GetEnd().transform.position, 0.35), "Edge " + i);
    66.         }
    67.     }
    68.    
    69.     private function ForceSceneRedraw() {
    70.         target.gameObject.transform.position.x += 0.1;
    71.         target.gameObject.transform.position.x -= 0.1;
    72.     }
    73.    
    74.     private function GetAllDots() {
    75.         return GameObject.FindGameObjectsWithTag("Dot");
    76.     }
    77. }
    78.  
    79.  
     

    Attached Files:

  5. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    Many, many thanks for sharing this hack. It works like a charm for any script that needs interactive updates in editor mode :D.
     
  6. sebbe

    sebbe

    Joined:
    Oct 18, 2009
    Posts:
    6
  7. andymads

    andymads

    Joined:
    Jun 16, 2011
    Posts:
    1,614