经常想在脚本中设置一个变量对应SortingLayer的某个层,然后赋值给SpriteRender修改排序层,但是unity官方似乎没有办法直接弹出SortingLayer面板进行选择,就像是LayerMask一样。
public LayerMask hurtLayer;
既然unity不内置,那就自己想办法通过PropertyAttribute来实现吧,脚本中只要在变量声明前面用"[]"括起来即可实现
[Range(0f,1f)]
public float linerDrag = 0.2f;
比如上面这些就是是unity内置PropertyAttribute,照着这个思路,我们来看看怎么实现SortingLayer选择面板。
ps:什么是自定义属性?见Unity 扩展属性自定义绘制
先写一个PropertyAttribute类
using UnityEngine;
using System.Collections;
public class SortingLayerAttribute : PropertyAttribute {
public SortingLayerAttribute(){
}
}
对应写属性绘制类:(解析该自定义属性,在Inspector进行GUI的绘制)
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Reflection;
using UnityEditorInternal;
using System;
[CustomPropertyDrawer(typeof(SortingLayerAttribute))]
public class SortingLayerDrawer : PropertyDrawer {
const string NONE = "<None>";
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)
{
if (property.propertyType != SerializedPropertyType.String) {
EditorGUI.LabelField(position, "ERROR:", "May only apply to type string");
return;
}
position = EditorGUI.PrefixLabel(position, label);
string value = property.stringValue;
if (string.IsNullOrEmpty (value))
value = NONE;
if (GUI.Button(position, value, EditorStyles.popup)) {
Selector(property);
}
}
void Selector(SerializedProperty property) {
string[] layers = GetSortingLayerNames ();
GenericMenu menu = new GenericMenu();
bool isNone = string.IsNullOrEmpty (property.stringValue);
menu.AddItem(new GUIContent(NONE), isNone, HandleSelect, new SpineDrawerValuePair(NONE, property));
for (int i = 0; i < layers.Length; i++) {
string name = layers[i];
menu.AddItem(new GUIContent(name), name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property));
}
menu.ShowAsContext();
}
void HandleSelect(object val) {
var pair = (SpineDrawerValuePair)val;
if (pair.str.Equals (NONE)) {
pair.property.stringValue = "";
} else {
pair.property.stringValue = pair.str;
}
pair.property.serializedObject.ApplyModifiedProperties();
}
// 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]);
}
}
实现后的效果如下:
记住:SortingLayerDrawer.cs是编辑器类,请放在Editor目录下才能生效,SortingLayerAttribute.cs随意放即可