Tasharen Entertainment Forum

Support => NGUI 3 Support => Topic started by: Nicki on October 06, 2013, 07:54:34 AM

Title: Nicki's Depth Management Tool
Post by: Nicki on October 06, 2013, 07:54:34 AM
So, I've gotten to a point where my tool is basically finished, but there's bound to be small tweaks to do here and there.

You open it by going into NGUI->Open->Nicki's Draw Call Toolbox.

This is how it looks:
(http://i.imgur.com/gaiJXnv.png)

You can set the depth on Panels and groups of widgets that have the same depth.  If you need to seperate an individual widget, you should expand the widget thingie and click the individual widget to go to it in the inspector, and change that there. I ran into som small issues with doing that directly in the tool easily, so that's not in yet.

The colors are set by Panel. That means that all that have the same colors are drawn by the same panel - so if you see something with the same color and same material in multiple places, that could probably be collapsed by moving the depths closer together.

When the numbers are changed, two buttons appear "Apply depth, Reset depth". Doing it instantly while typing caused too many problems with depths with more than 1 digit.

You install it by just putting the attached script into a Editor folder (doesn't matter where). I've decoupled it as much as possible from the rest of the NGUI core, so I don't stumble on side effects (DrawHeader set the GUI.backgroundColor to white, for instance), but I do still use the NGUIEditorTools.BeginContents/EndContents and NGUITools.GetHierarchy.

When you fold a draw call together it works as it does in the individual panels, and it does overlap with those - so if you fold it in the panel, or in my tool the others fold as well.

In this tool, when a draw call is folded, it turns bright red, to indicate that this should only be a temporary state and you should fold it back out again - they will stay folded together until you unfold them, so if you think you have missing references, that might be it.

Anyways, hope you can use it.

Updated link 15th jun 2014 http://nickithansen.dk/stuff/drawcalltoolbox.unitypackage (Unity 4.5+, NGUI 3.6.4+, no guarantees below that)
Title: Re: Nicki's Depth Management Tool
Post by: ArenMook on October 06, 2013, 10:29:07 PM
The folding of draw calls no longer hides the draw call in 3.0.2 -- I assume you noticed the newly added explicit checkbox on the matter, and the fact that it doesn't save the state from edit mode to play mode anymore in order to avoid confusion.

Aside from that, might be a handy tool if it's cleaned up a bit visually.
Title: Re: Nicki's Depth Management Tool
Post by: Nicki on October 07, 2013, 01:23:34 AM
I did not! :) I made it with 3.0.1 and only added the panel interaction and 3.0.2 this weekend, so I completely missed that part.

I think it is handy. My main reason for making it, is to be able to jump back and forth to panels and widgets without leaving the window, like it necessarily does on the individual UIPanels. The modifying of depths is actually just extra that I built on top.

It's in a bit of a rough shape, buttons placed a little weirdly here and there, which I intend to clean up, but otherwise, feel free to take it a modify, if you want to put something like it into NGUI.

That goes for the rest of y'all too - feel free to take it and modify for your own needs.
Title: Re: Nicki's Depth Management Tool
Post by: yuewah on October 07, 2013, 08:31:32 AM
Is it possible to not using UIPanel to group widgets ( UIButton A ) that is on top of another group of widgets  ( UIButton B ) in 3.0.2 ?
e.g.
UIButton A
|-Background Sprite ( depth = -1 )
|-Icon Sprite ( depth = 0 )
|-Label ( depth = 1 )

UIButton B
|-Background Sprite ( depth = -1 )
|-Icon Sprite ( depth = 0 )
|-Label ( depth = 1 )

In 2.x, I can change z of UIButton to easily move back and front, however, in 3.x, using UIPanel seems too much overhead.
Title: Re: Nicki's Depth Management Tool
Post by: ArenMook on October 08, 2013, 02:17:13 AM
Moving Z has no effect in relation to depth in 2.X. It only works if you have a UIPanel attached to your "UIButton" objects. Not sure why you would want to have a UIPanel there... but in any case, in 3.0.2 you can just specify a depth on your panels, exactly the same way you can specify it on widgets. Panel depth is more important than widget depth. All widgets are sorted by panel depth first, and only then by widget depth.
Title: Re: Nicki's Depth Management Tool
Post by: yuewah on October 08, 2013, 10:08:27 AM
In my experience, UIPanel is slow. In 3.0, z won't work, only UIPanel and UIWidget contains depth. And UIWidgetContainer is used to hold more than one widget inside, can it also have depth like UIPanel. Therefore, Button A and Button B can change the draw order using UIWidgetContainer depth.

Button A ( UIWidgetContainer, depth = 0 )
|-Background (UISprite, depth = -1)
|-Icon ( UISprite, depth = 0 )
|-Label ( UILabel, depth = 1 )

Button B ( UIWidgetContainer, depth = 1 )
|-Background (UISprite, depth = -1)
|-Icon ( UISprite, depth = 0 )
|-Label ( UILabel, depth = 1 )
Title: Re: Nicki's Depth Management Tool
Post by: ArenMook on October 08, 2013, 12:49:17 PM
Widget container doesn't have depth. It's a helper script that's used to make it possible to move a group of widgets at once. Depth is specified either on widgets, or on panels.

Z has no effect in 3.0.
Title: Re: Nicki's Depth Management Tool
Post by: Tiktaalik on October 09, 2013, 03:39:12 PM
Does the new depth scheme change anything with regard to the interaction between UIPanels and 3D Objects in the world?

If you wanted to have some 3D object infront of a UIPanel would you simply make the 3D Object have a more negative z in its transform?
Title: Re: Nicki's Depth Management Tool
Post by: Tiktaalik on October 09, 2013, 04:17:44 PM
Does the new depth scheme change anything with regard to the interaction between UIPanels and 3D Objects in the world?

If you wanted to have some 3D object infront of a UIPanel would you simply make the 3D Object have a more negative z in its transform?

Answer is right here:
Quote
- NEW: UICamera now has "world" and "UI" event types that affect how raycasts are processed.

Looking at the UICamera.cs, it looks like I just have to switch my camera type to world to get my world stuff to work again.
Title: Re: Nicki's Depth Management Tool
Post by: 7realm on October 09, 2013, 10:33:53 PM
I added this tool to my project, and I got a lot of exceptions when I try expand widgets at one of drawcalls.

ArgumentOutOfRangeException: startIndex + count > this.length
Parameter name: count
System.String.Remove (Int32 startIndex, Int32 count) (at /Applications/buildAgent/work/b59ae78cff80e584/mcs/class/corlib/System/String.cs:1747)
UIDrawCallOverview.OnGUI () (at Assets/_Scripts/Editor/UIDrawCallOverview.cs:240)
System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Applications/buildAgent/work/b59ae78cff80e584/mcs/class/corlib/System.Reflection/MonoMethod.cs:222)

The problem can occur, because I have UIPanel and UISprite on one object. Is that bad practice in NGUI 3.x?
Title: Re: Nicki's Depth Management Tool
Post by: Nicki on October 10, 2013, 12:53:37 AM
7realm, I haven't seen that bug in mine. Be sure to use the newest Unity and the newest NGUI as well.

I have an updated version of the tool, where it's more in line with how the UIPanel does the things and with some code cleanup, bit I can only post that once I get home later today.

Sprites directly on the same panel should be just fine, afaik.
Title: Re: Nicki's Depth Management Tool
Post by: ChrisPruett on October 10, 2013, 10:11:15 AM
This is an exceedingly useful thread.

We are experimenting with NGUI 3 for a new project we're working on.  Like some other folks in this thread, the new depth workflow is completely intractable for existing projects because we have a very large number of panels that contain a very large number of widgets and are instantiated in unpredictable order (think pop-up dialogs that may themselves spawn other pop-up dialogs that are based on the same prefab, etc).  But, on those projects we also had a lot of problems with depth sorting, so I'm happy to give the new stuff a shot for new projects.

Two questions related to the new sorting approach:

- The panel depth parameter doesn't do what I expected it to do.  I expected this value to serve as something of a depth offset of all children widgets, either by changing their depth values on the fly or by simply sorting the display list by panel depth first and widget depth second.  I expected to be able to sort panels as a single unit in front or behind of other panels by changing this value.  That doesn't seem to be how it works, though.  If I have two overlapping panels with widgets set to the same depth parameter, I get the same results (i.e. sorting of widgets at global scope rather than panel scope) regardless of the depth of the panels.  I can't pull a panel forward by increasing its depth value.  What am I missing?  What is the indented use pattern for this value?

- The new system seems to be splitting the widgets into draw calls much less efficiently than it should.  If my understanding is correct, the idea is a draw call per depth bucket per material in order to guarantee correct overdraw behavior.  But I am seeing widgets that do not overlap anything, that all have the same depth, that are all within the same panel and share the same material being split into multiple draw calls.  This is a panel that contains multiple materials (a sprite atlas and a font), but even when there is no obvious overlap, single widgets are split out from the draw call for their depth group and drawn later for reasons I don't understand.  What's the best way to debug this sort of thing?  My UI has gone from 2 - 4 draw calls under NGUI 2 to around 20 under NGUI 3, even after I've gone through and sorted all widgets into three depth buckets and corrected for widgets of different materials overlapping.

Thanks.
Title: Re: Nicki's Depth Management Tool
Post by: ChrisPruett on October 10, 2013, 11:06:41 AM
OK, so, to answer my own question (the second one):

Superfluous draw calls are generated in panels that have multiple materials because UIWidgets are sorted only by panel and then by depth, but never by material.  UIPanel.Fill() walks through all of the widgets (NOT the panels) and maintains a record of the last draw call used as it goes.  If it reaches a widget that can't be placed in the last draw call (different material, different panel, etc), it will split off a new draw call for that widget. 

The problem with this is that the order in which UIWidgets exist in the UIWidget.list is dependent on the order that they are instantiated (well, actually, enabled).  They are sorted by panel and then by depth, but within those buckets the order they appear in is undefined.  So if you have widget A, B, and C, all of the same panel and of the same depth, you'll get three draw calls if A and C share a material but B is something different.  Since they are all at the same depth it would be better to draw A and C in one pass and B in a different pass.

I modded UIWidget.CompareFunc as follows to sub-sort widgets of the same depth and panel by material.  I am now down to 8 draw calls, sorted by depth bucket and material as I would expect, from 22 previously. 

  1. static public int CompareFunc (UIWidget left, UIWidget right)
  2. {
  3.         int val = UIPanel.CompareFunc(left.mPanel, right.mPanel);
  4.  
  5.         if (val == 0)
  6.         {
  7.                 if (left.mDepth < right.mDepth) val = -1;
  8.                 if (left.mDepth > right.mDepth) val = 1;
  9.                 if (val == 0)
  10.                 {
  11.                         Material leftMat = left.material;
  12.                         Material rightMat = right.material;
  13.                        
  14.                         if (leftMat != rightMat)
  15.                         {
  16.                                 if (leftMat != null && rightMat != null)
  17.                                 {
  18.                                         val = leftMat.GetInstanceID() < rightMat.GetInstanceID() ? -1 : 1;
  19.                                 }
  20.                                 else
  21.                                 {
  22.                                         val = leftMat == null ? -1 : 1;
  23.                                 }
  24.                         }
  25.                 }
  26.         }
  27.         return val;
  28. }

This hasn't been throughly tested but does what I expected it to do (fewer draw calls with more verts each) and didn't break my scene. 

Anything wrong with this approach?

Also, I now see what the panel depth value does (sorts groups of widgets by panel depth first), but it doesn't actually correct the problem of widgets in overlapping panels being occluded by panels of higher depth.  Still working on why that is.
Title: Re: Nicki's Depth Management Tool
Post by: ChrisPruett on October 10, 2013, 12:45:11 PM
Hello again,

Looks like the core problem I am seeing with sorting is related to UITexture's shared material renderQueue.  Sprites and labels appear to use 30000 as the base render queue (to which the index of the draw call is added to find the actual render queue), but my UITextures have a base render queue of 20000.  So the order of the panels and widgets are correct, but the actual order that Unity draws them is not because the base draw queue is off.

The queue is off because we're using Unity's built-in Unlit/Texture shader for this material, which selects its render queue as Geometry.

So, problem solved: we should be using shaders that select the Transparent queue, as most of the NGUI shaders do. 

It might be worth throwing a warning when a shader that doesn't comply to this policy (i.e. has a material with a renderQueue lower than 30000) since sorting is now entirely dependent on the assumption that all materials are operating with the same base queue.

Cheers,
Chris
Title: Re: Nicki's Depth Management Tool
Post by: ChrisPruett on October 10, 2013, 12:58:07 PM
Oh, I see.  UITexture actually selects Unlit/Texture if there's no other material assigned.  In light of the new sorting mechanism, that seems like a bug (or the final renderQueue calculation needs to be based on something other than the shader).

4X POST POWERUP
Title: Re: Nicki's Depth Management Tool
Post by: Nicki on October 11, 2013, 12:59:34 AM
I actually stumbled on just that yesterday as well. If the UITexture is using Unlit/Texture it's lower in the render queue in shader, which makes it be under the other stuff if it's at the same z. Hilariously, if you move the Z position so it's in front, it will go in front of the other 2d. Change it to Transparent/Colored for a quick fix.
Title: Re: Nicki's Depth Management Tool
Post by: ArenMook on October 11, 2013, 06:54:19 AM
Could have sworn I already changed UITexture to use Unlit/Transparent Colored... Well, open up UITexture and change it on line 60.
Title: Re: Nicki's Depth Management Tool
Post by: ArenMook on October 11, 2013, 07:16:46 AM
@Chris: Your idea of adding a material ID sorting clause in there is actually a nice one. I'll add it to the NGUI's core.
Title: Re: Nicki's Depth Management Tool
Post by: Miau on October 11, 2013, 08:41:28 AM
@Nicki
Thanks for providing this tool. It really IS handy!
Title: Re: Nicki's Depth Management Tool
Post by: ChrisPruett on October 11, 2013, 09:10:27 AM
@ArenMook Cheers!

@Nicki Thanks for the tool from me as well.  I modded to watch the actual renderQueue value while debugging the UITexture thing.  Very useful!
Title: Re: Nicki's Depth Management Tool
Post by: Nicki on October 11, 2013, 09:14:12 AM
I actually have a significantly improved version that I'm using now. It's more akin to how UIPanel does things now. See the attachment.

If you guys have any improvements, please suggest or post your modifications. :)
Title: Re: Nicki's Depth Management Tool
Post by: Miau on October 11, 2013, 01:32:06 PM
I get some compilation errors with the new version:

Assets/Editor/UIDrawCallOverview.cs(88,56): error CS1061: Type `UIDrawCall' does not contain a definition for `baseMaterial' and no extension method `baseMaterial' of type `UIDrawCall' could be found (are you missing a using directive or an assembly reference?)

Assets/Editor/UIDrawCallOverview.cs(88,29): error CS1502: The best overloaded method match for `UnityEditor.EditorGUILayout.ObjectField(string, UnityEngine.Object,
System.Type, params UnityEngine.GUILayoutOption[])' has some invalid arguments

Assets/Editor/UIDrawCallOverview.cs(88,29): error CS1503: Argument `#2' cannot convert `object' expression to type `UnityEngine.Object'
Title: Re: Nicki's Depth Management Tool
Post by: Nicki on October 11, 2013, 03:18:57 PM
Ah, you need the newest NGUI I think - wait until the next update comes out, unless you have pro.
Title: Re: Nicki's Depth Management Tool
Post by: ikuniojp on November 14, 2013, 09:15:09 PM
Nope,
No joy here too.
No pro
We didn't know there's a Pro version
Would have got that.
Title: Re: Nicki's Depth Management Tool
Post by: Nicki on November 15, 2013, 05:12:47 AM
Doesn't it work in 3.0.5 for you?
Title: Re: Nicki's Depth Management Tool
Post by: ikuniojp on November 17, 2013, 08:39:14 PM
No, I get the same error message as Miau got :(
Title: Re: Nicki's Depth Management Tool
Post by: Nicki on November 19, 2013, 04:40:04 AM
OK I think I'll update my project to the newest NGUI version now and see if I get the same error, then I can fix it. :)
Title: Re: Nicki's Depth Management Tool
Post by: ikuniojp on November 19, 2013, 09:04:50 PM
Zip-a-Dee-Doo-Dah  ;D
Title: Re: Nicki's Depth Management Tool
Post by: Nicki on November 20, 2013, 03:59:13 AM
I'm using it in 3.0.6 right now, and I'm not seeing this problem..

Are you using the new one from http://www.tasharen.com/forum/index.php?action=dlattach;topic=6166.0;attach=2804 ?
Title: Re: Nicki's Depth Management Tool
Post by: ikuniojp on November 21, 2013, 09:05:18 PM
I'm using it in 3.0.6 right now, and I'm not seeing this problem..

Are you using the new one from http://www.tasharen.com/forum/index.php?action=dlattach;topic=6166.0;attach=2804 ?

Is 3.0.6 out for standard?
I was going to get a pro license,
was waiting for email reply but got none.
Weary to update now :(
Title: Re: Nicki's Depth Management Tool
Post by: ArenMook on November 22, 2013, 03:26:01 AM
3.0.6 is still in the Pro repository. What email reply are you waiting on, where did you send it, and from which email address?
Title: Re: Nicki's Depth Management Tool
Post by: ikuniojp on November 25, 2013, 01:40:41 AM
To support@tasharen.com
Asking about payment option.
Title: Re: Nicki's Depth Management Tool
Post by: ArenMook on November 25, 2013, 03:26:36 AM
I haven't received anything. Can you re-send?
Title: Re: Nicki's Depth Management Tool
Post by: ikuniojp on November 27, 2013, 06:50:19 AM
I'm using it in 3.0.6 right now, and I'm not seeing this problem..

Are you using the new one from http://www.tasharen.com/forum/index.php?action=dlattach;topic=6166.0;attach=2804 ?

Work like a charm in 3.0.6! You're a LIFE SAVER! Genius  ;D
Thanks!
Title: Re: Nicki's Depth Management Tool
Post by: ikuniojp on January 05, 2014, 10:39:00 PM
not working in 3.0.8 f5?
Title: Re: Nicki's Depth Management Tool
Post by: Nicki on January 07, 2014, 12:19:32 AM
No it isn't right now, since some of the dependencies have changed. I'll upload a new version shortly.
Title: Re: Nicki's Depth Management Tool
Post by: lacusclyne on February 05, 2014, 07:31:55 AM
This is a pretty extension, I'm waiting for new version for the lastest NGUI. 8)
Title: Re: Nicki's Depth Management Tool
Post by: Nicki on February 06, 2014, 03:31:00 AM
So, when I say "shortly" I evidently mean "1 month from now". Sorry, I forgot to post this when it was updated.

It still needs some code cleanup, but it works. :)
Title: Re: Nicki's Depth Management Tool
Post by: lacusclyne on February 06, 2014, 05:29:04 AM
So, when I say "shortly" I evidently mean "1 month from now". Sorry, I forgot to post this when it was updated.

It still needs some code cleanup, but it works. :)

Fantastic, I can update NGUI to lastest version now, thx for ur work :)
Title: Re: Nicki's Depth Management Tool
Post by: DarkMagicCK on March 21, 2014, 01:38:05 AM
If a sprite is a component of it's UIPanel's gameobject (UIWidget and UIPanel is the same object), NGUITools.GetHierarchy(depths[d][iW].cachedGameObject).Remove will cause an outofindex error. Though it's not good to put UIPanel and UISprite on same object, you can add a length check for this string.
Title: Re: Nicki's Depth Management Tool
Post by: Nicki on March 26, 2014, 05:24:59 AM
Duly noted. I suppose it's about time to update this again, in any case. ;)
Title: Re: Nicki's Depth Management Tool
Post by: honeal on June 11, 2014, 03:22:52 PM
Hey Nicki, any word on an updated version of your tool?
Title: Re: Nicki's Depth Management Tool
Post by: Nicki on June 12, 2014, 03:32:58 AM
Eek, I've been busy with other things. I'll take a stab at it this weekend. Until then there's a similar tool in NGUI in NGUI->Open->Draw Call Tool which shows some of the same information.
Title: Re: Nicki's Depth Management Tool
Post by: Nicki on June 15, 2014, 02:55:54 PM
I've made some updates to the tool and renamed it Nicki's Draw Call Toolbox since it's largely some tools to batch-set depth values.

Here's the download link: http://nickithansen.dk/stuff/drawcalltoolbox.unitypackage

I made it with Unity 4.5 and NGUI 3.6.4, so there's no guaranteee it will work on less than that. When I get around to it, I'll push it to github or something, so it's a little easier to get updates.

If you'd like to help out, I could use a little assistance getting the colors right. There's not real upper limit to the number of colors used, other than they should be clearly distinguishable - look in the top of the UIDrawCallToolbox to see the ones used now.

I've also included a OnGUIWrapper file, which makes OnGUI setup a little more sane than GUI.Begin... GUI.End in weird places, so you can instead do clever things like this

  1. using (new GUIHorizontal())
  2.                 {
  3.                         using (new GUIVertical())
  4.                         {
  5.                                 //column of stuff      
  6.                         }
  7.                         using (new GUIVertical())
  8.                         {
  9.                                 //other column of stuff
  10.                         }
  11.                 }      
  12.  

instead of

  1.                 GUILayout.BeginHorizontal();
  2.                 GUILayout.BeginVertical();
  3.                 //column
  4.                 GUILayout.EndVertical();
  5.                 GUILayout.BeginVertical();
  6.                 //column
  7.                 GUILayout.EndVertical();
  8.                 GUILayout.EndHorizontal();

Essentially wrapping the standard OnGUI things with a nicer IDisposable structure, so you can have some sanity debugging your OnGUI code.

I'll put this link in the top post too.
Title: Re: Nicki's Depth Management Tool
Post by: thienhaflash on July 22, 2014, 10:37:21 PM
Hello everyone,

Sorry to bring this up, I've write an NGUIDepth extension that support drag and drop to adjusting the depth, very intuitive and easy, have a look and tell me if there are something you want me to improve.

  1. https://www.assetstore.unity3d.com/en/#!/content/19845

thanks a lot.