데이터 파이프라인 개선 및 포탈 로직 생성
csv import 시 자동으로 완전한 프리팹이 생성될 수 있도록 함.
This commit is contained in:
@@ -12,6 +12,27 @@ namespace Northbound.Editor
|
||||
{
|
||||
private static readonly string GAMEDATA_PATH = Path.Combine(Application.dataPath, "..", "GameData");
|
||||
private static readonly string SO_BASE_PATH = "Assets/Data/ScriptableObjects";
|
||||
private static readonly string PREFAB_BASE_PATH = "Assets/Prefabs";
|
||||
private static readonly string TEMPLATE_BASE_PATH = "Assets/Data/Templates";
|
||||
|
||||
private static System.Collections.Generic.Dictionary<string, IPrefabSetup> prefabSetups =
|
||||
new System.Collections.Generic.Dictionary<string, IPrefabSetup>();
|
||||
|
||||
static CSVToSOImporter()
|
||||
{
|
||||
RegisterPrefabSetups();
|
||||
}
|
||||
|
||||
private static void RegisterPrefabSetups()
|
||||
{
|
||||
prefabSetups.Clear();
|
||||
prefabSetups["Monster"] = new MonsterPrefabSetup();
|
||||
|
||||
// To add new data types, create a class implementing IPrefabSetup
|
||||
// Example:
|
||||
// prefabSetups["Tower"] = new TowerPrefabSetup();
|
||||
// prefabSetups["Player"] = new PlayerPrefabSetup();
|
||||
}
|
||||
|
||||
[MenuItem("Tools/Data/Import All CSV")] // 메뉴 추가 (편의성)
|
||||
public static void ImportAll()
|
||||
@@ -54,6 +75,7 @@ namespace Northbound.Editor
|
||||
if (lines.Length < 2) return false;
|
||||
|
||||
var headers = ParseCSVLine(lines[0]);
|
||||
var createdSOs = new List<ScriptableObject>();
|
||||
|
||||
for (int lineIndex = 1; lineIndex < lines.Length; lineIndex++)
|
||||
{
|
||||
@@ -72,7 +94,12 @@ namespace Northbound.Editor
|
||||
}
|
||||
|
||||
string assetName = GetAssetName(so, lineIndex);
|
||||
AssetDatabase.CreateAsset(so, Path.Combine(outputPath, $"{assetName}.asset"));
|
||||
string soPath = Path.Combine(outputPath, $"{assetName}.asset");
|
||||
|
||||
AssetDatabase.CreateAsset(so, soPath);
|
||||
createdSOs.Add(so);
|
||||
|
||||
GenerateOrUpdatePrefab(schemaName, assetName, so, lineIndex);
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
@@ -148,11 +175,97 @@ namespace Northbound.Editor
|
||||
return l == "true" || l == "1" || l == "yes";
|
||||
}
|
||||
if (targetType == typeof(string)) return value.Replace("\\n", "\n");
|
||||
return Convert.ChangeType(value, targetType);
|
||||
return Convert.ChangeType(value, targetType);
|
||||
}
|
||||
catch { return null; }
|
||||
}
|
||||
|
||||
private static int GetColumnIndex(string[] headers, string columnName)
|
||||
{
|
||||
for (int i = 0; i < headers.Length; i++)
|
||||
{
|
||||
if (headers[i].Equals(columnName, System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static void GenerateOrUpdatePrefab(string schemaName, string prefabName, ScriptableObject so, int lineNumber)
|
||||
{
|
||||
string prefabOutputPath = Path.Combine(PREFAB_BASE_PATH, schemaName);
|
||||
if (!Directory.Exists(prefabOutputPath))
|
||||
{
|
||||
Directory.CreateDirectory(prefabOutputPath);
|
||||
}
|
||||
|
||||
string prefabPath = Path.Combine(prefabOutputPath, $"{prefabName}.prefab");
|
||||
IPrefabSetup prefabSetup = GetPrefabSetup(schemaName);
|
||||
|
||||
if (prefabSetup == null)
|
||||
{
|
||||
Debug.LogWarning($"[CSVImporter] No prefab setup found for {schemaName}, skipping prefab generation");
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject template = LoadTemplate(schemaName);
|
||||
if (template == null)
|
||||
{
|
||||
Debug.LogWarning($"[CSVImporter] No template found for {schemaName}, skipping prefab generation");
|
||||
return;
|
||||
}
|
||||
|
||||
if (AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath) != null)
|
||||
{
|
||||
UpdateExistingPrefab(prefabPath, so, prefabSetup);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameObject prefabInstance = GameObject.Instantiate(template);
|
||||
prefabInstance.name = prefabName;
|
||||
PrefabUtility.SaveAsPrefabAsset(prefabInstance, prefabPath);
|
||||
GameObject.DestroyImmediate(prefabInstance);
|
||||
|
||||
UpdateExistingPrefab(prefabPath, so, prefabSetup);
|
||||
|
||||
Debug.Log($"[CSVImporter] Created prefab: {prefabPath}");
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
private static GameObject LoadTemplate(string schemaName)
|
||||
{
|
||||
string templatePath = Path.Combine(TEMPLATE_BASE_PATH, $"{schemaName}Template.prefab");
|
||||
return AssetDatabase.LoadAssetAtPath<GameObject>(templatePath);
|
||||
}
|
||||
|
||||
private static IPrefabSetup GetPrefabSetup(string schemaName)
|
||||
{
|
||||
prefabSetups.TryGetValue(schemaName, out IPrefabSetup setup);
|
||||
return setup;
|
||||
}
|
||||
|
||||
private static void UpdateExistingPrefab(string prefabPath, ScriptableObject so, IPrefabSetup prefabSetup)
|
||||
{
|
||||
GameObject prefabContents = PrefabUtility.LoadPrefabContents(prefabPath);
|
||||
|
||||
prefabSetup.SetupPrefab(prefabContents, so);
|
||||
|
||||
PrefabUtility.SaveAsPrefabAsset(prefabContents, prefabPath);
|
||||
GameObject.DestroyImmediate(prefabContents);
|
||||
}
|
||||
|
||||
private static void RemoveOldModel(GameObject prefab)
|
||||
{
|
||||
Transform oldModel = prefab.transform.Find("Model");
|
||||
if (oldModel != null)
|
||||
{
|
||||
GameObject.DestroyImmediate(oldModel.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
// --- 유틸리티 메서드 (기존과 동일) ---
|
||||
private static string[] ParseCSVLine(string line)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user