우당탕탕 개발일지

[Unity] Custom Editor - enum값을 dropdown에서 선택하기 + 원하는값만 나타내기 본문

Unity

[Unity] Custom Editor - enum값을 dropdown에서 선택하기 + 원하는값만 나타내기

devchop 2025. 3. 17. 17:00

 

여러가지 성장 시스템에서 강화할 수 있는 내용을 다음처럼 BattleUpgradeEnum으로 한곳에 통합관리하도록 만들었다.

 

public enum BattleUpgradeEnum
{
    //스탯강화
    HpUp_Basic = 101,
    //...

    //스킬강화
    SkillDamageIncrease = 1001, //스킬 데미지증가
    DecreaseCoolTs = 1002, //쿨타임 감소
    IncreaseBuffValue = 1003, //버프랑증가
    
    //버프스킬 종류
    Buff_PowerUp = 2001, //최종 공격력 증가
}

 

커스텀에디터에서 강화내용을 선택할 수 있게 하는데, 각 분야에 맞는 타입으로 제한하도록 구현해보자.

우선은 제한을 두기 위해 Description 을 생성해준다. 나의 경우 스탯강화, 버프스킬시전 종류, 스킬강화 3개로 나누었다.

 

 

Description 만들어서 선택제약 설정하기

 

다음은 스킬 강화내용을 담는다. 버프스킬인 "Buff_PowerUp" 은 추가하지 않았다. 드롭다운에서도 보여지지 않는다. 설명부분은 드롭다운메뉴에서 사용자가 보는 설명란이다. 

public static class BattleUpgradeTypeDescriptions
{
    public static readonly Dictionary<BattleUpgradeEnum, string> Descriptions = new Dictionary<BattleUpgradeEnum, string>{

        {BattleUpgradeEnum.HpUp_Basic,"체력증가[기본]"},
        {BattleUpgradeEnum.PowerUp_Basic,"공격력증가[기본]"},
        {BattleUpgradeEnum.MpUp_Basic,"최대마나 증가[기본]"},
        {BattleUpgradeEnum.EnergyUp_Basic,"최대기력 증가[기본]"},
        {BattleUpgradeEnum.AttackSpeedUp,"공격속도 증가"},
        {BattleUpgradeEnum.MpHealUp,"마나회복 증가"},
        {BattleUpgradeEnum.HpHealUp,"체력회복 증가"},
        {BattleUpgradeEnum.CriRateUp,"치명타 확률 증가"},
        {BattleUpgradeEnum.CriDamageUp,"치명타데미지 증가"},
        {BattleUpgradeEnum.DoubleShotUp,"더블샷 확률 증가"},
        {BattleUpgradeEnum.TripleShotUp,"트리플샷 확률 증가"},
        {BattleUpgradeEnum.AccuracyUp,"정확도 증가"},
        {BattleUpgradeEnum.EvasionUp,"회피율 증가"},

        {BattleUpgradeEnum.HpUp_Bonus,"체력증가[추가]"},
        {BattleUpgradeEnum.PowerUp_Bonus,"공격력증가[추가]"},
        {BattleUpgradeEnum.MpUp_Bonus,"최대마나 증가[추가]"},
        {BattleUpgradeEnum.EnergyUp_Bonus,"최대기력 증가[추가]"},

        {BattleUpgradeEnum.SkillDamageIncrease,"스킬 데미지 증폭[%]"},
        {BattleUpgradeEnum.SkillDamageIncrease_Fire,"불속성 스킬 데미지 증폭[%]"},
        {BattleUpgradeEnum.SkillDamageIncrease_Water,"물속성 스킬 데미지 증폭[%]"},
        {BattleUpgradeEnum.SkillDamageIncrease_Wind,"바람속성 스킬 데미지 증폭[%]"},
        {BattleUpgradeEnum.SkillDamageIncrease_Lightning,"번개속성 스킬 데미지 증폭[%]"},


    };
    public static string GetDescription(BattleUpgradeEnum type)
    {
        return Descriptions.TryGetValue(type, out string description) ? description : type.ToString();
    }

    public static BattleUpgradeEnum[] GetAvailableTypes()
    {
        return Descriptions.Keys.ToArray();
    }
}

 

 

 

에디터 작업하기

 

아래부분이 Description 에 있는 드롭다운 메뉴만 가져와서 보여주고, 선택 시 해당 enum값으로 설정하는 부분이다.

 

  // 1️⃣ 필터링된 enum 리스트 가져오기
BattleUpgradeEnum[] enumValues = BattleUpgradeTypeDescriptions.GetAvailableTypes();

// 2️⃣ 설명문 리스트 생성
string[] descriptions = new string[enumValues.Length];
for (int j = 0; j < enumValues.Length; j++)
{
    descriptions[j] = BattleUpgradeTypeDescriptions.GetDescription(enumValues[j]);
}

// 3️⃣ 현재 선택된 인덱스 찾기
int currentIndex = System.Array.IndexOf(enumValues, (BattleUpgradeEnum)passiveType.intValue);

// 4️⃣ 설명문이 있는 드롭다운 표시
int selectedIndex = EditorGUILayout.Popup("효과 타입", currentIndex, descriptions);

// 5️⃣ 값이 변경되었을 때 적용
if (selectedIndex != currentIndex)
{
    passiveType.intValue = (int)enumValues[selectedIndex];
}

 

editor부분 전체코드

    public override void OnInspectorGUI()
    {
        serializedObject.Update();

        EditorGUILayout.Space(10);
        GUIStyle titleStyle = CreateTitleStyle();
        GUIStyle sectionBackground = CreateSectionStyle();

        bool newShowPassiveEffects = EditorGUILayout.Foldout(showPassiveEffects, "▶ 보유 효과", true, titleStyle);
        if (newShowPassiveEffects != showPassiveEffects)
        {
            showPassiveEffects = newShowPassiveEffects;
            EditorPrefs.SetBool("SkillPassiveEffectEditor_showPassiveEffects", showPassiveEffects);
        }

        if (showPassiveEffects)
        {
            EditorGUILayout.BeginVertical(sectionBackground);
            EditorGUI.indentLevel++;

            GUILayout.Space(5);
            EditorGUILayout.PropertyField(maxLevel, new GUIContent("최대 레벨"));

            previewLevel = EditorGUILayout.IntSlider("미리보기 레벨", previewLevel, 1, maxLevel.intValue);

            Dictionary<BattleUpgradeEnum, float> activeEffects = skillData.GetActiveEffects(previewLevel);
            if (activeEffects.Count > 0)
            {
                EditorGUILayout.LabelField("현재 적용 효과", EditorStyles.boldLabel);
                foreach (var effect in activeEffects)
                {
                    string effectDescription = BattleUpgradeTypeDescriptions.GetDescription(effect.Key);
                    EditorGUILayout.LabelField($"- {effectDescription}: {effect.Value}");
                }
            }
            else
            {
                EditorGUILayout.LabelField("⚠️ 이 레벨에서는 적용되는 효과가 없습니다.");
            }

            GUILayout.Space(10);
            EditorGUILayout.LabelField("스킬 보유 효과 목록", EditorStyles.boldLabel);

            for (int i = 0; i < effects.arraySize; i++)
            {
                SerializedProperty effectProperty = effects.GetArrayElementAtIndex(i);

                SerializedProperty passiveType = effectProperty.FindPropertyRelative("upgradeType");
                SerializedProperty baseValue = effectProperty.FindPropertyRelative("baseValue");
                SerializedProperty startLevel = effectProperty.FindPropertyRelative("startLevel");
                SerializedProperty endLevel = effectProperty.FindPropertyRelative("endLevel");
                SerializedProperty increasePerLevel = effectProperty.FindPropertyRelative("increasePerLevel");

                EditorGUILayout.BeginVertical("box");




                // 1️⃣ 필터링된 enum 리스트 가져오기
                BattleUpgradeEnum[] enumValues = BattleUpgradeTypeDescriptions.GetAvailableTypes();

                // 2️⃣ 설명문 리스트 생성
                string[] descriptions = new string[enumValues.Length];
                for (int j = 0; j < enumValues.Length; j++)
                {
                    descriptions[j] = BattleUpgradeTypeDescriptions.GetDescription(enumValues[j]);
                }

                // 3️⃣ 현재 선택된 인덱스 찾기
                int currentIndex = System.Array.IndexOf(enumValues, (BattleUpgradeEnum)passiveType.intValue);

                // 4️⃣ 설명문이 있는 드롭다운 표시
                int selectedIndex = EditorGUILayout.Popup("효과 타입", currentIndex, descriptions);

                // 5️⃣ 값이 변경되었을 때 적용
                if (selectedIndex != currentIndex)
                {
                    passiveType.intValue = (int)enumValues[selectedIndex];
                }


                baseValue.floatValue = EditorGUILayout.FloatField("기본 값", baseValue.floatValue);
                startLevel.intValue = EditorGUILayout.IntField("적용 시작 레벨", startLevel.intValue);
                endLevel.intValue = EditorGUILayout.IntField("적용 종료 레벨", endLevel.intValue);
                increasePerLevel.floatValue = EditorGUILayout.FloatField("레벨당 증가량", increasePerLevel.floatValue);

                if (GUILayout.Button("삭제"))
                {
                    effects.DeleteArrayElementAtIndex(i);
                }
                EditorGUILayout.EndVertical();
            }

            if (GUILayout.Button("새로운 효과 추가"))
            {
                effects.arraySize++;
            }

            EditorGUI.indentLevel--;
            EditorGUILayout.EndVertical();
        }

        EditorGUILayout.Space(10);
        DrawMasterEffect();

        serializedObject.ApplyModifiedProperties();
    }