Search code examples
unity-game-engine

How can I get my Custom Editor Tool to work in unity


I want to be able to visualize where my 'ResourceAreas' are whilst in edit mode so i tried to create a tool to display them in the scene view. Here is the code for the editor:

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(ResourceAreas))]
public class ResourceAreasEditor : Editor
{
    void OnSceneGUI()
    {
        ResourceAreas resourceAreas = (ResourceAreas)target;

        foreach (ResourceArea area in resourceAreas.resourceAreas)
        {
            Handles.color = Color.red;
            Handles.DrawWireDisc(area.center, new Vector3(0,1,0), area.radius);

            EditorGUI.BeginChangeCheck();
            Vector3 newCenter = Handles.PositionHandle(area.center, Quaternion.identity);
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(resourceAreas, "Move Resource Area Center");
                area.center = newCenter;
                EditorUtility.SetDirty(resourceAreas);
            }
        }
    }
}

However upon selecting my ResourceAreas scriptable object no discs appear in the scene view. This is the code for the scriptable object and what one looks like in inspector:

using UnityEngine;

[System.Serializable]
public class ResourceArea
{
    public string resourceName;
    public Vector3 center;  // Center point in terrain space
    public float radius;    // Radius of the resource area
    public int resourceCount;
}

[CreateAssetMenu(fileName = "ResourceAreas", menuName = "ScriptableObjects/ResourceAreas", order = 1)]
public class ResourceAreas : ScriptableObject
{
    public ResourceArea[] resourceAreas;
}

enter image description here


Solution

  • You need to create an Editor Window Script. This script will create a custom editor window that listens to selection changes and draws Gizmos in the Scene view.

    using UnityEditor;
    using UnityEngine;
    
    public class ResourceAreasEditorWindow : EditorWindow
    {
       private ResourceAreas resourceAreas;
    
       [MenuItem("Window/Resource Areas Editor")]
       public static void ShowWindow()
       {
           GetWindow<ResourceAreasEditorWindow>("Resource Areas Editor");
       }
    
       private void OnEnable()
       {
           Selection.selectionChanged += OnSelectionChanged;
           SceneView.duringSceneGui += OnSceneGUI;
       }
    
       private void OnDisable()
       {
           Selection.selectionChanged -= OnSelectionChanged;
           SceneView.duringSceneGui -= OnSceneGUI;
       }
    
       private void OnSelectionChanged()
       {
           if (Selection.activeObject is ResourceAreas)
           {
            resourceAreas = Selection.activeObject as ResourceAreas;
           }
       }
    
       private void OnSceneGUI(SceneView sceneView)
       {
           if(resourceAreas == null)
             return;
    
           foreach (ResourceArea area in resourceAreas.resourceAreas)
           {
               Handles.color = Color.red;
               Handles.DrawWireDisc(area.center, new Vector3(0,1,0), area.radius);
               SceneView.RepaintAll();
           }
       }
    
       private void OnGUI()
       {
           EditorGUILayout.LabelField("Selected ResourceAreas:", EditorStyles.boldLabel);
           if (resourceAreas != null)
           {
               EditorGUILayout.LabelField("Name: ", resourceAreas.name);
               // Display other properties of resourceAreas if needed
           }
           else
               EditorGUILayout.LabelField("No ResourceAreas selected.");
     
       }
     }
    

    Then, open the custom editor window via Window > Resource Areas Editor. Select a ResourceAreas ScriptableObject in the Project window. it will draw wiredisc in the Scene view when a ResourceAreas ScriptableObject is selected.

    enter image description here