반응형
Unity 엔진 내장 에디터툴에서 자주 사용되는 폴드바 GUI 에디터 스크립트입니다.
EditorGUILayout과 같은 기본 에디터 클래스에는 구현되어 있지 않아 직접 제작해야합니다.
GUI 클래스
public static class CategoryHeader
{
protected static class Styles
{
public static readonly GUIStyle foldoutStyle;
public static readonly GUIStyle categoryHeader;
static Styles()
{
var builtInSkin = GetCurrentSkin();
foldoutStyle = new GUIStyle(EditorStyles.foldout);
foldoutStyle.fontStyle = FontStyle.Bold;
categoryHeader = new GUIStyle(builtInSkin.label);
categoryHeader.fontStyle = FontStyle.Bold;
categoryHeader.border.left = 2;
categoryHeader.padding.left = 32;
categoryHeader.padding.top = 2;
categoryHeader.border.right = 2;
categoryHeader.normal.background = GetBackgroundProcedural_Twotone(new Color(0.196f, 0.196f, 0.196f),
new Color(0.121f, 0.121f, 0.121f));
}
private static Texture2D GetBackgroundProcedural(Color color)
{
Texture2D texture = new Texture2D(1, 1);
texture.SetPixel(0, 0, color);
texture.Apply();
return texture;
}
private static Texture2D GetBackgroundProcedural_Twotone(Color color, Color headerColor)
{
const int height = 16;
Texture2D texture = new Texture2D(1, height);
for(int i=0; i< height - 1; i++)
{
texture.SetPixel(0, i, color);
}
texture.SetPixel(0, height - 1, headerColor);
texture.Apply();
return texture;
}
private static Texture2D GetBackgroundAsset(string assetPath)
{
Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath);
if (!texture)
{
Debug.LogWarning("GUITexture Asset does not exist : " + assetPath);
texture = null;
}
return texture;
}
public static GUISkin GetCurrentSkin()
{
return EditorGUIUtility.isProSkin ? EditorGUIUtility.GetBuiltinSkin(EditorSkin.Scene) : EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector);
}
}
public static bool ShowHeader(GUIContent nameContent, bool foldoutState, string preferenceName = null)
{
float height = Styles.categoryHeader.CalcHeight(nameContent, 4000) + 3;
Rect rect = GUILayoutUtility.GetRect(1, height - 1);
rect.width += rect.x;
rect.x = 0;
if (Event.current.type == EventType.Repaint)
Styles.categoryHeader.Draw(rect, nameContent, false, true, true, false);
bool result = false;
rect.x += 14;
rect.width -= 2;
result = EditorGUI.Toggle(rect, foldoutState, Styles.foldoutStyle);
EditorGUI.indentLevel = result ? 1 : 0;
if (preferenceName != null && result != foldoutState)
{
EditorPrefs.SetBool(preferenceName, result);
}
return result;
}
public static bool ShowHeader(string label, bool foldoutState, string preferenceName = null)
{
return ShowHeader(EditorGUIUtility.TrTempContent(label), foldoutState, preferenceName);
}
}
사용 샘플 & 전체 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(CustomInspectorSample))]
public class CustomInspectorSample_Editor : Editor
{
protected struct PropertyDefine
{
public SerializedProperty prop;
public string path;
public PropertyDefine(string path)
{
this.prop = null;
this.path = path;
}
public void Init(SerializedObject serializedObject)
{
prop = serializedObject.FindProperty(path);
}
}
protected static class Contents
{
public static readonly GUIContent headerGeneral = EditorGUIUtility.TrTextContent("General");
public static readonly GUIContent amount = EditorGUIUtility.TrTextContent("Amount", "Amount Property Description");
}
const string kGeneralFoldoutStatePreferenceName = "CustomInspectorSample_Editor.Foldout.General";
private bool showGeneralCategory;
private bool showRendererCategory;
private PropertyDefine _amountProp = new PropertyDefine("_amount");
private PropertyDefine _colorProp = new PropertyDefine("_color");
private CustomInspectorSample _component;
private void OnEnable()
{
_component = (CustomInspectorSample)target;
showGeneralCategory = EditorPrefs.GetBool(kGeneralFoldoutStatePreferenceName, true);
_amountProp.Init(serializedObject);
_colorProp.Init(serializedObject);
}
public override void OnInspectorGUI()
{
if (!_component) return;
serializedObject.Update();
EditorGUI.BeginChangeCheck();
GUILayout.Space(6);
showGeneralCategory = CategoryHeader.ShowHeader(Contents.headerGeneral, showGeneralCategory, kGeneralFoldoutStatePreferenceName);
if(showGeneralCategory)
{
EditorGUILayout.PropertyField(_amountProp.prop, Contents.amount);
GUILayout.Space(6);
}
showRendererCategory = CategoryHeader.ShowHeader("Renderer", showRendererCategory);
if (showRendererCategory)
{
EditorGUILayout.PropertyField(_colorProp.prop);
GUILayout.Space(6);
}
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
}
}
public static class CategoryHeader
{
protected static class Styles
{
public static readonly GUIStyle foldoutStyle;
public static readonly GUIStyle categoryHeader;
static Styles()
{
var builtInSkin = GetCurrentSkin();
foldoutStyle = new GUIStyle(EditorStyles.foldout);
foldoutStyle.fontStyle = FontStyle.Bold;
categoryHeader = new GUIStyle(builtInSkin.label);
categoryHeader.fontStyle = FontStyle.Bold;
categoryHeader.border.left = 2;
categoryHeader.padding.left = 32;
categoryHeader.padding.top = 2;
categoryHeader.border.right = 2;
categoryHeader.normal.background = GetBackgroundProcedural_Twotone(new Color(0.196f, 0.196f, 0.196f),
new Color(0.121f, 0.121f, 0.121f));
}
private static Texture2D GetBackgroundProcedural(Color color)
{
Texture2D texture = new Texture2D(1, 1);
texture.SetPixel(0, 0, color);
texture.Apply();
return texture;
}
private static Texture2D GetBackgroundProcedural_Twotone(Color color, Color headerColor)
{
const int height = 16;
Texture2D texture = new Texture2D(1, height);
for(int i=0; i< height - 1; i++)
{
texture.SetPixel(0, i, color);
}
texture.SetPixel(0, height - 1, headerColor);
texture.Apply();
return texture;
}
private static Texture2D GetBackgroundAsset(string assetPath)
{
Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath);
if (!texture)
{
Debug.LogWarning("GUITexture Asset does not exist : " + assetPath);
texture = null;
}
return texture;
}
public static GUISkin GetCurrentSkin()
{
return EditorGUIUtility.isProSkin ? EditorGUIUtility.GetBuiltinSkin(EditorSkin.Scene) : EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector);
}
}
public static bool ShowHeader(GUIContent nameContent, bool foldoutState, string preferenceName = null)
{
float height = Styles.categoryHeader.CalcHeight(nameContent, 4000) + 3;
Rect rect = GUILayoutUtility.GetRect(1, height - 1);
rect.width += rect.x;
rect.x = 0;
if (Event.current.type == EventType.Repaint)
Styles.categoryHeader.Draw(rect, nameContent, false, true, true, false);
bool result = false;
rect.x += 14;
rect.width -= 2;
result = EditorGUI.Toggle(rect, foldoutState, Styles.foldoutStyle);
EditorGUI.indentLevel = result ? 1 : 0;
if (preferenceName != null && result != foldoutState)
{
EditorPrefs.SetBool(preferenceName, result);
}
return result;
}
public static bool ShowHeader(string label, bool foldoutState, string preferenceName = null)
{
return ShowHeader(EditorGUIUtility.TrTempContent(label), foldoutState, preferenceName);
}
}
반응형
'Unity > TA' 카테고리의 다른 글
SpriteRenderer CustomVertex Attributes R&D (0) | 2023.12.04 |
---|---|
SRP Batcher GLES & Vulkan 비교 (0) | 2023.11.14 |
Unity 2023-URP 16 렌더피처 API 변경 정리 (0) | 2023.09.22 |
URP 15 데칼 레이어 분석 & 구현 방법 (1) | 2023.08.31 |
URP 15.0.5 데칼 레이어 렌더링 이슈 (0) | 2023.07.25 |
WRITTEN BY
- CatDarkGame
Technical Artist dhwlgn12@gmail.com
,