Unity Inspector에서 Enum의 일부 항목을 숨기는 방법
하고 싶은 일
직렬화된 EnumField의 내용을 변경하지 않고 Editor에서 표시할 수 있는 항목을 제한하고 싶습니다.
// サンプルEnumの定義
public enum ColorEnum {
None = 0,
Red = 1,
Green = 2,
Blue = 3
}
그대로 Editor로 표시시킬 경우 모든 항목을 선택 가능
[SerializeField] ColorEnum myColor;
이와 같이, 「HideEnumItem」이라고 하는 마법 Attribute를 붙이는 것으로, Editor로 표시된 「myColor」로부터 「None」과 「Red」를 숨기고 싶다
[HideEnumItem("None", "Red"), SerializeField] ColorEnum myColor;
「HideEnumItem」이라는 마법 Attribute는 아래와 같은 「Custom Attribute」와 「Custom Property Drawer」로 준비한다.
Custom Attribute 준비
"Custom Attribute"은 c# 표준 기능으로, "SerializeField"와 같은 Attribute를 자작할 수 있습니다.
먼저 일반 Scripts 폴더에서 아래의 "HideEnumItemAttribute.cs"파일을 만듭니다.
using System.Collections.Generic;
using UnityEngine;
// AttributeUsageで使用できる変数をクラスのフィールドに限定
[System.AttributeUsage(System.AttributeTargets.Field)]
public class HideEnumItemAttribute : PropertyAttribute
{
// 隠したい項目を保存用
public HashSet<string> Filter { get; private set; }
public HideEnumItemAttribute(params string[] filters)
{
Filter = new HashSet<string>();
for (var i = 0; i < filters.Length; i++) {
Filter.Add(filters[i]);
}
}
}
Custom Property Drawer 준비
「 Custom Property Drawer 」는 UnityEditor의 기능으로, Editor의 인스펙터 주위의 묘화를 커스터마이즈 할 수가 있습니다.
위의
HideEnumItemAttribute
를 받고 지정된 항목을 숨기는 "HideEnumItemAttribute.cs"파일을 만듭니다 (이것은 UnityEditor의 API를 사용하므로 Editor 폴더에 넣어야합니다) :using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
// 自作のAttributeを指定
[CustomPropertyDrawer(typeof(HideEnumItemAttribute))]
public class HideEnumItemDrawer : PropertyDrawer
{
int selectedIndex;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
// Attribute取得
var filterInfo = (HideEnumItemAttribute)attribute;
// eunmValueIndex変換用
var enum2index = new Dictionary<int, int>(property.enumNames.Length);
for (int i = 0; i < property.enumNames.Length; i++)
{
var enumEntry = Enum.Parse(fieldInfo.FieldType, property.enumNames[i]);
enum2index[(int)enumEntry] = i;
}
// 表示項目を加工
var filteredItems = property.enumNames.Where(item => !filterInfo.Filter.Contains(item)).ToList();
// Editor表示の同期
selectedIndex = filteredItems.IndexOf(property.enumNames[property.enumValueIndex]);
// シリアライズされた値が範囲外だった場合、最初の項目に設定
if (selectedIndex < 0) {
selectedIndex = 0;
var mappedEnum = Enum.Parse(fieldInfo.FieldType, filteredItems[selectedIndex]);
property.enumValueIndex = enum2index[(int)mappedEnum];
}
// オリジナルの代わりに、加工されたリストを描画
using (var check = new EditorGUI.ChangeCheckScope())
{
selectedIndex = EditorGUI.Popup(position, label.text, selectedIndex, filteredItems.ToArray());
if (check.changed)
{
// 元のEnum値に変換
var mappedEnum = Enum.Parse(fieldInfo.FieldType, filteredItems[selectedIndex]);
property.enumValueIndex = enum2index[(int)mappedEnum];
}
}
}
}
요약
이와 같이 「Custom Attribute」와 「Custom Property Drawer」를 조합하는 것으로, 범용적이고 효율적인 Editor 확장을 할 수 있게 되므로, 편리하게 하고 싶네요. 덧붙여서, 이러한 편리한 「Custom Attribute」를 많이 준비해 주는 Unity 에셋이 「Odin Inspector And Serializer」이 됩니다. 흥미있는 분은 꼭 체크해 보세요.
Reference
이 문제에 관하여(Unity Inspector에서 Enum의 일부 항목을 숨기는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/superkerokero/items/41fc8d2a3a1dd25a5dc8텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)