Sort Layer Renderer Extension

转载:http://forum.unity3d.com/threads/sort-layer-renderer-extension.219799/


Hello Guys,
As we know since Unity 4.3, Unity have a sort layer manager. This feature is exposed and fully manageable from Edit->Project Settings->Tags and Layers.
Every Renderer have some exposed variables to deal with the sort layer but only the Sprite Renderer has it exposed on the inspector.
So I find a way to do an extension to Unity Renderers, adding sort layer options as in Sprite Renderer to every Renderer. (so you can use it at TrailRenderer, LineRenderer, ParticleLegacyRenderer and etc...)
I did it yesterday so I`m not sure, at this moment, if it really works as it should work in all cases. The code is also a little dirt (sorry for that).
I also added a include child toggle option because well... it`s quite useful.

I tried to do the same in Shuriken Particle System but I`m new in this Custom Editor thing and I`m not able to change Shuriken Particle System without destroy that charming look from Shuriken Particle System Inspector.

  1.  
  2. //  SortLayerRendererExtension.cs
  3. //   Author:
  4. //       Yves J. Albuquerque <yves.albuquerque@gmail.com>
  5. //  Last Update:
  6. //       27-12-2013
  7. //Put this file into a folder named Editor.
  8. //Based on Nick`s code at https://gist.github.com/nickgravelyn/7460288 and Ivan Murashko solution at http://forum.unity3d.com/threads/210683-List-of-sorting-layers?p=1432958&viewfull=1#post1432958 aput by Guavaman at http://answers.unity3d.com/questions/585108/how-do-you-access-sorting-layers-via-scripting.html
  9. using System;
  10. using UnityEngine;
  11. using UnityEditor;
  12. using UnityEditorInternal;
  13. using System. Reflection;
  14.  
  15. [CanEditMultipleObjects ( ) ]
  16. [CustomEditor ( typeof ( Renderer ), true ) ]
  17. public  class SortLayerRendererExtension  :  Editor
  18. {
  19.      Renderer renderer;
  20.      Renderer [ ] childsRenderer;
  21.      string [ ] sortingLayerNames;
  22.  
  23.      int selectedOption;
  24.      bool applyToChild  =  false;
  25.      bool applyToChildOldValue  =  false;
  26.  
  27.      void  OnEnable ( )
  28.      {
  29.         sortingLayerNames  = GetSortingLayerNames ( );
  30.         renderer  =  ( target  as  Renderer ). gameObject. renderer;
  31.          if  ( ( target  as  Renderer ). transform. childCount  >  1 )
  32.             childsRenderer  =  ( target  as SortingLayerExposed ). transform. GetComponentsInChildren <Renderer > ( );
  33.  
  34.          for  ( int i  =  0; i <sortingLayerNames. Length;i ++ )
  35.          {
  36.              if  (sortingLayerNames [i ]  == renderer. sortingLayerName )
  37.                 selectedOption  = i;
  38.          }
  39.      }
  40.  
  41.      public  override  void  OnInspectorGUI ( )
  42.      {
  43.          DrawDefaultInspector ( );
  44.          if  ( !renderer )
  45.          {
  46.              return;
  47.          }
  48.  
  49.          EditorGUILayout. LabelField ( "\n" );
  50.  
  51.         selectedOption  =  EditorGUILayout. Popup ( "Sorting Layer", selectedOption, sortingLayerNames );
  52.          if  (sortingLayerNames [selectedOption ]  != renderer. sortingLayerName )
  53.          {
  54.              Undo. RecordObject (renderer,  "Sorting Layer" );
  55.              if  ( !applyToChild )
  56.                 renderer. sortingLayerName  = sortingLayerNames [selectedOption ];
  57.              else
  58.              {
  59.                  for  ( int i  =  0; i <childsRenderer. Length;i ++ )
  60.                  {
  61.                     childsRenderer [i ]. sortingLayerName  = sortingLayerNames [selectedOption ];
  62.                  }
  63.              }
  64.              EditorUtility. SetDirty (renderer );
  65.          }
  66.  
  67.          int newSortingLayerOrder  =  EditorGUILayout. IntField ( "Order in Layer", renderer. sortingOrder );
  68.          if  (newSortingLayerOrder  != renderer. sortingOrder )
  69.          {
  70.              Undo. RecordObject (renderer,  "Edit Sorting Order" );
  71.             renderer. sortingOrder  = newSortingLayerOrder;
  72.              EditorUtility. SetDirty (renderer );
  73.          }
  74.  
  75.         applyToChild  =  EditorGUILayout. ToggleLeft ( "Apply to Childs", applyToChild );
  76.          if  (applyToChild  != applyToChildOldValue )
  77.          {
  78.              for  ( int i  =  0; i <childsRenderer. Length;i ++ )
  79.              {
  80.                 childsRenderer [i ]. sortingLayerName  = sortingLayerNames [selectedOption ];
  81.              }
  82.              Undo. RecordObject (renderer,  "Apply Sort Mode To Child" );
  83.             applyToChildOldValue  = applyToChild;
  84.              EditorUtility. SetDirty (renderer );
  85.          }
  86.      }
  87.  
  88.      // Get the sorting layer names
  89.      public  string [ ] GetSortingLayerNames ( )
  90.      {
  91.         Type internalEditorUtilityType  =  typeof (InternalEditorUtility );
  92.         PropertyInfo sortingLayersProperty  = internalEditorUtilityType. GetProperty ( "sortingLayerNames", BindingFlags. Static  | BindingFlags. NonPublic );
  93.          return  ( string [ ] )sortingLayersProperty. GetValue ( nullnew  object [ 0 ] );
  94.      }
  95.    
  96.      // Get the unique sorting layer IDs -- tossed this in for good measure
  97.      public  int [ ] GetSortingLayerUniqueIDs ( )
  98.      {
  99.         Type internalEditorUtilityType  =  typeof (InternalEditorUtility );
  100.         PropertyInfo sortingLayerUniqueIDsProperty  = internalEditorUtilityType. GetProperty ( "sortingLayerUniqueIDs", BindingFlags. Static  | BindingFlags. NonPublic );
  101.          return  ( int [ ] )sortingLayerUniqueIDsProperty. GetValue ( nullnew  object [ 0 ] );
  102.      }
  103. }
  104.  
EDIT:
Still wanted some help here but I did a little trick. Not the wanted solution but worked until someone comes with an integrated solution for Shuriken.

This is the Editor code

  1. //  RendererLayerEditor.cs
  2. //   Author:
  3. //       Yves J. Albuquerque <yves.albuquerque@gmail.com>
  4. //  Last Update:
  5. //       28-12-2013
  6. //Put this file into a folder named Editor.
  7. //Based on Nick`s code at https://gist.github.com/nickgravelyn/7460288 and Ivan Murashko solution at http://forum.unity3d.com/threads/210683-List-of-sorting-layers?p=1432958&viewfull=1#post1432958 aput by Guavaman at http://answers.unity3d.com/questions/585108/how-do-you-access-sorting-layers-via-scripting.html
  8. using System;
  9. using UnityEngine;
  10. using UnityEditor;
  11. using UnityEditorInternal;
  12. using System. Reflection;
  13.  
  14. [CanEditMultipleObjects ( ) ]
  15. [CustomEditor ( typeof (RendererLayer ) ) ]
  16. public  class RendererLayerEditor  :  Editor
  17. {
  18.      ParticleSystem [ ] l_particleSystems;  //reference to our particle systems
  19.      Renderer [ ] l_renderers; //reference to our renderers
  20.  
  21.      string [ ] sortingLayerNames; //we load here our Layer names to be displayed at the popup GUI
  22.      int popupMenuIndex; //The selected GUI popup Index
  23.      bool applyToChild  =  false; //Turn on/off if the effect will be extended to all renderers in child transforms
  24.      bool applyToChildOldValue  =  false; //Used this old value to detect changes in applyToChild boolean
  25.  
  26.      /// <summary>
  27.      /// Raises the enable event. We use it to set some references and do some initialization. I don`t figured out how to make a variable persistent in Unity Editor yet so most of the codes here can useless
  28.      /// </summary>
  29.      void  OnEnable ( )
  30.      {
  31.         sortingLayerNames  = GetSortingLayerNames ( )//First we load the name of our layers
  32.         l_particleSystems  =  ( target  as RendererLayer ). gameObject. GetComponentsInChildren <ParticleSystem > ( ); //Then we load our ParticleSystems
  33.         l_renderers  =  new  Renderer [l_particleSystems. Length ]; //and Initialize our renderers array with the right size
  34.  
  35.          for  ( int i  =  0; i <l_particleSystems. Length;i ++ )  //here we loads all renderers to our renderersarray
  36.          {
  37.             l_renderers [i ]  = l_particleSystems [i ]. renderer;
  38.          }
  39.  
  40.          for  ( int i  =  0; i <sortingLayerNames. Length;i ++ )  //here we initialize our popupMenuIndex with the current Sort Layer Name
  41.          {
  42.              if  (sortingLayerNames [i ]  == l_particleSystems [ 0 ]. renderer. sortingLayerName )
  43.                 popupMenuIndex  = i;
  44.          }
  45.      }
  46.  
  47.      /// <summary>
  48.      /// OnInspectorGUI is where the magic happens. Here we draw and change all the stuff
  49.      /// </summary>
  50.      public  override  void  OnInspectorGUI ( )
  51.      {
  52.          DrawDefaultInspector ( )//first we draw our DefaultInspector
  53.  
  54.          if  (l_renderers. Length  ==  0 )  //if there`s no Renderer at this object
  55.          {
  56.              return//returns
  57.          }
  58.  
  59.         popupMenuIndex  =  EditorGUILayout. Popup ( "Sorting Layer", popupMenuIndex, sortingLayerNames ); //The popup menu is displayed simple as that
  60.          int newSortingLayerOrder  =  EditorGUILayout. IntField ( "Order in Layer", l_renderers [ 0 ]. sortingOrder )//Specifies the order to be drawed in this particular SortLayer
  61.         applyToChild  =  EditorGUILayout. ToggleLeft ( "Apply to Childs", applyToChild ); //If this change will be applyed to every renderer or just this one
  62.  
  63.          if  (sortingLayerNames [popupMenuIndex ]  != l_renderers [ 0 ]. sortingLayerName  ||
  64.             newSortingLayerOrder  != l_renderers [ 0 ]. sortingOrder  ||
  65.             applyToChild  != applyToChildOldValue )  //if there`s some change
  66.          {
  67.              Undo. RecordObject (l_renderers [ 0 ]"Change Particle System Renderer Order" )//first let record this change into Undo class so if the user did a mess, he can use ctrl+z to undo
  68.  
  69.              if  (applyToChild )  //change sortingLayerName and sortingOrder in each Renderer
  70.              {
  71.                  for  ( int i  =  0; i <l_renderers. Length;i ++ )
  72.                  {
  73.                     l_renderers [i ]. sortingLayerName  = sortingLayerNames [popupMenuIndex ];
  74.                     l_renderers [i ]. sortingOrder  = newSortingLayerOrder;
  75.                  }
  76.              }
  77.              else  //or at least at this one
  78.              {
  79.                 l_renderers [ 0 ]. sortingLayerName  = sortingLayerNames [popupMenuIndex ];
  80.                 l_renderers [ 0 ]. sortingOrder  = newSortingLayerOrder;
  81.              }
  82.  
  83.              EditorUtility. SetDirty (l_renderers [ 0 ] )//saves
  84.          }
  85.      }
  86.  
  87.      // Get the sorting layer names
  88.      public  string [ ] GetSortingLayerNames ( )
  89.      {
  90.         Type internalEditorUtilityType  =  typeof (InternalEditorUtility );
  91.         PropertyInfo sortingLayersProperty  = internalEditorUtilityType. GetProperty ( "sortingLayerNames", BindingFlags. Static  | BindingFlags. NonPublic );
  92.          return  ( string [ ] )sortingLayersProperty. GetValue ( nullnew  object [ 0 ] );
  93.      }
  94. }
But unfortunately you need to put a code in your Shuriken Effect. An almost empty code with a particular name. Sad but true.


  1.  
  2. using UnityEngine;
  3. public  class RendererLayer  :  MonoBehaviour { }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值