Search Unity

How can I use the "Mesh Inspector" preview in an Editor Window?

Discussion in 'Immediate Mode GUI (IMGUI)' started by StewVanB, Jan 18, 2019.

  1. StewVanB

    StewVanB

    Joined:
    Apr 12, 2011
    Posts:
    74
    I have built a tool to allow our artists to search for Mesh assets by complexity. This is so they can quickly find assess and correct models in the project. I have also written an "Auto Mesh Simplify" function that I would like to show a preview of before applying the changes to the Mesh asset.

    I can not find any documentation on how Unity renders the preview of the mesh in the Mesh Inspector. I have messed with the PreviewRenderUtility with which I can ultimately generate a 2d image of a specific angle of the model. This works for some objects and not for others as the zoom and framing of the models is largely depending on size. Another caveat of this method is that it doesn't allow for manipulation of the view. It is also missing the Mesh statistical information.

    I want to create an instance of this UI in my own EditorWindow:



    I have thought I could use the GUI loop to add controls to the images and update the image every frame. This seems like a poor solution to what should be an easy implementation of an existing Editor system.

    Thanks for reading my post, any help is appreciated.
     
    Last edited: Jan 18, 2019
  2. alexanderameye

    alexanderameye

    Joined:
    Nov 27, 2013
    Posts:
    1,383
    Hey, I have no idea if this still works or if this did work, but I remember that I managed to get it to work and someone asked me how I did it and I send him this code.

    Code (CSharp):
    1. public class RockStudio : EditorWindow
    2. {
    3.     GameObject gameObject;
    4.     Editor gameObjectEditor;
    5.     Texture2D previewBackgroundTexture;
    6.     void OnGUI ()
    7.     {
    8.         EditorGUI.BeginChangeCheck();
    9.    
    10.         gameObject = (GameObject) EditorGUILayout.ObjectField(gameObject, typeof(GameObject), true);
    11.    
    12.         if(EditorGUI.EndChangeCheck())
    13.         {
    14.             if(gameObjectEditor != null) DestroyImmediate(gameObjectEditor);
    15.         }
    16.    
    17.         GUIStyle bgColor = new GUIStyle();
    18.    
    19.         bgColor.normal.background = previewBackgroundTexture;
    20.    
    21.         if (gameObject != null)
    22.         {
    23.             if (gameObjectEditor == null)
    24.        
    25.             gameObjectEditor = Editor.CreateEditor(gameObject);
    26.             gameObjectEditor.OnInteractivePreviewGUI(GUILayoutUtility.GetRect (200,200),bgColor);
    27.         }
    28.     }
    29. }
     
    CodeSmile, ryanlin138, dev2X and 2 others like this.
  3. alexanderameye

    alexanderameye

    Joined:
    Nov 27, 2013
    Posts:
    1,383
    I also have an open source prefab painter on GitHub where I use this interactive preview. You can check it out there how I did it. https://github.com/AlexanderAmeye/prefab-painter
    The mesh statistical information is just a label rendered on top of the preview.

     
  4. Urocco

    Urocco

    Joined:
    Apr 17, 2018
    Posts:
    1
    It's working @2019.4.8
    Thank you sooo much
     
  5. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,975
    Here's my implementation using UIElements / UI Toolkit (simply wrapping the Inspector GUI in a IMGUIContainer):
    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3. using UnityEngine.UIElements;
    4.  
    5. [CustomEditor(typeof(MeshPreview))]
    6. public class MeshPreviewEditor : Editor
    7. {
    8.     private UnityEditor.MeshPreview preview;
    9.  
    10.     private void OnDisable()
    11.     {
    12.         if (preview != null)
    13.         {
    14.             preview.Dispose();
    15.             preview = null;
    16.         }
    17.     }
    18.  
    19.     public override void OnInspectorGUI()
    20.     {
    21.         DrawDefaultInspector();
    22.  
    23.         var mp = target as MeshPreview;
    24.         if (mp.mesh == null)
    25.             return;
    26.  
    27.         if (preview == null)
    28.             preview = new UnityEditor.MeshPreview(mp.mesh);
    29.         if (preview.mesh != mp.mesh)
    30.             preview.mesh = mp.mesh;
    31.  
    32.         var rect = GUILayoutUtility.GetRect(1, mp.previewHeight);
    33.         preview.OnPreviewGUI(rect, "TextField");
    34.         if (mp.showSettings)
    35.             preview.OnPreviewSettings();
    36.     }
    37.  
    38.     public override VisualElement CreateInspectorGUI()
    39.     {
    40.         var customInspector = new VisualElement();
    41.         customInspector.Add(new IMGUIContainer(() => { OnInspectorGUI(); }));
    42.         return customInspector;
    43.     }
    44. }
    The referenced MeshPreview class is a MonoBehaviour with fields to control behaviour via Inspector:
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class MeshPreview : MonoBehaviour
    4. {
    5.     public Mesh mesh;
    6.     [Range(1, 1000)] public int previewHeight = 100;
    7.     public bool showSettings = true;
    8. }
     
    CunningFox146 likes this.