업그레이드 데이터 입력 로직 및 기능 추가
캐릭터 스탯을 PlayerStats 컴포넌트에서 모아서 관리하도록 변경 코드에서도 마찬가지
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -45,12 +46,12 @@ namespace Northbound.Editor
|
||||
}
|
||||
|
||||
Debug.Log($"<color=green>[CSVToSOImporter] Import complete: {successCount} succeeded, {failCount} failed</color>");
|
||||
|
||||
|
||||
if (towerImported)
|
||||
{
|
||||
AutoConfigureBuildingManager();
|
||||
}
|
||||
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
@@ -61,7 +62,8 @@ namespace Northbound.Editor
|
||||
{ "Monster", new MonsterPrefabSetup() },
|
||||
{ "Creep", new CreepPrefabSetup() },
|
||||
{ "Tower", new TowerPrefabSetup() },
|
||||
{ "Player", new PlayerPrefabSetup() }
|
||||
{ "Player", new PlayerPrefabSetup() },
|
||||
{ "Upgrade", new UpgradePrefabSetup() }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -82,14 +84,19 @@ namespace Northbound.Editor
|
||||
}
|
||||
|
||||
IPrefabSetup prefabSetup = prefabSetups[typeName];
|
||||
string templateName = prefabSetup.GetTemplateName();
|
||||
string templatePath = $"Assets/Data/Templates/{templateName}.prefab";
|
||||
|
||||
GameObject template = AssetDatabase.LoadAssetAtPath<GameObject>(templatePath);
|
||||
if (template == null)
|
||||
// Upgrade는 템플릿이 필요 없음
|
||||
GameObject template = null;
|
||||
if (typeName != "Upgrade")
|
||||
{
|
||||
Debug.LogError($"[CSVToSOImporter] Template not found: {templatePath}");
|
||||
return false;
|
||||
string templateName = prefabSetup.GetTemplateName();
|
||||
string templatePath = $"Assets/Data/Templates/{templateName}.prefab";
|
||||
template = AssetDatabase.LoadAssetAtPath<GameObject>(templatePath);
|
||||
if (template == null)
|
||||
{
|
||||
Debug.LogError($"[CSVToSOImporter] Template not found: {templatePath}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
string[] csvLines = File.ReadAllLines(csvPath);
|
||||
@@ -123,7 +130,6 @@ namespace Northbound.Editor
|
||||
Debug.Log($"[CSVToSOImporter] {typeName}: {successCount} prefabs created/updated");
|
||||
}
|
||||
|
||||
// If towers were imported, auto-configure BuildingManager
|
||||
if (typeName == "Tower")
|
||||
{
|
||||
Debug.Log($"<color=cyan>[CSVToSOImporter] Tower import complete!</color>");
|
||||
@@ -134,8 +140,19 @@ namespace Northbound.Editor
|
||||
|
||||
private static bool CreatePrefabFromRow(string typeName, string[] headers, string[] values, GameObject template, IPrefabSetup prefabSetup)
|
||||
{
|
||||
string soPath = $"Assets/Data/ScriptableObjects/{typeName}";
|
||||
Directory.CreateDirectory(Path.Combine(Application.dataPath, $"ScriptableObjects/{typeName}"));
|
||||
string soPath;
|
||||
if (typeName == "Upgrade")
|
||||
{
|
||||
// Upgrade는 Resources 폴더에 저장 (런타임 자동 로드용)
|
||||
soPath = "Assets/Resources/Data/ScriptableObjects/Upgrade";
|
||||
Directory.CreateDirectory(Path.Combine(Application.dataPath, "Resources/Data/ScriptableObjects/Upgrade"));
|
||||
}
|
||||
else
|
||||
{
|
||||
soPath = $"Assets/Data/ScriptableObjects/{typeName}";
|
||||
Directory.CreateDirectory(Path.Combine(Application.dataPath, $"ScriptableObjects/{typeName}"));
|
||||
}
|
||||
|
||||
|
||||
int id = 0;
|
||||
for (int i = 0; i < headers.Length && i < values.Length; i++)
|
||||
@@ -188,6 +205,11 @@ namespace Northbound.Editor
|
||||
PlayerPrefabSetup.UpdatePlayerPrefab((PlayerData)data);
|
||||
prefabObj = null;
|
||||
}
|
||||
else if (typeName == "Upgrade")
|
||||
{
|
||||
// Upgrade는 프리팹이 필요 없음
|
||||
prefabObj = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
string prefabPath = $"Assets/Prefabs/{typeName}/{typeName}{id}.prefab";
|
||||
@@ -219,7 +241,6 @@ namespace Northbound.Editor
|
||||
EditorUtility.SetDirty(data);
|
||||
}
|
||||
|
||||
// Force save assets to disk
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
@@ -236,7 +257,6 @@ namespace Northbound.Editor
|
||||
return;
|
||||
}
|
||||
|
||||
// Load TowerData
|
||||
string[] towerDataGuids = AssetDatabase.FindAssets("t:TowerData", new[] { "Assets/Data/ScriptableObjects" });
|
||||
List<TowerData> allTowers = new List<TowerData>();
|
||||
|
||||
@@ -302,6 +322,26 @@ namespace Northbound.Editor
|
||||
return type.IsValueType ? System.Activator.CreateInstance(type) : null;
|
||||
}
|
||||
|
||||
// List<T> 타입 처리 (세미콜론 구분)
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
|
||||
{
|
||||
System.Type elementType = type.GetGenericArguments()[0];
|
||||
var elements = value.Split(';').Select(s => s.Trim()).Where(s => !string.IsNullOrEmpty(s)).ToList();
|
||||
|
||||
IList list = (IList)System.Activator.CreateInstance(type);
|
||||
|
||||
foreach (string element in elements)
|
||||
{
|
||||
object elementValue = ParseValue(element, elementType);
|
||||
if (elementValue != null)
|
||||
{
|
||||
list.Add(elementValue);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
if (type == typeof(int))
|
||||
{
|
||||
int result;
|
||||
|
||||
@@ -45,52 +45,38 @@ namespace Northbound.Editor
|
||||
|
||||
private static void SetupPrefabComponents(GameObject prefab, PlayerData playerData)
|
||||
{
|
||||
var networkController = prefab.GetComponent<NetworkPlayerController>();
|
||||
if (networkController != null)
|
||||
// PlayerStats에 모든 스탯 설정
|
||||
var playerStats = prefab.GetComponent<PlayerStats>();
|
||||
if (playerStats != null)
|
||||
{
|
||||
SerializedObject so = new SerializedObject(networkController);
|
||||
so.FindProperty("moveSpeed").floatValue = playerData.moveSpeed;
|
||||
so.FindProperty("maxHealth").intValue = playerData.maxHp;
|
||||
SerializedObject so = new SerializedObject(playerStats);
|
||||
so.FindProperty("baseMaxHp").intValue = playerData.maxHp;
|
||||
so.FindProperty("baseDamage").intValue = playerData.atkDamage;
|
||||
so.FindProperty("baseCapacity").intValue = playerData.capacity;
|
||||
so.FindProperty("baseManpower").floatValue = playerData.manpower;
|
||||
so.FindProperty("baseMoveSpeed").floatValue = playerData.moveSpeed;
|
||||
so.FindProperty("baseSight").floatValue = playerData.sight;
|
||||
so.FindProperty("baseAttackRange").floatValue = playerData.atkRange;
|
||||
so.ApplyModifiedProperties();
|
||||
Debug.Log($"[PlayerPrefabSetup] Updated NetworkPlayerController: moveSpeed={playerData.moveSpeed}, maxHealth={playerData.maxHp}");
|
||||
Debug.Log($"[PlayerPrefabSetup] Updated PlayerStats: " +
|
||||
$"maxHp={playerData.maxHp}, damage={playerData.atkDamage}, " +
|
||||
$"capacity={playerData.capacity}, manpower={playerData.manpower}, " +
|
||||
$"moveSpeed={playerData.moveSpeed}, sight={playerData.sight}, " +
|
||||
$"attackRange={playerData.atkRange}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[PlayerPrefabSetup] PlayerStats component not found on prefab!");
|
||||
}
|
||||
|
||||
// AttackAction의 attackCooldown은 별도 설정 (스탯이 아님)
|
||||
var attackAction = prefab.GetComponent<AttackAction>();
|
||||
if (attackAction != null)
|
||||
{
|
||||
SerializedObject so = new SerializedObject(attackAction);
|
||||
so.FindProperty("attackRange").intValue = playerData.atkRange;
|
||||
so.FindProperty("attackDamage").intValue = playerData.atkDamage;
|
||||
so.FindProperty("attackCooldown").floatValue = playerData.atkIntervalSec;
|
||||
so.ApplyModifiedProperties();
|
||||
Debug.Log($"[PlayerPrefabSetup] Updated AttackAction: attackRange={playerData.atkRange}, attackDamage={playerData.atkDamage}, attackCooldown={playerData.atkIntervalSec}");
|
||||
}
|
||||
|
||||
var visionProvider = prefab.GetComponent<PlayerVisionProvider>();
|
||||
if (visionProvider != null)
|
||||
{
|
||||
SerializedObject so = new SerializedObject(visionProvider);
|
||||
so.FindProperty("visionRange").floatValue = playerData.sight;
|
||||
so.ApplyModifiedProperties();
|
||||
Debug.Log($"[PlayerPrefabSetup] Updated PlayerVisionProvider: visionRange={playerData.sight}");
|
||||
}
|
||||
|
||||
var resourceInventory = prefab.GetComponent<PlayerResourceInventory>();
|
||||
if (resourceInventory != null)
|
||||
{
|
||||
SerializedObject so = new SerializedObject(resourceInventory);
|
||||
so.FindProperty("maxResourceCapacity").intValue = playerData.capacity;
|
||||
so.ApplyModifiedProperties();
|
||||
Debug.Log($"[PlayerPrefabSetup] Updated PlayerResourceInventory: maxResourceCapacity={playerData.capacity}");
|
||||
}
|
||||
|
||||
var playerInteraction = prefab.GetComponent<PlayerInteraction>();
|
||||
if (playerInteraction != null)
|
||||
{
|
||||
SerializedObject so = new SerializedObject(playerInteraction);
|
||||
so.FindProperty("workPower").floatValue = playerData.manpower;
|
||||
so.ApplyModifiedProperties();
|
||||
Debug.Log($"[PlayerPrefabSetup] Updated PlayerInteraction: workPower={playerData.manpower}");
|
||||
Debug.Log($"[PlayerPrefabSetup] Updated AttackAction: attackCooldown={playerData.atkIntervalSec}");
|
||||
}
|
||||
|
||||
EditorUtility.SetDirty(prefab);
|
||||
|
||||
23
Assets/Scripts/Editor/UpgradePrefabSetup.cs
Normal file
23
Assets/Scripts/Editor/UpgradePrefabSetup.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Northbound.Data;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Northbound.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Upgrade 타입은 프리팹이 필요 없으므로 빈 구현
|
||||
/// </summary>
|
||||
public class UpgradePrefabSetup : IPrefabSetup
|
||||
{
|
||||
public string GetTemplateName()
|
||||
{
|
||||
return ""; // 템플릿 필요 없음
|
||||
}
|
||||
|
||||
public void SetupPrefab(GameObject prefab, ScriptableObject data)
|
||||
{
|
||||
// Upgrade는 프리팹이 필요 없음
|
||||
Debug.LogWarning($"[UpgradePrefabSetup] Upgrade 타입은 프리팹이 필요하지 않습니다.");
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Editor/UpgradePrefabSetup.cs.meta
Normal file
2
Assets/Scripts/Editor/UpgradePrefabSetup.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f33f085cffff92c489c74fc11a89fa49
|
||||
Reference in New Issue
Block a user