#if UNITY_EDITOR
using UnityEditor;
#endif
 
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Core;
using TestingTools;
 
namespace ResistanceSystem
{
    /// <summary>
    /// 상태 효과 데이터베이스 관리 클래스.
    /// </summary>
    [CreateAssetMenu(fileName = "StatusEffectDatabase", menuName = "ResistanceSystem/StatusEffectDatabase", order = 2)]
    public class StatusEffectDataBaseSO : DataBaseTemplate<StatusEffectSO>
    {
        #region Fields
 
        private const string StatusEffectGroup = "StatusEffect"// 기본 그룹 이름
 
        #endregion
 
        #region Public Methods
 
        /// <summary>
        /// 상태 효과 타입에 해당하는 StatusEffectSO 반환.
        /// </summary>
        /// <param name="effectType">상태 효과 타입</param>
        /// <returns>StatusEffectSO 객체 (없을 경우 null)</returns>
        public StatusEffectSO GetStatusEffect(StatusEffectType effectType)
        {
            foreach (StatusEffectSO effect in GetGroupData(StatusEffectGroup))
            {
                if (effect.effectType == effectType)
                {
                    return effect;
                }
            }
            Debug.LogWarning($"[StatusEffectDatabase] {effectType}에 해당하는 상태 효과 데이터가 없습니다.");
            return null;
        }
 
        #endregion
 
        #region Editor Val-idation
 
#if UNITY_EDITOR
        /// <summary>
        /// 에디터에서 변경 사항 발생 시 호출.
        /// </summary>
        protected override void OnVal-idate()
        {
            // 에셋 임포트 중이거나 플레이 모드인 경우 실행하지 않음
            if (Application.isPlaying || EditorApplication.isUpdating || AssetDatabase.IsAssetImportWorkerProcess())
            {
                return;
            }
 
            // 중복 호출 방지
            if (isDirty)
            {
                return;
            }
 
            try
            {
                isDirty = true;
 
                // 기본 유효성 검사 실행
                base.OnVal-idate();
 
                // Enum과 동기화
                SyncWithEnum();
            }
            catch (Exception e)
            {
                Debug.LogError($"[{name}] OnVal-idate 중 오류 발생: {e.Message}");
                Debug.LogError(e.StackTrace);
            }
            finally
            {
                isDirty = false;
            }
        }
 
        /// <summary>
        /// StatusEffectType Enum과 데이터 리스트 동기화.
        /// </summary>
        private void SyncWithEnum()
        {
            AssetDatabase.StartAssetEditing();
            try
            {
                Debug.Log($"[SyncWithEnum] 시작: {DateTime.Now}");
 
                List<StatusEffectType> enumValues = Enum.GetValues(typeof(StatusEffectType)).Cast<StatusEffectType>().ToList();
                Dictionary<StatusEffectType, StatusEffectSO> existingEffects = new Dictionary<StatusEffectType, StatusEffectSO>();
 
                // 기존 리스트를 딕셔너리로 변환 (null 체크 강화)
                IReadOnlyList<StatusEffectSO> groupData = GetGroupData(StatusEffectGroup);
                if (groupData != null)
                {
                    foreach (StatusEffectSO effect in groupData)
                    {
                        if (effect != null)
                        {
                            existingEffects[effect.effectType] = effect;
                        }
                    }
                }
 
                Debug.Log($"[SyncWithEnum] 기존 리스트 변환 완료: {existingEffects.Count}개 항목");
 
                // Enum 값에 따라 리스트 업데이트
                DataGroup<StatusEffectSO> group = dataGroups.Find(g => g.GetGroupName() == StatusEffectGroup);
                if (group == null)
                {
                    group = new DataGroup<StatusEffectSO>();
                    group.SetGroupName(StatusEffectGroup);
                    dataGroups.Add(group);
                }
 
                // 리스트 초기화 (새로운 리스트 생성)
                List<StatusEffectSO> list = new List<StatusEffectSO>();
 
                foreach (StatusEffectType type in enumValues)
                {
                    if (type == StatusEffectType.None) continue;
 
                    if (existingEffects.TryGetValue(type, out StatusEffectSO effect))
                    {
                        list.Add(effect);
                    }
                    else
                    {
                        // 새로운 StatusEffectSO 생성 및 하위 에셋으로 저장
                        StatusEffectSO newEffect = CreateInstance<StatusEffectSO>();
                        newEffect.effectType = type;
                        newEffect.name = $"{type}Effect";
 
                        // 메인 에셋이 저장되었는지 확인
                        string assetPath = AssetDatabase.GetAssetPath(this);
                        if (string.IsNullOrEmpty(assetPath))
                        {
                            Debug.LogWarning($"[{name}] 메인 에셋이 저장되지 않았습니다. 임시로 저장합니다.");
                            assetPath = "Assets/StatusEffectDatabase.asset";
 
                            // 이미 존재하는지 확인
                            if (AssetDatabase.LoadAssetAtPath<StatusEffectDataBaseSO>(assetPath) != null)
                            {
                                Debug.LogWarning($"[{name}] 이미 동일한 경로에 에셋이 존재합니다. 새로운 경로를 생성합니다.");
                                assetPath = AssetDatabase.GenerateUniqueAssetPath(assetPath);
                            }
 
                            AssetDatabase.CreateAsset(this, assetPath);
                            AssetDatabase.SaveAssets(); // 변경 사항 저장
                        }
 
                        // 하위 에셋으로 추가 (중복 추가 방지)
                        if (!AssetDatabase.IsSubAsset(newEffect))
                        {
                            AssetDatabase.AddObjectToAsset(newEffect, this);
                            Debug.Log($"[{name}] 하위 에셋 추가: {newEffect.name}");
                        }
 
                        list.Add(newEffect);
                        isDirty = true;
                    }
                }
 
                Debug.Log($"[SyncWithEnum] 새로운 데이터 생성 완료: {list.Count}개 항목");
 
                // 변경된 리스트를 다시 그룹에 저장
                if (isDirty)
                {
                    group.SetDataL-ist(list);
                    SaveChanges();
                    isDirty = false;
                }
 
                Debug.Log($"[SyncWithEnum] 변경 사항 저장 완료: {DateTime.Now}");
            }
            catch (Exception e)
            {
                Debug.LogError($"[{name}] SyncWithEnum 중 오류 발생: {e.Message}");
                Debug.LogError(e.StackTrace);
            }
            finally
            {
                AssetDatabase.StopAssetEditing();
            }
        }
#endif
 
        #endregion
    }
}
 
cs





나는 코드 자체는 딱히 잘 짜는 편이 아니라서 딱히 공유해도 상관은 없긴함


제네릭 이런거야 기본적으로 다들 쓰는거고


제네릭 데이터 처리하고, 코드 중복 제거하는거야 기본이니까


딱히 남들만큼 혁신적인 코드는 없는듯


뭐가 됐건 기초가 중요한거니까