转载: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.
-
-
// SortLayerRendererExtension.cs
-
// Author:
-
// Yves J. Albuquerque <yves.albuquerque@gmail.com>
-
// Last Update:
-
// 27-12-2013
-
//Put this file into a folder named Editor.
-
//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
-
using System;
-
using UnityEngine;
-
using UnityEditor;
-
using UnityEditorInternal;
-
using System. Reflection;
-
-
[CanEditMultipleObjects ( ) ]
-
{
-
Renderer renderer;
-
string [ ] sortingLayerNames;
-
-
int selectedOption;
-
bool applyToChild = false;
-
bool applyToChildOldValue = false;
-
-
{
-
sortingLayerNames = GetSortingLayerNames ( );
-
childsRenderer = ( target as SortingLayerExposed ). transform. GetComponentsInChildren <Renderer > ( );
-
-
{
-
if (sortingLayerNames [i ] == renderer. sortingLayerName )
-
selectedOption = i;
-
}
-
}
-
-
{
-
if ( !renderer )
-
{
-
return;
-
}
-
-
-
if (sortingLayerNames [selectedOption ] != renderer. sortingLayerName )
-
{
-
if ( !applyToChild )
-
renderer. sortingLayerName = sortingLayerNames [selectedOption ];
-
else
-
{
-
{
-
childsRenderer [i ]. sortingLayerName = sortingLayerNames [selectedOption ];
-
}
-
}
-
}
-
-
if (newSortingLayerOrder != renderer. sortingOrder )
-
{
-
renderer. sortingOrder = newSortingLayerOrder;
-
}
-
-
if (applyToChild != applyToChildOldValue )
-
{
-
{
-
childsRenderer [i ]. sortingLayerName = sortingLayerNames [selectedOption ];
-
}
-
applyToChildOldValue = applyToChild;
-
}
-
}
-
-
// Get the sorting layer names
-
public string [ ] GetSortingLayerNames ( )
-
{
-
Type internalEditorUtilityType = typeof (InternalEditorUtility );
-
PropertyInfo sortingLayersProperty = internalEditorUtilityType. GetProperty ( "sortingLayerNames", BindingFlags. Static | BindingFlags. NonPublic );
-
return ( string [ ] )sortingLayersProperty. GetValue ( null, new object [ 0 ] );
-
}
-
-
// Get the unique sorting layer IDs -- tossed this in for good measure
-
public int [ ] GetSortingLayerUniqueIDs ( )
-
{
-
Type internalEditorUtilityType = typeof (InternalEditorUtility );
-
PropertyInfo sortingLayerUniqueIDsProperty = internalEditorUtilityType. GetProperty ( "sortingLayerUniqueIDs", BindingFlags. Static | BindingFlags. NonPublic );
-
return ( int [ ] )sortingLayerUniqueIDsProperty. GetValue ( null, new object [ 0 ] );
-
}
-
}
-
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
-
// RendererLayerEditor.cs
-
// Author:
-
// Yves J. Albuquerque <yves.albuquerque@gmail.com>
-
// Last Update:
-
// 28-12-2013
-
//Put this file into a folder named Editor.
-
//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
-
using System;
-
using UnityEngine;
-
using UnityEditor;
-
using UnityEditorInternal;
-
using System. Reflection;
-
-
[CanEditMultipleObjects ( ) ]
-
[CustomEditor ( typeof (RendererLayer ) ) ]
-
{
-
-
string [ ] sortingLayerNames; //we load here our Layer names to be displayed at the popup GUI
-
int popupMenuIndex; //The selected GUI popup Index
-
bool applyToChild = false; //Turn on/off if the effect will be extended to all renderers in child transforms
-
bool applyToChildOldValue = false; //Used this old value to detect changes in applyToChild boolean
-
-
/// <summary>
-
/// 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
-
/// </summary>
-
{
-
sortingLayerNames = GetSortingLayerNames ( ); //First we load the name of our layers
-
l_particleSystems = ( target as RendererLayer ). gameObject. GetComponentsInChildren <ParticleSystem > ( ); //Then we load our ParticleSystems
-
-
for ( int i = 0; i <l_particleSystems. Length;i ++ ) //here we loads all renderers to our renderersarray
-
{
-
l_renderers [i ] = l_particleSystems [i ]. renderer;
-
}
-
-
for ( int i = 0; i <sortingLayerNames. Length;i ++ ) //here we initialize our popupMenuIndex with the current Sort Layer Name
-
{
-
if (sortingLayerNames [i ] == l_particleSystems [ 0 ]. renderer. sortingLayerName )
-
popupMenuIndex = i;
-
}
-
}
-
-
/// <summary>
-
/// OnInspectorGUI is where the magic happens. Here we draw and change all the stuff
-
/// </summary>
-
{
-
-
{
-
return; //returns
-
}
-
-
popupMenuIndex = EditorGUILayout. Popup ( "Sorting Layer", popupMenuIndex, sortingLayerNames ); //The popup menu is displayed simple as that
-
int newSortingLayerOrder = EditorGUILayout. IntField ( "Order in Layer", l_renderers [ 0 ]. sortingOrder ); //Specifies the order to be drawed in this particular SortLayer
-
applyToChild = EditorGUILayout. ToggleLeft ( "Apply to Childs", applyToChild ); //If this change will be applyed to every renderer or just this one
-
-
if (sortingLayerNames [popupMenuIndex ] != l_renderers [ 0 ]. sortingLayerName ||
-
newSortingLayerOrder != l_renderers [ 0 ]. sortingOrder ||
-
applyToChild != applyToChildOldValue ) //if there`s some change
-
{
-
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
-
-
if (applyToChild ) //change sortingLayerName and sortingOrder in each Renderer
-
{
-
{
-
l_renderers [i ]. sortingLayerName = sortingLayerNames [popupMenuIndex ];
-
l_renderers [i ]. sortingOrder = newSortingLayerOrder;
-
}
-
}
-
else //or at least at this one
-
{
-
l_renderers [ 0 ]. sortingLayerName = sortingLayerNames [popupMenuIndex ];
-
l_renderers [ 0 ]. sortingOrder = newSortingLayerOrder;
-
}
-
-
}
-
}
-
-
// Get the sorting layer names
-
public string [ ] GetSortingLayerNames ( )
-
{
-
Type internalEditorUtilityType = typeof (InternalEditorUtility );
-
PropertyInfo sortingLayersProperty = internalEditorUtilityType. GetProperty ( "sortingLayerNames", BindingFlags. Static | BindingFlags. NonPublic );
-
return ( string [ ] )sortingLayersProperty. GetValue ( null, new object [ 0 ] );
-
}
-
}
-
-
using UnityEngine;