Category Archives: NGUI

Custom Inspector: Mixing custom drawer and default property drawers

I’ve been playing around with ScriptableObjects and using them to define parameters for my Dialog display gameobject.  In previous instances, I’d just use constant strings and pass them to the function that creates and displays the dialog.  After reading about ScriptableObjects, I decided to give them a shot to build strings for the dialogs.

Everything was great, except for the inspector displaying long strings.  They just get truncated of the right side of the display.  The behavior exhibited by the NGUI UILabel inspector is much better, as any text to long to be displayed in the inspector is wrapped and the field is extended vertically.

I found the NGUI code in UILabelInspector that handles the displaying of strings across multiple lines, and took a copy to use in my own inspector.  Then I realized, with a custom inspector I have to display all the properties myself, and I didn’t want to (a) write a custom display for each property type, and (b) remember to extend the inspector anytime I modified my ScriptableObject class.

The second problem was solved by iterating over the SerializedProperties contained in the SerializedObject, while the first problem was solved by calling EditorGui.PropertyField on SerializedProperties I didn’t want to display myself.

I then added an exception for the ‘Script’ property, to make it non-editable.

This resulted in the code below:

public override void OnInspectorGUI()
{
	serializedObject.Update();
	SerializedProperty sp = serializedObject.GetIterator();
	if (!sp.NextVisible(true))
		sp = null;
	while (sp!=null)
	{
		if (sp.type == "string")
			DrawMultiLineString(sp.name);
		else
		{
			Rect position = EditorGUILayout.GetControlRect(GUILayout.Height(EditorGUI.GetPropertyHeight(sp)));
			if (sp.name == "m_Script")
			{
				EditorGUI.BeginDisabledGroup(true);
				EditorGUI.PropertyField(position, sp, new GUIContent(sp.displayName), true);
				EditorGUI.EndDisabledGroup();
			}
			else
				EditorGUI.PropertyField(position, sp, new GUIContent(sp.displayName), true);
		}
		if (!sp.NextVisible(true))
			sp = null;
	}
	serializedObject.ApplyModifiedProperties();
}

The call to DrawMultiLineString uses code directly from NGUI’s UILabelInspector, and is not available unless you have NGUI for Unity.

Non-breaking space in Unity3D/NGUI

I was messing with some text line wrapping an an app today, and needed to stop NGUI inserting a line break between a number and a label in a long string.  Using the escape sequence ‘\u00A0’ did the trick.

return category + "\u00A0#" + indexInCategory;

Now the last word in the string category and the number preceded with a # stay on the same line!

Note: I read that pressing ALT-Space on the Mac will insert this character.  It may do that, but MonoDevelop/NGUI don’t seem to care.  The escape literal worked, the ALT-Space just acted like a regular space.

Note: To insert a non-breaking space in a XML document without using Document Entities, use the following:  

UIButton and isEnabled color change

As part of my hidden UIWidget stuff, the widget has a few buttons on it that I set the isEnabled flag to false when appropriate.  This had the effect of the button changing over time to a dark gray color when it appears on screen.

I didn’t want the color to transition, I wanted it to start gray when it appeared.  So I added the following lines:

float oldDur = button.duration;
button.duration = 0;
button.isEnabled = false;
button.duration = oldDur;

That did the trick – button appeared gray and didn’t transition.

NGUI and inactive widgets in Unity3D

I have a UITexture that I resize before making it visible in the game view.  The problem I ran into is that when you resize a UIWidget and that widget is currently inactive, then NGUI will not force an update to any collider you have attached to it.

I got around this by adding a call to ResizeCollider() after I enabled the UIWidget.  I’ll keep watching to see if there are other properties not being updated while the UIWidget is inactive.

NGUI EventDelegate

I have a button whose function changes depending on which panel is currently being displayed.  When switching panels, this button stays on screen (think a NavBar).  I ran into this unexpected behavior today, that slowed me down.

If you change the contents of an EventDelegate list during a method called from that  EventDelegate list then its probable that your new method will get called right way when control is passed back to the Execute method of EventDelegate.  This looked like the OnClick method of a UIButton was not waiting for a release, so I went down that rabbit hole for a bit.

I ended up adding a short delay to the code that switches the current OnClick action to the new OnClick action, which solved the problem.

	button.onClick.Clear();
	//delay this by a frame, so it happens outside the EventDelegate processing
	callAfterDelay(0.01f,()=>{
		button.onClick.Add(action);
	});