So when an object has a mesh renderer with a material selected, you can edit the material in the same inspector window. Is there anyway to do this with a custom editor?
2 Answers
2Hi, I know this topic is old but I think I have a nice way to achieve this with shader selection.
I use a MaterialEditor with the following methods: MaterialEditor.DrawHeader () and MaterialEditor.OnInspectorGUI ().
Example code:
using UnityEditor;
[CustomEditor(typeof(MyScript))]
public class MyScriptEditor : Editor
{
private MyScript _myScript;
// We need to use and to call an instnace of the default MaterialEditor
private MaterialEditor _materialEditor;
void OnEnable ()
{
_myScript = (MyScript)target;
if (_myScript.material != null) {
// Create an instance of the default MaterialEditor
_materialEditor = (MaterialEditor)CreateEditor (_myScript.material);
}
}
public override void OnInspectorGUI ()
{
EditorGUI.BeginChangeCheck ();
// Draw the material field of MyScript
EditorGUILayout.PropertyField (serializedObject.FindProperty ("material"));
if (EditorGUI.EndChangeCheck ()) {
serializedObject.ApplyModifiedProperties ();
if (_materialEditor != null) {
// Free the memory used by the previous MaterialEditor
DestroyImmediate (_materialEditor);
}
if (_myScript.material != null) {
// Create a new instance of the default MaterialEditor
_materialEditor = (MaterialEditor)CreateEditor (_myScript.material);
}
}
if (_materialEditor != null) {
// Draw the material's foldout and the material shader field
// Required to call _materialEditor.OnInspectorGUI ();
_materialEditor.DrawHeader ();
// We need to prevent the user to edit Unity default materials
bool isDefaultMaterial = !AssetDatabase.GetAssetPath (_myScript.material).StartsWith ("Assets");
using (new EditorGUI.DisabledGroupScope(isDefaultMaterial)) {
// Draw the material properties
// Works only if the foldout of _materialEditor.DrawHeader () is open
_materialEditor.OnInspectorGUI ();
}
}
}
void OnDisable ()
{
if (_materialEditor != null) {
// Free the memory used by default MaterialEditor
DestroyImmediate (_materialEditor);
}
}
}
With the new Unity 4 Editor.CreateEditor class you can in fact render a preview interface as well. Here is a simple demonstration:
using UnityEngine;
using UnityEditor;
class MaterialEditorWindow : EditorWindow {
[MenuItem("Window/Material Editor Test")]
static void ShowWindow() {
GetWindow<MaterialEditorWindow>("Material Editor Test");
}
Material mat;
Editor matEditor;
void OnGUI() {
mat = EditorGUILayout.ObjectField(mat, typeof(Material)) as Material;
if (mat != null) {
if (matEditor == null)
matEditor = Editor.CreateEditor(mat);
matEditor.OnPreviewGUI(GUILayoutUtility.GetRect(200, 300), EditorStyles.whiteLabel);
}
}
}
Sorry, I'm actually talking about editing the properties of the material, not just previewing it. Currently, I'm using CreateEditor and then calling OnInspectorGUI with the material editor. However, this leaves out the top bar that appears for built in components.
– TheOrangeManEditorGUILayout.InspectorTitlebar? http://docs.unity3d.com/Documentation/ScriptReference/EditorGUILayout.InspectorTitlebar.html
Gave it a shot. It's better than nothing at all, but as you said, there's unfortunately no shader selection.
– TheOrangeMan
You can create enumerate the properties of a material to present a custom user interface similar to the default Unity one. You will need to be using Unity Pro in order to render a real-time preview of the material in your editor interface since the indie version cannot do this properly due to restrictions.
– numberkruncherCurrently, I'm just creating an editor for the desired material (Editor::CreateEditor) and drawing that. This almost works, but it leaves out the preview bar. If the only option's to create that by hand though, I'll probably just leave it how it is.
– TheOrangeMan