Hi there!
I’m trying to make a custom editor for GameObject. It works fine, and I’m glad to share the trick with you. But wait, Unity acts really weird when you’re using 3D models with a custom editor for GameObject in your project!
As an example, I made the following script, which will list all the components on a selected GameObject:
using System;
using System.Reflection;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(GameObject))]
[CanEditMultipleObjects]
public class GameObjectCustomEditorDemo : Editor
{
private Editor m_DefaultGameObjectEditor = null;
private void OnEnable()
{
// Creates the default inspector view of GameObject using reflection (needed to access to the internal UnityEditor classes)
m_DefaultGameObjectEditor = CreateEditor(target, Type.GetType("UnityEditor.GameObjectInspector, UnityEditor"));
}
private void OnDisable()
{
if (m_DefaultGameObjectEditor != null)
{
// Check if the preview cache property is set
object previewCache = m_DefaultGameObjectEditor.GetType()
.GetField("m_PreviewCache", BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(m_DefaultGameObjectEditor);
// If the preview cache is not defined, call OnEnable() method to initialize the GameObject editor, avoiding exceptions
if (previewCache == null)
m_DefaultGameObjectEditor.GetType().GetMethod("OnEnable").Invoke(m_DefaultGameObjectEditor, null);
DestroyImmediate(m_DefaultGameObjectEditor);
}
}
protected override void OnHeaderGUI()
{
// Draw the default GameObject editor header
m_DefaultGameObjectEditor.DrawHeader();
}
public override void OnInspectorGUI()
{
// Draw the default GameObject editor inspector GUI
m_DefaultGameObjectEditor.OnInspectorGUI();
// Draw a list of all the components on the first selected GameObject
EditorGUILayout.LabelField("Components on this GameObject:", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
Component[] components = (target as GameObject).GetComponents<Component>();
for (int i = 0; i < components.Length; i++)
{
EditorGUILayout.LabelField($"[{i}] {components[i].GetType().Name}");
}
EditorGUI.indentLevel--;
EditorGUILayout.Space();
}
}
With this script in your project, you should see the components list in the inspector when you select a GameObject:
Pretty cool, right? This really works like a charm (and the trick is quite the same for other native components by the way)… But there is bad side effects with 3D models:
- Their preview are no more visible in the Project window
- Their preview is not displayed in the Model Importer view (in the Inspector)
- I can’t drag and drop them from my Project view to the Scene view (but dragging them to the Hierarchy still works)
Unfortunately, these bugs makes the tool unusable for productions. I searched for a solution by tryings things with reflection and using the Unity’s C# reference on GitHub, but that was unsuccessful.
So, I would like to find:
- why Unity behaves that way when creating a custom GameObject editor?
- and how can I fix this issue?
Does someone have at least a track I can explore?
Thanks in advance for any answer!
(and sorry to the Unity Technologies guys who will see this post for doing too many experiments with your wonderful game engine!)