Skip to content

Instantly share code, notes, and snippets.

@tomkail
Last active August 21, 2024 10:41
Show Gist options
  • Save tomkail/1cb4e700e328675f2c54ea56e75b2cd0 to your computer and use it in GitHub Desktop.
Save tomkail/1cb4e700e328675f2c54ea56e75b2cd0 to your computer and use it in GitHub Desktop.
Draws inspectors for any file type Unity doesn't draw by default
/// Used to draw custom inspectors for unrecognised file types, which Unity imports as "DefaultAsset"
/// To do this, create a new editor class extending DefaultAssetInspector
/// Return true in the IsValid function if the file extension of the file matches the type you'd like to draw.
/// The DefaultAssetEditor class will then hold a reference to the new instance of your editor class and call the appropriate methods for drawing.
/// An example can be found at the bottom of the file.
using UnityEngine;
using UnityEditor;
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
/// <summary>
/// Used to draw custom inspectors for unrecognised file types, which Unity imports as "DefaultAsset"
/// </summary>
[CustomEditor(typeof(DefaultAsset), true)]
public class DefaultAssetEditor : Editor {
private DefaultAssetInspector inspector;
private void OnEnable () {
inspector = FindObjectInspector ();
if(inspector != null) {
inspector.editor = this;
inspector.serializedObject = serializedObject;
inspector.target = target;
inspector.OnEnable();
}
}
private void OnDisable () {
if(inspector != null)
inspector.OnDisable();
}
protected override void OnHeaderGUI () {
if(inspector != null) {
inspector.OnHeaderGUI();
}
else if (target.GetType() != typeof(UnityEditor.DefaultAsset))
base.OnHeaderGUI();
}
public void DrawDefaultHeaderGUI () {
base.OnHeaderGUI();
}
public override void OnInspectorGUI () {
if(inspector != null) {
GUI.enabled = true;
inspector.OnInspectorGUI();
}
else if (target.GetType() != typeof(UnityEditor.DefaultAsset))
base.OnInspectorGUI();
}
private DefaultAssetInspector FindObjectInspector () {
List<string> assembliesToCheck = new List<string>{"Assembly-CSharp-Editor", "Assembly-CSharp-Editor-firstpass", "Assembly-UnityScript-Editor", "Assembly-UnityScript-Editor-firstpass"};
string assetPath = AssetDatabase.GetAssetPath(target);
Assembly[] referencedAssemblies = System.AppDomain.CurrentDomain.GetAssemblies();
for(int i = 0; i < referencedAssemblies.Length; ++i) {
if(!assembliesToCheck.Contains(referencedAssemblies[i].GetName().Name))
continue;
foreach(var type in referencedAssemblies[i].GetTypes()) {
if(!type.IsSubclassOf(typeof(DefaultAssetInspector)))
continue;
DefaultAssetInspector objectInspector = (DefaultAssetInspector)Activator.CreateInstance(type);
if(objectInspector.IsValid(assetPath)) {
objectInspector.target = target;
return objectInspector;
}
}
}
return null;
}
}
/// <summary>
/// Default asset inspector. Used by DefaultAssetEditor
/// </summary>
public abstract class DefaultAssetInspector {
// Reference to the actual editor we draw to
public DefaultAssetEditor editor;
// Shortcut to the target object
public UnityEngine.Object target;
// Shortcut to the serializedObject
public SerializedObject serializedObject;
public abstract bool IsValid(string assetPath);
public virtual void OnEnable () {}
public virtual void OnDisable () {}
// An example of how Unity draws headers can be found at https://github.com/MattRix/UnityDecompiled/blob/master/UnityEditor/UnityEditor/Editor.cs
public virtual void OnHeaderGUI () {
editor.DrawDefaultHeaderGUI();
}
public virtual void OnInspectorGUI() {}
}
// EXAMPLE FOR A .SAVE FILE
// public class SaveFileInspector : DefaultAssetInspector {
// public override bool IsValid(string assetPath) {
// return Path.GetExtension(assetPath) == ".save";
// }
// public override void OnInspectorGUI () {
// // Call to redraw every frame
// editor.Repaint();
// serializedObject.Update();
// // Use System.IO.File to read the file contents and draw it here if you wish!
// var assetPath = AssetDatabase.GetAssetPath(editor.target);
// var absolutePath = System.IO.Path.Combine(Application.dataPath.Substring(0, Application.dataPath.Length-7), assetPath);
// var text = System.IO.File.ReadAllText(absolutePath);
// EditorGUILayout.TextArea(text);
// serializedObject.ApplyModifiedProperties();
// }
// }
@tomkail
Copy link
Author

tomkail commented Nov 7, 2017

Example of use in our Ink Integration package.

image

@mewpipe
Copy link

mewpipe commented Aug 17, 2024

Hello. Do you know how to draw on inspector only if it is empty? Because when there is no object selected, it's a lot of useless space. I want to add some shortcuts inside inspector window if there is nothing to inspect.
Thanks.

@tomkail
Copy link
Author

tomkail commented Aug 21, 2024

@mewpipe I assume you mean when selecting a Directory, since you mention being empty? If so, override IsValid, and using the path, use System.IO.Directory to determine if the folder is empty and return a boolean.

@mewpipe
Copy link

mewpipe commented Aug 21, 2024

Thanks, I'll try that. I don't know if it's exactly what I am looking for.
I want to draw something in inspector if nothing is selected (empty inspector like that:)
empty

@mewpipe
Copy link

mewpipe commented Aug 21, 2024

Ok, I tried. In fact what I need is that :

public override bool IsValid(string assetPath) {
   return string.IsNullOrEmpty(assetPath); // Nothing selected
}

But your code only execute when something is selected in project window.
My condition is always "false".

@tomkail
Copy link
Author

tomkail commented Aug 21, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment