diff --git a/Assembly-CSharp-Editor.csproj b/Assembly-CSharp-Editor.csproj
index 4901f29..04846a1 100644
--- a/Assembly-CSharp-Editor.csproj
+++ b/Assembly-CSharp-Editor.csproj
@@ -61,6 +61,7 @@
+
diff --git a/Assets/Prefabs/Player.prefab b/Assets/Prefabs/Player/Player.prefab
similarity index 99%
rename from Assets/Prefabs/Player.prefab
rename to Assets/Prefabs/Player/Player.prefab
index b6ee481..ea50b18 100644
--- a/Assets/Prefabs/Player.prefab
+++ b/Assets/Prefabs/Player/Player.prefab
@@ -81,7 +81,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::NetworkPlayerController
ShowTopMostFoldoutHeaderGroup: 1
- moveSpeed: 5
+ moveSpeed: 10
rotationSpeed: 10
initialTeam: 1
maxHealth: 100
@@ -211,9 +211,9 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Northbound.AttackAction
ShowTopMostFoldoutHeaderGroup: 1
- attackRange: 3
- attackDamage: 100
- attackCooldown: 0.5
+ attackRange: 6
+ attackDamage: 200
+ attackCooldown: 1
attackableLayer:
serializedVersion: 2
m_Bits: 4294967295
@@ -260,7 +260,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Northbound.PlayerResourceInventory
ShowTopMostFoldoutHeaderGroup: 1
- maxResourceCapacity: 50
+ maxResourceCapacity: 100
--- !u!114 &2148255267416253297
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -274,7 +274,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Northbound.PlayerVisionProvider
ShowTopMostFoldoutHeaderGroup: 1
- visionRange: 10
+ visionRange: 20
--- !u!1001 &1445453803682481668
PrefabInstance:
m_ObjectHideFlags: 0
diff --git a/Assets/Prefabs/Player.prefab.meta b/Assets/Prefabs/Player/Player.prefab.meta
similarity index 100%
rename from Assets/Prefabs/Player.prefab.meta
rename to Assets/Prefabs/Player/Player.prefab.meta
diff --git a/Assets/Scripts/Editor/CSVToSOImporter.cs b/Assets/Scripts/Editor/CSVToSOImporter.cs
index 4bd8d83..8955c3f 100644
--- a/Assets/Scripts/Editor/CSVToSOImporter.cs
+++ b/Assets/Scripts/Editor/CSVToSOImporter.cs
@@ -59,7 +59,8 @@ namespace Northbound.Editor
prefabSetups = new Dictionary
{
{ "Monster", new MonsterPrefabSetup() },
- { "Tower", new TowerPrefabSetup() }
+ { "Tower", new TowerPrefabSetup() },
+ { "Player", new PlayerPrefabSetup() }
};
}
@@ -112,7 +113,14 @@ namespace Northbound.Editor
}
}
- Debug.Log($"[CSVToSOImporter] {typeName}: {successCount} prefabs created/updated");
+ if (typeName == "Player")
+ {
+ Debug.Log($"[CSVToSOImporter] {typeName}: Player prefab updated successfully");
+ }
+ else
+ {
+ Debug.Log($"[CSVToSOImporter] {typeName}: {successCount} prefabs created/updated");
+ }
// If towers were imported, auto-configure BuildingManager
// TowerData now extends BuildingData, so it can be used directly!
@@ -174,16 +182,25 @@ namespace Northbound.Editor
}
}
- string prefabPath = $"Assets/Prefabs/{typeName}/{typeName}{id}.prefab";
- Directory.CreateDirectory(Path.Combine(Application.dataPath, $"Prefabs/{typeName}"));
+ GameObject prefabObj;
+ if (typeName == "Player")
+ {
+ PlayerPrefabSetup.UpdatePlayerPrefab((PlayerData)data);
+ prefabObj = null;
+ }
+ else
+ {
+ string prefabPath = $"Assets/Prefabs/{typeName}/{typeName}{id}.prefab";
+ Directory.CreateDirectory(Path.Combine(Application.dataPath, $"Prefabs/{typeName}"));
- GameObject prefabInstance = GameObject.Instantiate(template);
- prefabInstance.name = $"{typeName}{id}";
+ GameObject prefabInstance = GameObject.Instantiate(template);
+ prefabInstance.name = $"{typeName}{id}";
- prefabSetup.SetupPrefab(prefabInstance, data);
+ prefabSetup.SetupPrefab(prefabInstance, data);
- GameObject prefabObj = PrefabUtility.SaveAsPrefabAsset(prefabInstance, prefabPath);
- GameObject.DestroyImmediate(prefabInstance);
+ prefabObj = PrefabUtility.SaveAsPrefabAsset(prefabInstance, prefabPath);
+ GameObject.DestroyImmediate(prefabInstance);
+ }
// Now set the prefab reference on data
if (data is BuildingData buildingData)
diff --git a/Assets/Scripts/Editor/PlayerPrefabSetup.cs b/Assets/Scripts/Editor/PlayerPrefabSetup.cs
new file mode 100644
index 0000000..bb66647
--- /dev/null
+++ b/Assets/Scripts/Editor/PlayerPrefabSetup.cs
@@ -0,0 +1,92 @@
+using Northbound.Data;
+using UnityEditor;
+using UnityEngine;
+
+namespace Northbound.Editor
+{
+ public class PlayerPrefabSetup : IPrefabSetup
+ {
+ public string GetTemplateName()
+ {
+ return "Player";
+ }
+
+ public static void UpdatePlayerPrefab(PlayerData playerData)
+ {
+ string prefabPath = playerData.prefabPath;
+ if (!prefabPath.EndsWith(".prefab"))
+ {
+ prefabPath += ".prefab";
+ }
+
+ GameObject prefabObj = AssetDatabase.LoadAssetAtPath(prefabPath);
+ if (prefabObj == null)
+ {
+ Debug.LogError($"[PlayerPrefabSetup] Player prefab not found at: {prefabPath}");
+ return;
+ }
+
+ SetupPrefabComponents(prefabObj, playerData);
+ EditorUtility.SetDirty(prefabObj);
+ PrefabUtility.SavePrefabAsset(prefabObj);
+ Debug.Log($"[PlayerPrefabSetup] Player prefab updated from: {prefabPath}");
+ }
+
+ public void SetupPrefab(GameObject prefab, ScriptableObject data)
+ {
+ if (!(data is PlayerData playerData))
+ {
+ Debug.LogWarning($"[PlayerPrefabSetup] Expected PlayerData, got {data.GetType().Name}");
+ return;
+ }
+
+ SetupPrefabComponents(prefab, playerData);
+ }
+
+ private static void SetupPrefabComponents(GameObject prefab, PlayerData playerData)
+ {
+ var networkController = prefab.GetComponent();
+ if (networkController != null)
+ {
+ SerializedObject so = new SerializedObject(networkController);
+ so.FindProperty("moveSpeed").floatValue = playerData.moveSpeed;
+ so.FindProperty("maxHealth").intValue = playerData.maxHp;
+ so.ApplyModifiedProperties();
+ Debug.Log($"[PlayerPrefabSetup] Updated NetworkPlayerController: moveSpeed={playerData.moveSpeed}, maxHealth={playerData.maxHp}");
+ }
+
+ var attackAction = prefab.GetComponent();
+ 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();
+ if (visionProvider != null)
+ {
+ SerializedObject so = new SerializedObject(visionProvider);
+ so.FindProperty("visionRange").floatValue = playerData.visionRadius;
+ so.ApplyModifiedProperties();
+ Debug.Log($"[PlayerPrefabSetup] Updated PlayerVisionProvider: visionRange={playerData.visionRadius}");
+ }
+
+ var resourceInventory = prefab.GetComponent();
+ if (resourceInventory != null)
+ {
+ SerializedObject so = new SerializedObject(resourceInventory);
+ so.FindProperty("maxResourceCapacity").intValue = playerData.capacity;
+ so.ApplyModifiedProperties();
+ Debug.Log($"[PlayerPrefabSetup] Updated PlayerResourceInventory: maxResourceCapacity={playerData.capacity}");
+ }
+
+ EditorUtility.SetDirty(prefab);
+ PrefabUtility.SavePrefabAsset(prefab);
+ Debug.Log($"[PlayerPrefabSetup] Player prefab updated successfully from {playerData.name}");
+ }
+ }
+}
diff --git a/Assets/Scripts/Editor/PlayerPrefabSetup.cs.meta b/Assets/Scripts/Editor/PlayerPrefabSetup.cs.meta
new file mode 100644
index 0000000..a270d0c
--- /dev/null
+++ b/Assets/Scripts/Editor/PlayerPrefabSetup.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: e5d9fa32f3480914abc8b2320d315554
\ No newline at end of file
diff --git a/GameData/Player.csv b/GameData/Player.csv
index 28ff483..a5e37e3 100644
--- a/GameData/Player.csv
+++ b/GameData/Player.csv
@@ -1,2 +1,2 @@
-id,memo,move_speed,vision_radius,capacity,manpower,max_hp,atk_range,atk_damage,atk_interval_sec,prefab_path
-1,,10,20,100,10,100,6,200,1,Assets/Prefabs/Player
+id,memo,move_speed,vision_radius,capacity,manpower,max_hp,atk_range,atk_damage,atk_interval_sec,prefab_path
+1,,10,20,100,10,100,6,200,1,Assets/Prefabs/Player/Player