Tasharen Entertainment Forum

Support => NGUI 3 Support => Topic started by: brago on December 04, 2013, 06:31:57 AM

Title: NGUI, 4.3 and new Sortyng Layers
Post by: brago on December 04, 2013, 06:31:57 AM
Hello all,
is there a way to put a NGUI widget over a custom "Sorting Layer" in unity 4.3.x?
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: ArenMook on December 04, 2013, 03:20:31 PM
Sorting layers are a 2D system feature. They are completely unrelated to NGUI. To ensure that NGUI is drawn on top of everything, make sure it's using a separate camera.
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: Clarens on January 07, 2014, 10:59:38 AM
We have to combine SkinnedMeshRenderer with NGUI UIPanels in  Unity 4.3.x. In this case we have to handle the sorting layers in NGUI. Is the following code a correct way to do this?
I used the SortingLayerExposed-Script (https://gist.github.com/nickgravelyn/7460288 (https://gist.github.com/nickgravelyn/7460288)) to set the SortingLayer for the SkinnedMashRenderer. In NGUI I did the following patch:

In UIPanel.cs I added:

  1. 67      public int sortingOrder = 0;
  2. 68      public int sortingLayerID = 0;
  3.  
In UIDrawCall GetDrawCall (int index, Material mat) I added after:

  1. 397       // Create the draw call
  2. 398      UIDrawCall drawCall = go.AddComponent<UIDrawCall>();
  3. 399      drawCall.baseMaterial = mat;
  4. 400      drawCall.renderQueue = UIDrawCall.list.size;
  5. 401      drawCall.panel = this;
  6.  
the lines

  1. 402       drawCall.sortingLayerID = sortingLayerID;
  2. 403           drawCall.sortingOrder = sortingOrder;
  3.  

In UIDrawCall.cs I added:

  1. 43   public int sortingLayerID
  2. 44   {
  3. 45      get
  4. 46      {
  5. 47         return mSortingLayerID;
  6. 48      }
  7. 49      set
  8. 50      {
  9. 51         if (mSortingLayerID != value)
  10. 52         {
  11. 53            mSortingLayerID = value;
  12. 54            
  13. 55            if (mRen != null)
  14. 56            {
  15. 57               mRen.sortingLayerID = mSortingLayerID;
  16. 58               UnityEditor.EditorUtility.SetDirty(gameObject);
  17. 59            }
  18. 60         }
  19. 61      }
  20. 62   }
  21. 63   int mSortingLayerID;
  22. 64
  23. 65   public int sortingOrder
  24. 66   {
  25. 67      get
  26. 68      {
  27. 69         return mSortingOrder;
  28. 70      }
  29. 71      set
  30. 72      {
  31. 73         if (mSortingOrder != value)
  32. 74         {
  33. 75            mSortingOrder = value;
  34. 76            
  35. 77            if (mRen != null)
  36. 78            {
  37. 79               mRen.sortingOrder = mSortingOrder;
  38. 80               UnityEditor.EditorUtility.SetDirty(gameObject);
  39. 81            }
  40. 82         }
  41. 83      }
  42. 84   }
  43. 85   int mSortingOrder;

In public void Set (BetterList<Vector3> verts, BetterList<Vector3> norms, BetterList<Vector4> tans, BetterList<Vector2> uvs, BetterList<Color32> cols) I added after:

  1. 363         if (mRen == null)
  2. 364         {
  3. 365            mRen = gameObject.GetComponent<MeshRenderer>();
  4. 366         }
  5.  
the lines:

  1. 368         if (mRen != null)
  2. 369         {
  3. 370            mRen.sortingLayerID = sortingLayerID;
  4. 371            mRen.sortingOrder = sortingOrder;
  5. 372         }

And after:

  1. 374         if (mRen == null)
  2. 375         {
  3. 376            mRen = gameObject.AddComponent<MeshRenderer>();
  4.  

the lines:

  1. 377            mRen.sortingLayerID = sortingLayerID;
  2. 378            mRen.sortingOrder = sortingOrder;
  3.  

Finally I added in UIPanelInspector.cs after:

  1. 211      if (clipping != UIDrawCall.Clipping.None && !NGUIEditorTools.IsUniform(panel.transform.lossyScale))
  2. 212      {
  3. 213         EditorGUILayout.HelpBox("Clipped panels must have a uniform scale, or clipping won't work properly!", MessageType.Error);
  4. 214        
  5. 215         if (GUILayout.Button("Auto-fix"))
  6. 216         {
  7. 217            NGUIEditorTools.FixUniform(panel.gameObject);
  8. 218         }
  9. 219      }
  10.  

the lines:

  1. 221   int newSortingLayerId = EditorGUILayout.IntField("SOL ID", panel.sortingLayerID);
  2. 222   if (newSortingLayerId != panel.sortingLayerID)
  3. 223    {
  4. 224         panel.sortingLayerID = newSortingLayerId;
  5. 225         UnityEditor.EditorUtility.SetDirty(panel);
  6. 226   }
  7. 227
  8. 228   int newSortingLayerOrder = EditorGUILayout.IntField("SOL Order", panel.sortingOrder);
  9. 229    if (newSortingLayerOrder != panel.sortingOrder)
  10. 230   {
  11. 231         panel.sortingOrder = newSortingLayerOrder;
  12. 232         UnityEditor.EditorUtility.SetDirty(panel);
  13. 233    }
  14.  
  15.  
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: ArenMook on January 08, 2014, 01:40:47 PM
I don't know anything about this sorting feature, so can't say.
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: mudart on February 14, 2014, 08:26:45 PM
Faced with this problem. Found a simple solution.

1. File:UIDrawCall.cs
Added code:
  1.    
  2. public int sortingOrder
  3. {
  4.     get { if (mRenderer != null) return mRenderer.sortingOrder; else return 0; }
  5.     set { if (mRenderer != null && mRenderer.sortingOrder != value) mRenderer.sortingOrder = value; }
  6. }
  7.  


2. File:UIPanel.cs Method:UpdateDrawCalls
/// Update all draw calls associated with the panel

Find a cycle update all drawCalls (NGUI v3.49, #1180 string)
dc.clipping = clipping; - etc

Added code:
  1. if (dc.sortingOrder != depth) dc.sortingOrder = depth;

Now depth parameter is equivalent to the sort order.
Use sortable layers can be added to the panel, and similarly updated.
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: ArenMook on February 15, 2014, 02:08:41 AM
Can you explain your setup, mudart? (UIPanel settings, what you're trying to do, etc?)
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: DEngland on March 05, 2014, 06:32:53 PM
Thanks for the examples mudart. I needed to make a customization similar to this (except with sortingLayerID instead of sortingOrder).

In my case, I have a 2D isometric game where the user can pan and zoom the camera, and I need to have some UI elements which appear to be attached to objects in the world. I am tackling this by letting the game camera render those particular pieces of UI, which works fairly well and avoids the need for positioning/scaling them each frame as the camera is panned/zoomed, while also ensuring there is no positional lag when this happens.

The downside is that NGUI isn't really intended to be rendered by non-UI cameras and does not provide a way to control the sorting layer. With mudart's change to UIDrawCall I also added a public variable to UIPanel that lets my other scripts set the sorting layer, which allows me to properly control where it's drawn in by regular cameras.
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: ArenMook on March 06, 2014, 10:33:07 AM
As a note, 'sort order' is something you can set on the UIPanel in the current Pro version if the Render Q is set to Explicit.
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: coeing on April 23, 2014, 08:36:17 AM
@Clarens: Thanks for sharing your patch, I will try it in our project. We need to sort our NGUI elements with Spine models and some bitmap texts which are rendered by mesh renderers. I used the render queue before but in my opinion the sorting layers are a great way to achieve the sorting in a 2D game. Here is a good answer which explains the difference between the two: http://answers.unity3d.com/questions/671540/render-queue-vs-sorting-layer.html

@ArenMook: I'm sure there are many important features to add to NGUI, but it would be great to include the sorting layer property for UIPanels in one of the next versions :)
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: ArenMook on April 24, 2014, 12:33:03 AM
It has already been included over a month ago. As mentioned, you can specify  it on the panel when the render queue is set to explicit.
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: coeing on April 25, 2014, 11:37:55 AM
It has already been included over a month ago. As mentioned, you can specify  it on the panel when the render queue is set to explicit.

Yes, I saw the sorting order property. What I was talking about is the possibility to define the sorting layer as well.
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: ArenMook on April 26, 2014, 01:23:53 PM
I'll look into it some more when 4.5 is in a more stable beta.
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: Benzino07 on September 04, 2014, 05:16:09 AM
Hi,

I see the mSortingOrder property has been added but I am still unable to get my UIPanels to draw over Unity's Sprite unless the sprite is on the Default Sorting Layer.

I've gone ahead and implemented a similar approach to DEngland by adding a public property to the UIPanel inspector so you can specify the SortingLayer, but was wondering if there is a more official approach so my changes are not lost after an update.

Thanks.
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: ArenMook on September 04, 2014, 10:56:01 AM
Hmm? You can already specify a sorting layer on the panels. It works best if you specify "Explicit" as the Render Queue however, as otherwise NGUI will keep changing draw queues on you.
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: Benzino07 on September 04, 2014, 02:22:53 PM
Hmm? You can already specify a sorting layer on the panels. It works best if you specify "Explicit" as the Render Queue however, as otherwise NGUI will keep changing draw queues on you.

In 3.7.1? I see no option for sorting layer on UIPanel, only depth, Render Q and Sort Order. I've messed around with these, and it makes no difference, any Unity Sprite in a sorting layer that is not default will be drawn over it.
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: ArenMook on September 05, 2014, 09:29:37 AM
Sorting layer is the game object's layer.
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: yuewah on September 14, 2014, 06:33:09 AM
I also want NGUI can officially support Renderer.sortingLayerID
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: bogart on September 24, 2014, 02:51:39 PM
Me too. I'm combining NGUI with some various GUI Labels. I currently have my belly button wrapped around my neck.
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: RDeluxe on October 21, 2014, 08:28:37 PM
Totally agree. Would be really nice to be able to use correctly and easily unity sorting layers.

Sorting layer is the game object's layer.

I think there is a misunderstanding here : layers and sorting layers are not the same thing.
(http://i.imgur.com/3K6cJ8c.png)

I tried to put a uGUI canvas and a NGUI panel (rendered in the same camera, both are rendered correctly) on the same "Layer" (not sorting layer) and changing their order, and I never manage to get the NGUI object to be drawn up front.

(http://i.imgur.com/VxgQjMs.png)

(Parts in red are my sprite being drawn behind)
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: Benzino07 on April 09, 2015, 05:38:23 AM
Yeah, I ended up having to roll my own solution (annoying when you are updating NGUI though) as setting the game layer made no difference. Seems like an important feature to have, but doesn't seem like many people have encountered this.
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: damelin on July 16, 2015, 10:03:00 PM
+1 for supporting Sorting Layers in NGUI objects (panel/widgets)
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: Benzino07 on November 25, 2015, 08:03:47 AM
Is there any update on this? I think this is a very important feature and surprised it's not added yet. Even more so when it can be added relevantly quickly to support it at a Panel level (which I think is all that is required, as you would expect everything on a UIPanel to be drawn on the same layer.

I've edited NGUI's code to support it, but I just know someday I will forget to put the edits back in after an update. For those interested, this is my code to show a dropdown for sorting layers in UIPanel inspector (using the latest NGUI version).

In UIPanelInspector.cs, line 9 add:
  1. using UnityEditorInternal;
  2. using System.Reflection;
  3. using System;
  4.  

In UIPanelInspector.cs, line 458 add:
  1.         GUILayout.BeginHorizontal();
  2.         {
  3.             EditorGUILayout.PrefixLabel("Sorting Layer");
  4.  
  5.             // Get the names of the Sorting layers
  6.             System.Type internalEditorUtilityType = typeof(InternalEditorUtility);
  7.             PropertyInfo sortingLayersProperty = internalEditorUtilityType.GetProperty("sortingLayerNames", BindingFlags.Static | BindingFlags.NonPublic);
  8.             string[] names = (string[])sortingLayersProperty.GetValue(null, new object[0]);
  9.  
  10.             int index = 0;
  11.             if (!String.IsNullOrEmpty(mPanel.mSortingLayer))
  12.             {
  13.                 for (int i = 0; i < names.Length; i++)
  14.                 {
  15.                     if (mPanel.mSortingLayer == names[i])
  16.                     {
  17.                         index = i;
  18.                         break;
  19.                     }
  20.                 }
  21.             }
  22.  
  23.             // Get the selected index and update the panel sorting layer if it has changed
  24.             int selectedIndex = EditorGUILayout.Popup(index, names);
  25.             if (index != selectedIndex)
  26.             {
  27.                 mPanel.mSortingLayer = names[selectedIndex];
  28.                 EditorUtility.SetDirty(mPanel);
  29.             }
  30.         }
  31.         GUILayout.EndHorizontal();
  32.  

In UIDrawCall.cs, line 130 add:
  1.     public string sortingLayerName
  2.     {
  3.         get { return (mRenderer != null) ? mRenderer.sortingLayerName : ""; }
  4.         set { if (mRenderer != null && mRenderer.sortingLayerName != value) mRenderer.sortingLayerName = value; }
  5.     }
  6.  

In UIPanel.cs, line 97 add:
  1.     /// <summary>
  2.     /// The sorting layer for this panel, used to work with Unity 2D system
  3.     /// </summary>
  4.     public string mSortingLayer = "";
  5.  

In UIPanel.cs, line 263 add (this could potentially be optimised?):
  1. dc.sortingLayerName = mSortingLayer;
  2.  

Now you should have a dropdown for your UIPanels to select the sorting layer it should be drawn on.
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: ArenMook on November 25, 2015, 06:06:54 PM
Thanks! I've added it to my repository, so you will find it in the next version.
Title: Re: NGUI, 4.3 and new Sortyng Layers
Post by: Benzino07 on November 26, 2015, 04:37:32 AM
Oh cool! Glad I could help :)