#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 |
나는 코드 자체는 딱히 잘 짜는 편이 아니라서 딱히 공유해도 상관은 없긴함
제네릭 이런거야 기본적으로 다들 쓰는거고
제네릭 데이터 처리하고, 코드 중복 제거하는거야 기본이니까
딱히 남들만큼 혁신적인 코드는 없는듯
뭐가 됐건 기초가 중요한거니까
막 플러그인만들고 뭐가 되게하고 이런 느낌의 코드. 예를들어 음성녹음을 하면 해당 목소리 분석해서 주인겅 대사에 더빙하는걸 구현한 느낌? 자료가 적어서 만들기는 힘들지만 만들고 정리하면 쉬워지는 코드
이런 느낌의 코드가 선뜻 공유하기 몬가 부담스럽더라
다 그런법이지