Skip to content

Instantly share code, notes, and snippets.

@jimkang
Created December 15, 2012 19:02
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jimkang/4298204 to your computer and use it in GitHub Desktop.
Save jimkang/4298204 to your computer and use it in GitHub Desktop.
Unity wizard script for projects using NGUI that lists all of the depths of all of the UIWidgets, arranged by UIPanel and atlas. You can then edit depths from it, but the idea is that it gives you a global sense of your widget/panel/atlas arrangement. Looks like this: http://cl.ly/image/3k3J2G0q1m1F
// ArrangeWidgetDepths.cs
// Ghost Crab Workshop
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
public class ArrangeWidgetDepths : ScriptableWizard
{
public GameObject NGUIRootObject = null;
public int numberOfLevelsToSearch = 10;
// Keys/values for this monster data struct:
// Panel transform path, atlas name, depth, widget.
Dictionary<string, Dictionary<string, Dictionary<int, List<UIWidget>>>>
widgetHierarchy = new
Dictionary<string, Dictionary<string, Dictionary<int, List<UIWidget>>>>();
protected Vector2 scrollPosition = Vector2.zero;
[MenuItem ("NGUI/Arrange All Widget Depths")]
static void CreateWizard()
{
ScriptableWizard.DisplayWizard(
"Arrange Widget Depths", typeof(ArrangeWidgetDepths));
}
void OnGUI()
{
EditorGUIUtility.LookLikeControls(80f);
this.NGUIRootObject = (GameObject)
EditorGUILayout.ObjectField("Root Object", this.NGUIRootObject,
typeof(GameObject), true, GUILayout.MaxWidth(200));
if (GUILayout.Button("Find Widgets Under Root"))
{
this.findWidgets();
this.Repaint();
}
if (this.widgetHierarchy.Count == 0)
{
GUILayout.Label(
"Use 'Find Widgets Under Root' to get the widgets and their depths.");
}
else
{
this.drawWidgetHierarchyScrollView();
}
}
protected void drawWidgetHierarchyScrollView()
{
this.scrollPosition =
EditorGUILayout.BeginScrollView(this.scrollPosition);
// Sort.
List<string> sortedPanelPaths = new List<string>(
this.widgetHierarchy.Keys);
sortedPanelPaths.Sort();
foreach (string panelPath in sortedPanelPaths)
{
GUILayout.Label(string.Format("Panel: {0}", panelPath),
EditorStyles.boldLabel);
EditorGUILayout.ObjectField(
this.objectAtTransformPathUnderRoot(panelPath),
typeof(GameObject), false);
Dictionary<string, Dictionary<int, List<UIWidget>>>
hierarchyUnderPanel = this.widgetHierarchy[panelPath];
List<string> sortedAtlasNames = new List<string>(
hierarchyUnderPanel.Keys);
sortedAtlasNames.Sort();
foreach (string atlasName in sortedAtlasNames)
{
GUILayout.BeginHorizontal();
{
GUILayout.Space(32.0f);
GUILayout.Label(string.Format("Atlas: {0}", atlasName),
EditorStyles.boldLabel);
}
GUILayout.EndHorizontal();
Dictionary<int, List<UIWidget>> hierarchyUnderAtlas =
hierarchyUnderPanel[atlasName];
List<int> sortedDepths = new List<int>(
hierarchyUnderAtlas.Keys);
sortedDepths.Sort();
foreach (int depth in sortedDepths)
{
List<UIWidget> widgetsAtDepth = hierarchyUnderAtlas[depth];
foreach (UIWidget widget in widgetsAtDepth)
{
this.drawDepthWidgetPair(depth, widget);
}
}
}
}
EditorGUILayout.EndScrollView();
}
protected void drawDepthWidgetPair(int depth, UIWidget widget)
{
GUILayout.BeginHorizontal();
{
GUILayout.Space(64.0f);
EditorGUILayout.ObjectField(widget, typeof(UIWidget), true,
GUILayout.ExpandWidth(true));
GUILayout.Space(16.0f);
widget.depth = EditorGUILayout.IntField("Depth:",
widget.depth, GUILayout.MaxWidth(128.0f));
}
GUILayout.EndHorizontal();
}
protected void findWidgets()
{
if (this.NGUIRootObject == null)
{
return;
}
this.widgetHierarchy.Clear();
this.findWidgetsUnderTransformTree(0, this.numberOfLevelsToSearch - 1,
this.NGUIRootObject.transform, "", ref this.widgetHierarchy);
}
protected void findWidgetsUnderTransformTree(int recursionLevel,
int maxRecursionLevel, Transform currentTransform,
string parentPanelPath,
ref Dictionary<string, Dictionary<string, Dictionary<int, List<UIWidget>>>>
widgetHierarchy)
{
if (recursionLevel > maxRecursionLevel)
{
// We've gone as deep as we're supposed to go.
return;
}
// Assumption: Widgets are not on the same GameObject as a UIPanel.
UIPanel currentPanel =
currentTransform.gameObject.GetComponent<UIPanel>();
if (currentPanel != null)
{
// Find the path under the absolute root object to the
// object we're currently working on.
string underPath = AnimationUtility.CalculateTransformPath(
currentTransform, this.NGUIRootObject.transform);
if (underPath.Length > 0)
{
parentPanelPath = string.Format("{0}/{1}",
this.NGUIRootObject.name, underPath);
}
else
{
parentPanelPath = this.NGUIRootObject.name;
}
}
foreach (Transform child in currentTransform)
{
UIWidget widget = child.gameObject.GetComponent<UIWidget>();
if (widget != null)
{
// We need three keys to use to store the widget.
// The first is the panel path, which we already have.
// So, we find the atlas name and the depth here.
string atlasName =
ArrangeWidgetDepths.atlasNameFromWidget(widget);
int depth = widget.depth;
// Look up the subhierarchies for these keys.
Dictionary<string, Dictionary<int, List<UIWidget>>>
hierarchyUnderPanel = null;
if (!widgetHierarchy.TryGetValue(parentPanelPath,
out hierarchyUnderPanel))
{
// There's no hierarchy for that panel yet, so create it.
hierarchyUnderPanel =
new Dictionary<string, Dictionary<int, List<UIWidget>>>();
widgetHierarchy[parentPanelPath] = hierarchyUnderPanel;
}
Dictionary<int, List<UIWidget>> hierarchyUnderAtlas = null;
if (!hierarchyUnderPanel.TryGetValue(atlasName,
out hierarchyUnderAtlas))
{
// There's no hierarchy for that atlas yet, so create it.
hierarchyUnderAtlas = new Dictionary<int, List<UIWidget>>();
hierarchyUnderPanel[atlasName] = hierarchyUnderAtlas;
}
List<UIWidget> widgetsAtDepth = null;
// Create a list for this depth if it hasn't been done
// already.
if (!hierarchyUnderAtlas.TryGetValue(depth,
out widgetsAtDepth))
{
widgetsAtDepth = new List<UIWidget>();
hierarchyUnderAtlas[depth] = widgetsAtDepth;
}
widgetsAtDepth.Add(widget);
}
// Go a level deeper.
this.findWidgetsUnderTransformTree(recursionLevel + 1,
maxRecursionLevel, child, parentPanelPath, ref widgetHierarchy);
}
}
static public string atlasNameFromWidget(UIWidget widget)
{
string atlasName = "No atlas";
UIAtlas atlas = null;
if (widget is UISprite)
{
atlas = ((UISprite)widget).atlas;
}
else if (widget is UILabel)
{
UIFont font = ((UILabel)widget).font;
atlas = font.atlas;
}
// Other widget subtypes (as of now) don't have atlases.
if (atlas != null)
{
atlasName = atlas.gameObject.name;
}
return atlasName;
}
public GameObject objectAtTransformPathUnderRoot(string path)
{
GameObject objectAtPath = null;
// The paths used in this class have the root object prepended,
// so peel that off first.
string subPath = path.Substring(this.NGUIRootObject.name.Length);
UnityEngine.Debug.Log("Finding path: " + subPath);
if (subPath.Length < 1)
{
objectAtPath = this.NGUIRootObject;
}
else
{
// Remove the first slash.
subPath = subPath.Substring(1);
Transform transformAtPath =
this.NGUIRootObject.transform.Find(subPath);
if (transformAtPath != null)
{
objectAtPath = transformAtPath.gameObject;
}
}
return objectAtPath;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment