【Unity】エディタ拡張でSortingLayerのフィールドを表示する
このメニューを出したい
標準のエディタ拡張APIでは、Sorting Layerを編集するポップアップを出す手段がありません。
これを手動で出せるようにするというお話です。
方針
実はSortingLayerのリストを表示するAPIがEditorGUI.SortingLayerField()として存在しているのですが、internal
に指定されているために直接使用することができなくなっています。
当初はそのままコピペして動かそうと思ったのですが、結局別のinternalなメンバーにアクセスする必要が出てきてしまったので、EditorGUI.SortingLayerField()
を直接リフレクションで呼び出すことにしました。
Unityでinternalなメンバにアクセスするにはasmrefを使う方法なんかもあるのですが、今回は相手がUnityEditor.dll
なので使えず。素直にリフレクションを使います。
実装
エディタ描画の度にリフレクションさせるとエディタのパフォーマンスに影響しそうな気がするので、初回だけデリゲートを動的生成して2回目以降はキャッシュを使います。
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace Ruccho.Utilities
{
public static class SortingLayerEditorUtility
{
private static GUIStyle boldPopupStyle;
private static GUIStyle BoldPopupStyle
{
get
{
if (boldPopupStyle == null)
{
boldPopupStyle = new GUIStyle(EditorStyles.popup);
boldPopupStyle.fontStyle = FontStyle.Bold;
}
return boldPopupStyle;
}
}
private delegate void SortingLayerFieldDelegate(Rect position, GUIContent label, SerializedProperty layerID,
GUIStyle style, GUIStyle labelStyle);
private static SortingLayerFieldDelegate sortingLayerFieldDelegate = default;
private static bool HasPrefabOverride(SerializedProperty property)
{
return property != null && property.serializedObject.targetObjects.Length == 1 && property.isInstantiatedPrefab && property.prefabOverride;
}
public static void SortingLayerFieldLayout(GUIContent label, SerializedProperty layerID)
{
var hasPrefabOverride = HasPrefabOverride(layerID);
var style = hasPrefabOverride ? BoldPopupStyle : EditorStyles.popup;
var labelStyle = hasPrefabOverride ? EditorStyles.boldLabel : EditorStyles.label;
SortingLayerFieldLayout(label, layerID, style, labelStyle);
}
public static void SortingLayerFieldLayout(GUIContent label, SerializedProperty layerID, GUIStyle style, GUIStyle labelStyle)
{
Rect rect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight, style);
SortingLayerField(rect, label, layerID, style, labelStyle);
}
public static void SortingLayerField(Rect position, GUIContent label, SerializedProperty layerID)
{
var hasPrefabOverride = HasPrefabOverride(layerID);
var style = hasPrefabOverride ? BoldPopupStyle : EditorStyles.popup;
var labelStyle = hasPrefabOverride ? EditorStyles.boldLabel : EditorStyles.label;
SortingLayerField(position, label, layerID, style, labelStyle);
}
public static void SortingLayerField(Rect position, GUIContent label, SerializedProperty layerID,
GUIStyle style, GUIStyle labelStyle)
{
if (sortingLayerFieldDelegate == default)
{
var editorGuiType = typeof(EditorGUI);
var sortingLayerFieldMethod =
editorGuiType.GetMethod("SortingLayerField", BindingFlags.Static | BindingFlags.NonPublic);
if (sortingLayerFieldMethod == null) return;
sortingLayerFieldDelegate = (SortingLayerFieldDelegate)
Delegate.CreateDelegate(typeof(SortingLayerFieldDelegate), sortingLayerFieldMethod);
}
sortingLayerFieldDelegate?.Invoke(position, label, layerID, style, labelStyle);
}
}
}
ここまでやればSortingLayerEditorUtility.SortingLayerFieldLayout()
または SortingLayerEditorUtility.SortingLayerField()
で呼び出しが可能です。
参考
Author And Source
この問題について(【Unity】エディタ拡張でSortingLayerのフィールドを表示する), 我々は、より多くの情報をここで見つけました https://qiita.com/ruccho_vector/items/6a28e20b62121464e24a著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .