Skip to content

Instantly share code, notes, and snippets.

@GhatSmith
Last active September 15, 2018 23:35
Show Gist options
  • Save GhatSmith/aded0728815ef714dda4dab1f0be0f4a to your computer and use it in GitHub Desktop.
Save GhatSmith/aded0728815ef714dda4dab1f0be0f4a to your computer and use it in GitHub Desktop.
using UnityEngine;
using UnityEditor;
using System.Linq;
using UnityEngine.SceneManagement;
using System.Globalization;
namespace OddTales.Framework.Core.EditorExtension
{
// InitializeOnLoad : force constructor call
[InitializeOnLoad]
public static class SceneInformationsWidget
{
private static bool enable = false;
private static bool initialized = false;
// Needed for bold (rich text) and font color
private static GUIStyle textStyle;
private static bool selectionChanged = false, hierarchyChanged = false;
private static int numberOfSelected = 0, numberOfChildren = 0, numberOfChildrenRecursive = 0;
private static int numberOfRootGameObjects = 0, numberOfGamesObjectsInScene = 0;
private static int numberOfVerticesInChildren = 0, numberOfTrianglesInChildren = 0;
// Needed to display numbers with good formatting
private static NumberFormatInfo integerFormatInfo;
// Construtor
static SceneInformationsWidget()
{
enable = EditorPrefs.GetBool(SceneInformationsKey("Display"), false);
if (enable) Init();
}
static void Init()
{
initialized = true;
SceneView.onSceneGUIDelegate -= SceneInformationsWidget.OnSceneGUI;
SceneView.onSceneGUIDelegate += SceneInformationsWidget.OnSceneGUI;
Selection.selectionChanged -= OnSelectionChanged;
Selection.selectionChanged += OnSelectionChanged;
EditorApplication.hierarchyChanged -= OnHierarchyChanged;
EditorApplication.hierarchyChanged += OnHierarchyChanged;
selectionChanged = hierarchyChanged = true;
integerFormatInfo = new NumberFormatInfo();
integerFormatInfo.NumberGroupSeparator = " ";
SceneView.RepaintAll();
}
[MenuItem("Tools/Scene Widgets/Display Scene Informations")]
public static void Enable()
{
enable = !enable;
EditorPrefs.SetBool(SceneInformationsKey("Display"), enable);
Menu.SetChecked("Tools/Display Scene Informations", enable);
if (enable && !initialized) Init();
else SceneView.RepaintAll();
}
// Menu.SetChecked doesn't work in constructor (Unity bug ?). Must use it in MenuItem validation method
[MenuItem("Tools/Display Scene Informations", true)]
public static bool EnableValidation()
{
Menu.SetChecked("Tools/Scene Widgets/Display Scene Informations", enable);
return true;
}
private static string SceneInformationsKey(string key)
{
return "NyxFramework_ScenesInformationsWidget_" + key;
}
public static void OnSceneGUI(SceneView sceneView)
{
if (!enable) return;
// Style must be initialized in GUI method (because it uses GUI method)
if (textStyle == null)
{
textStyle = new GUIStyle(GUI.skin.label);
textStyle.richText = true;
textStyle.normal.textColor = Color.white;
}
// 2D Screen GUI
Handles.BeginGUI();
// Background to improve text visibility
GUI.backgroundColor = Color.black;
EditorGUI.HelpBox(new Rect(0, 0, 200, 210), "", MessageType.None);
GUI.backgroundColor = Color.white;
if (selectionChanged)
{
UpdateSelectionChildrenCount();
UpdateChildenVerticesAndTrianglesNumbers();
selectionChanged = false;
}
GUI.Label(new Rect(20, 10, 400, 20), "<b>Selection</b>", textStyle);
GUI.Label(new Rect(20, 30, 400, 20), "GameObjects : " + numberOfSelected, textStyle);
GUI.Label(new Rect(20, 50, 400, 20), "Direct children : " + numberOfChildren, textStyle);
GUI.Label(new Rect(20, 70, 400, 100), "Recursive children : " + numberOfChildrenRecursive, textStyle);
GUI.Label(new Rect(20, 90, 400, 100), "Vertices : " + numberOfVerticesInChildren.ToString("N0", integerFormatInfo), textStyle);
GUI.Label(new Rect(20, 110, 400, 100), "Triangles : " + numberOfTrianglesInChildren.ToString("N0", integerFormatInfo), textStyle);
if (hierarchyChanged)
{
UpdateSceneNumberOfobjectsCount();
hierarchyChanged = false;
}
GUI.Label(new Rect(20, 140, 400, 20), "<b>Active scene</b>", textStyle);
GUI.Label(new Rect(20, 160, 400, 20), "Root GameObjects : " + numberOfRootGameObjects, textStyle);
GUI.Label(new Rect(20, 180, 400, 20), "GameObjects : " + numberOfGamesObjectsInScene, textStyle);
Handles.EndGUI();
}
private static void OnHierarchyChanged()
{
hierarchyChanged = true;
}
private static void OnSelectionChanged()
{
selectionChanged = true;
}
private static void UpdateSelectionChildrenCount()
{
numberOfSelected = Selection.gameObjects.Length;
numberOfChildren = numberOfChildrenRecursive = 0;
for (int i = 0; i < Selection.gameObjects.Length; i++)
{
numberOfChildren += GetNumberOfChildren(Selection.gameObjects[i].transform, false);
numberOfChildrenRecursive += GetNumberOfChildren(Selection.gameObjects[i].transform, true);
}
}
private static void UpdateSceneNumberOfobjectsCount()
{
GameObject[] rootGameObjects = SceneManager.GetActiveScene().GetRootGameObjects();
numberOfRootGameObjects = rootGameObjects.Length;
numberOfGamesObjectsInScene = 0;
for (int i = 0; i < rootGameObjects.Length; i++)
{
numberOfGamesObjectsInScene += 1 + GetNumberOfChildren(rootGameObjects[i].transform, true);
}
}
private static int GetNumberOfChildren(Transform goTransform, bool recursive)
{
if (recursive)
{
int childrenNumber = 0;
for (int i = 0; i < goTransform.childCount; i++)
{
childrenNumber += 1 + GetNumberOfChildren(goTransform.GetChild(i), true);
}
return childrenNumber;
}
else return goTransform.childCount;
}
private static void UpdateChildenVerticesAndTrianglesNumbers()
{
numberOfVerticesInChildren = numberOfTrianglesInChildren = 0;
for (int i = 0; i < Selection.gameObjects.Length; i++)
{
MeshFilter[] meshFilters = Selection.gameObjects[i].GetComponentsInChildren<MeshFilter>();
numberOfVerticesInChildren += meshFilters.Where(x => x.sharedMesh != null).Sum(x => x.sharedMesh.vertexCount);
numberOfTrianglesInChildren += meshFilters.Where(x => x.sharedMesh != null).Sum(x => x.sharedMesh.triangles.Length / 3);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment