데이터파이프라인 타워 부분 개선
This commit is contained in:
353
Assets/Scripts/Editor/CSVToSOImporter.cs
Normal file
353
Assets/Scripts/Editor/CSVToSOImporter.cs
Normal file
@@ -0,0 +1,353 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using Northbound.Data;
|
||||
|
||||
namespace Northbound.Editor
|
||||
{
|
||||
public class CSVToSOImporter : EditorWindow
|
||||
{
|
||||
private static Dictionary<string, IPrefabSetup> prefabSetups;
|
||||
|
||||
[MenuItem("Tools/Data/Import All CSV")]
|
||||
public static void ImportAllCSV()
|
||||
{
|
||||
InitializePrefabSetups();
|
||||
string dataPath = Path.Combine(Application.dataPath, "../GameData");
|
||||
|
||||
if (!Directory.Exists(dataPath))
|
||||
{
|
||||
Debug.LogError("[CSVToSOImporter] GameData folder not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
string[] csvFiles = Directory.GetFiles(dataPath, "*.csv");
|
||||
int successCount = 0;
|
||||
int failCount = 0;
|
||||
bool towerImported = false;
|
||||
|
||||
foreach (string csvFile in csvFiles)
|
||||
{
|
||||
string fileName = Path.GetFileNameWithoutExtension(csvFile);
|
||||
if (ImportCSV(fileName))
|
||||
{
|
||||
successCount++;
|
||||
if (fileName == "Tower")
|
||||
towerImported = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log($"<color=green>[CSVToSOImporter] Import complete: {successCount} succeeded, {failCount} failed</color>");
|
||||
|
||||
if (towerImported)
|
||||
{
|
||||
AutoConfigureBuildingManager();
|
||||
}
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
private static void InitializePrefabSetups()
|
||||
{
|
||||
prefabSetups = new Dictionary<string, IPrefabSetup>
|
||||
{
|
||||
{ "Monster", new MonsterPrefabSetup() },
|
||||
{ "Tower", new TowerPrefabSetup() }
|
||||
};
|
||||
}
|
||||
|
||||
private static bool ImportCSV(string typeName)
|
||||
{
|
||||
string csvPath = Path.Combine(Application.dataPath, "../GameData", $"{typeName}.csv");
|
||||
|
||||
if (!File.Exists(csvPath))
|
||||
{
|
||||
Debug.LogWarning($"[CSVToSOImporter] CSV file not found: {csvPath}");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!prefabSetups.ContainsKey(typeName))
|
||||
{
|
||||
Debug.LogWarning($"[CSVToSOImporter] No prefab setup found for type: {typeName}");
|
||||
return false;
|
||||
}
|
||||
|
||||
IPrefabSetup prefabSetup = prefabSetups[typeName];
|
||||
string templateName = prefabSetup.GetTemplateName();
|
||||
string templatePath = $"Assets/Data/Templates/{templateName}.prefab";
|
||||
|
||||
GameObject template = AssetDatabase.LoadAssetAtPath<GameObject>(templatePath);
|
||||
if (template == null)
|
||||
{
|
||||
Debug.LogError($"[CSVToSOImporter] Template not found: {templatePath}");
|
||||
return false;
|
||||
}
|
||||
|
||||
string[] csvLines = File.ReadAllLines(csvPath);
|
||||
if (csvLines.Length < 2)
|
||||
{
|
||||
Debug.LogWarning($"[CSVToSOImporter] CSV file is empty or has no data: {csvPath}");
|
||||
return false;
|
||||
}
|
||||
|
||||
string[] headers = ParseCSVLine(csvLines[0]);
|
||||
int successCount = 0;
|
||||
|
||||
for (int i = 1; i < csvLines.Length; i++)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(csvLines[i]))
|
||||
continue;
|
||||
|
||||
string[] values = ParseCSVLine(csvLines[i]);
|
||||
if (CreatePrefabFromRow(typeName, headers, values, template, prefabSetup))
|
||||
{
|
||||
successCount++;
|
||||
}
|
||||
}
|
||||
|
||||
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!
|
||||
if (typeName == "Tower")
|
||||
{
|
||||
Debug.Log($"<color=cyan>[CSVToSOImporter] Tower import complete, TowerData extends BuildingData now!</color>");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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}"));
|
||||
|
||||
int id = 0;
|
||||
for (int i = 0; i < headers.Length && i < values.Length; i++)
|
||||
{
|
||||
if (headers[i].ToLower() == "id")
|
||||
{
|
||||
int.TryParse(values[i], out id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (id == 0)
|
||||
{
|
||||
Debug.LogWarning($"[CSVToSOImporter] No valid ID found in row");
|
||||
return false;
|
||||
}
|
||||
|
||||
ScriptableObject data;
|
||||
string soAssetPath = $"{soPath}/{typeName}{id}.asset";
|
||||
data = AssetDatabase.LoadAssetAtPath<ScriptableObject>(soAssetPath);
|
||||
|
||||
bool isNew = false;
|
||||
if (data == null)
|
||||
{
|
||||
data = CreateInstance(typeName + "Data");
|
||||
isNew = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < headers.Length && i < values.Length; i++)
|
||||
{
|
||||
string fieldName = CSVToCamelCase(headers[i]);
|
||||
var field = data.GetType().GetField(fieldName);
|
||||
if (field != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
object value = ParseValue(values[i], field.FieldType);
|
||||
field.SetValue(data, value);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogWarning($"[CSVToSOImporter] Failed to set {fieldName}: {e.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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}";
|
||||
|
||||
prefabSetup.SetupPrefab(prefabInstance, data);
|
||||
|
||||
GameObject prefabObj = PrefabUtility.SaveAsPrefabAsset(prefabInstance, prefabPath);
|
||||
GameObject.DestroyImmediate(prefabInstance);
|
||||
|
||||
// Now set the prefab reference on data
|
||||
if (data is BuildingData buildingData)
|
||||
{
|
||||
buildingData.prefab = prefabObj;
|
||||
Debug.Log($"[CSVToSOImporter] Set prefab reference: {buildingData.name} -> {prefabObj.name}");
|
||||
}
|
||||
|
||||
// Save data asset
|
||||
if (isNew)
|
||||
{
|
||||
AssetDatabase.CreateAsset(data, soAssetPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.SetDirty(data);
|
||||
}
|
||||
|
||||
// Force save assets to disk
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void AutoConfigureBuildingManager()
|
||||
{
|
||||
BuildingManager buildingManager = GameObject.FindObjectOfType<BuildingManager>();
|
||||
|
||||
if (buildingManager == null)
|
||||
{
|
||||
Debug.LogError("<color=red>[CSVToSOImporter] BuildingManager not found in scene! Please add a BuildingManager component to a GameObject in your scene.</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
// Load TowerData (which extends BuildingData)
|
||||
string[] towerDataGuids = AssetDatabase.FindAssets("t:TowerData", new[] { "Assets/Data/ScriptableObjects" });
|
||||
List<BuildingData> allTowers = new List<BuildingData>();
|
||||
|
||||
Debug.Log($"<color=cyan>[CSVToSOImporter] Found {towerDataGuids.Length} TowerData assets</color>");
|
||||
|
||||
foreach (string guid in towerDataGuids)
|
||||
{
|
||||
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
TowerData towerData = AssetDatabase.LoadAssetAtPath<TowerData>(assetPath);
|
||||
|
||||
if (towerData == null)
|
||||
{
|
||||
Debug.LogWarning($"[CSVToSOImporter] Failed to load TowerData: {assetPath}");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (towerData.prefab == null)
|
||||
{
|
||||
Debug.LogWarning($"<color=yellow>[CSVToSOImporter] TowerData {towerData.name} has no prefab reference - skipping</color>");
|
||||
continue;
|
||||
}
|
||||
|
||||
allTowers.Add(towerData);
|
||||
Debug.Log($"<color=green>[CSVToSOImporter] Added tower: {towerData.buildingName}</color>");
|
||||
}
|
||||
|
||||
if (allTowers.Count == 0)
|
||||
{
|
||||
Debug.LogWarning("<color=yellow>[CSVToSOImporter] No TowerData with valid prefabs found!</color>");
|
||||
Debug.LogWarning("<color=yellow>Run 'Northbound > Diagnose Tower System' to see what's wrong</color>");
|
||||
return;
|
||||
}
|
||||
|
||||
allTowers.Sort((a, b) => string.Compare(a.buildingName, b.buildingName));
|
||||
|
||||
buildingManager.availableBuildings.Clear();
|
||||
foreach (var towerData in allTowers)
|
||||
{
|
||||
buildingManager.availableBuildings.Add(towerData);
|
||||
}
|
||||
|
||||
EditorUtility.SetDirty(buildingManager);
|
||||
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
|
||||
|
||||
Debug.Log($"<color=cyan>========================================</color>");
|
||||
Debug.Log($"<color=cyan>🏗️ TOWER IMPORT COMPLETE!</color>");
|
||||
Debug.Log($"<color=cyan>========================================</color>");
|
||||
Debug.Log($"<color=green>✓ BuildingManager automatically configured!</color>");
|
||||
Debug.Log($"<color=green>✓ Added {allTowers.Count} TowerData to availableBuildings list</color>");
|
||||
Debug.Log($"<color=green>✓ Ready to play - all towers will appear in quickslot!</color>");
|
||||
Debug.Log($"<color=cyan>========================================</color>");
|
||||
foreach (var towerData in allTowers)
|
||||
{
|
||||
Debug.Log($"<color=green> - {towerData.buildingName}</color>");
|
||||
}
|
||||
Debug.Log($"<color=cyan>========================================</color>");
|
||||
}
|
||||
|
||||
private static object ParseValue(string value, System.Type type)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
return type.IsValueType ? System.Activator.CreateInstance(type) : null;
|
||||
}
|
||||
|
||||
if (type == typeof(int))
|
||||
{
|
||||
int result;
|
||||
if (int.TryParse(value, out result)) return result;
|
||||
}
|
||||
else if (type == typeof(float))
|
||||
{
|
||||
float result;
|
||||
if (float.TryParse(value, out result)) return result;
|
||||
}
|
||||
else if (type == typeof(bool))
|
||||
{
|
||||
bool result;
|
||||
if (bool.TryParse(value, out result)) return result;
|
||||
}
|
||||
else if (type == typeof(string))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return type.IsValueType ? System.Activator.CreateInstance(type) : null;
|
||||
}
|
||||
|
||||
private static string CSVToCamelCase(string csvName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(csvName))
|
||||
return csvName;
|
||||
|
||||
string[] parts = csvName.Split('_');
|
||||
for (int i = 1; i < parts.Length; i++)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(parts[i]))
|
||||
{
|
||||
parts[i] = char.ToUpper(parts[i][0]) + parts[i].Substring(1);
|
||||
}
|
||||
}
|
||||
return string.Join("", parts);
|
||||
}
|
||||
|
||||
private static string[] ParseCSVLine(string line)
|
||||
{
|
||||
List<string> result = new List<string>();
|
||||
bool inQuotes = false;
|
||||
string current = "";
|
||||
|
||||
foreach (char c in line)
|
||||
{
|
||||
if (c == '"')
|
||||
{
|
||||
inQuotes = !inQuotes;
|
||||
}
|
||||
else if (c == ',' && !inQuotes)
|
||||
{
|
||||
result.Add(current);
|
||||
current = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
current += c;
|
||||
}
|
||||
}
|
||||
result.Add(current);
|
||||
return result.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Editor/CSVToSOImporter.cs.meta
Normal file
2
Assets/Scripts/Editor/CSVToSOImporter.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c00f900c9a822184dbb4dc85440d40dd
|
||||
@@ -2,6 +2,7 @@ using Unity.Netcode;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using Northbound;
|
||||
|
||||
namespace Northbound.Editor
|
||||
{
|
||||
@@ -147,9 +148,35 @@ namespace Northbound.Editor
|
||||
|
||||
private static void SetupTowerComponents(GameObject go)
|
||||
{
|
||||
Transform t = go.transform;
|
||||
t.localPosition = Vector3.zero;
|
||||
t.localRotation = Quaternion.identity;
|
||||
t.localScale = Vector3.one;
|
||||
|
||||
if (go.GetComponent<NetworkObject>() == null)
|
||||
go.AddComponent<NetworkObject>();
|
||||
|
||||
if (go.GetComponent<Building>() == null)
|
||||
go.AddComponent<Building>();
|
||||
|
||||
if (go.GetComponent<TowerDataComponent>() == null)
|
||||
go.AddComponent<TowerDataComponent>();
|
||||
|
||||
if (go.GetComponent<BoxCollider>() == null)
|
||||
{
|
||||
BoxCollider collider = go.AddComponent<BoxCollider>();
|
||||
collider.size = new Vector3(1f, 2f, 1f);
|
||||
collider.center = new Vector3(0f, 1f, 0f);
|
||||
}
|
||||
|
||||
if (go.GetComponent<NavMeshObstacle>() == null)
|
||||
{
|
||||
NavMeshObstacle obstacle = go.AddComponent<NavMeshObstacle>();
|
||||
obstacle.shape = NavMeshObstacleShape.Box;
|
||||
obstacle.size = new Vector3(1f, 1f, 1f);
|
||||
obstacle.center = new Vector3(0f, 0.5f, 0f);
|
||||
}
|
||||
|
||||
int defaultLayer = LayerMask.NameToLayer("Default");
|
||||
if (defaultLayer >= 0)
|
||||
{
|
||||
|
||||
80
Assets/Scripts/Editor/TowerPopulator.cs
Normal file
80
Assets/Scripts/Editor/TowerPopulator.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Northbound;
|
||||
using Northbound.Data;
|
||||
|
||||
namespace Northbound.Editor
|
||||
{
|
||||
public class TowerPopulator
|
||||
{
|
||||
private const string TOWER_PREFAB_PATH = "Assets/Prefabs/Tower";
|
||||
private const string TOWER_DATA_PATH = "Assets/Data/ScriptableObjects";
|
||||
|
||||
[MenuItem("Northbound/Diagnose Tower System")]
|
||||
public static void DiagnoseTowerSystem()
|
||||
{
|
||||
Debug.Log($"<color=cyan>========================================</color>");
|
||||
Debug.Log($"<color=cyan>[TowerPopulator] DIAGNOSING TOWER SYSTEM</color>");
|
||||
Debug.Log($"<color=cyan>========================================</color>");
|
||||
|
||||
string[] prefabGuids = AssetDatabase.FindAssets("t:Tower", new[] { TOWER_PREFAB_PATH });
|
||||
Debug.Log($"<color=cyan>Tower Prefabs in Assets/Prefabs/Tower/:</color>");
|
||||
if (prefabGuids.Length == 0)
|
||||
{
|
||||
Debug.Log($"<color=red>✗ No tower prefabs found!</color>");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (string guid in prefabGuids)
|
||||
{
|
||||
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
|
||||
TowerDataComponent tower = prefab?.GetComponent<TowerDataComponent>();
|
||||
string towerStatus = tower != null && tower.towerData != null ? "<color=green>✓</color>" : "<color=red>✗</color>";
|
||||
string towerDataName = tower?.towerData?.name ?? "MISSING";
|
||||
Debug.Log($" {towerStatus} {prefab.name} - TowerDataComponent: {tower != null}, TowerData: {towerDataName}");
|
||||
}
|
||||
}
|
||||
|
||||
string[] towerDataGuids = AssetDatabase.FindAssets("t:TowerData", new[] { TOWER_DATA_PATH });
|
||||
Debug.Log($"<color=cyan>TowerData assets in Assets/Data/ScriptableObjects/:</color>");
|
||||
if (towerDataGuids.Length == 0)
|
||||
{
|
||||
Debug.Log($"<color=yellow>⚠ No TowerData assets found - Run 'Tools > Data > Import All CSV' first!</color>");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (string guid in towerDataGuids)
|
||||
{
|
||||
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
TowerData data = AssetDatabase.LoadAssetAtPath<TowerData>(assetPath);
|
||||
string prefabStatus = data?.prefab != null ? "<color=green>✓</color>" : "<color=red>✗</color>";
|
||||
Debug.Log($" {prefabStatus} {data.name} - Prefab: {data?.prefab?.name ?? "MISSING"}, BuildingName: {data?.buildingName}");
|
||||
}
|
||||
}
|
||||
|
||||
BuildingManager buildingManager = GameObject.FindObjectOfType<BuildingManager>();
|
||||
Debug.Log($"<color=cyan>BuildingManager in Scene:</color>");
|
||||
if (buildingManager == null)
|
||||
{
|
||||
Debug.Log($"<color=red>✗ BuildingManager not found in scene!</color>");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"<color=green>✓ BuildingManager found: {buildingManager.gameObject.name}</color>");
|
||||
Debug.Log($"<color=cyan> Available Buildings: {buildingManager.availableBuildings.Count}</color>");
|
||||
foreach (var building in buildingManager.availableBuildings)
|
||||
{
|
||||
string status = building?.prefab != null ? "<color=green>✓</color>" : "<color=red>✗</color>";
|
||||
string isTower = building is TowerData ? "<color=green>[Tower]</color>" : "<color>yellow>[Building]</color>";
|
||||
Debug.Log($" {status} {isTower} {building?.name ?? "MISSING"} - {building?.buildingName}");
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log($"<color=cyan>========================================</color>");
|
||||
Debug.Log($"<color=cyan>[TowerPopulator] DIAGNOSIS COMPLETE</color>");
|
||||
Debug.Log($"<color=cyan>========================================</color>");
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Editor/TowerPopulator.cs.meta
Normal file
2
Assets/Scripts/Editor/TowerPopulator.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 069a105319ca9cf4a8323e1d5357960f
|
||||
128
Assets/Scripts/Editor/TowerPrefabSetup.cs
Normal file
128
Assets/Scripts/Editor/TowerPrefabSetup.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
using Northbound.Data;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
|
||||
namespace Northbound.Editor
|
||||
{
|
||||
public class TowerPrefabSetup : IPrefabSetup
|
||||
{
|
||||
public string GetTemplateName()
|
||||
{
|
||||
return "TowerTemplate";
|
||||
}
|
||||
|
||||
public void SetupPrefab(GameObject prefab, ScriptableObject data)
|
||||
{
|
||||
if (!(data is TowerData towerData))
|
||||
{
|
||||
Debug.LogWarning($"[TowerPrefabSetup] Expected TowerData, got {data.GetType().Name}");
|
||||
return;
|
||||
}
|
||||
|
||||
var towerDataComponent = prefab.GetComponent<TowerDataComponent>();
|
||||
if (towerDataComponent == null)
|
||||
{
|
||||
towerDataComponent = prefab.AddComponent<TowerDataComponent>();
|
||||
Debug.Log($"[TowerPrefabSetup] Added TowerDataComponent component");
|
||||
}
|
||||
|
||||
if (towerDataComponent != null)
|
||||
{
|
||||
towerDataComponent.towerData = towerData;
|
||||
}
|
||||
|
||||
// TowerData now extends BuildingData, so set prefab reference
|
||||
towerData.prefab = prefab;
|
||||
|
||||
// Ensure TowerData fields are synced to BuildingData
|
||||
towerData.EnsureSynced();
|
||||
|
||||
Transform modelTransform = null;
|
||||
|
||||
if (!string.IsNullOrEmpty(towerData.modelPath))
|
||||
{
|
||||
RemoveOldModel(prefab);
|
||||
|
||||
if (towerData.modelPath.ToLower().EndsWith(".fbx"))
|
||||
{
|
||||
GameObject fbxModel = AssetDatabase.LoadAssetAtPath<GameObject>(towerData.modelPath);
|
||||
if (fbxModel != null)
|
||||
{
|
||||
GameObject fbxInstance = GameObject.Instantiate(fbxModel);
|
||||
fbxInstance.name = "Model";
|
||||
fbxInstance.transform.SetParent(prefab.transform, false);
|
||||
fbxInstance.transform.localPosition = Vector3.zero;
|
||||
fbxInstance.transform.localRotation = Quaternion.identity;
|
||||
|
||||
// Set model scale based on sizeX/sizeY/sizeZ
|
||||
fbxInstance.transform.localScale = new Vector3(towerData.sizeX, towerData.sizeZ, towerData.sizeY);
|
||||
|
||||
modelTransform = fbxInstance.transform;
|
||||
|
||||
Debug.Log($"[TowerPrefabSetup] Applied FBX model: {towerData.modelPath} with scale {towerData.sizeX}x{towerData.sizeZ}x{towerData.sizeY}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[TowerPrefabSetup] Could not load FBX model: {towerData.modelPath}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var meshFilter = prefab.GetComponent<MeshFilter>();
|
||||
if (meshFilter == null)
|
||||
{
|
||||
meshFilter = prefab.AddComponent<MeshFilter>();
|
||||
}
|
||||
|
||||
var renderer = prefab.GetComponent<MeshRenderer>();
|
||||
if (renderer == null)
|
||||
{
|
||||
renderer = prefab.AddComponent<MeshRenderer>();
|
||||
}
|
||||
|
||||
Mesh mesh = AssetDatabase.LoadAssetAtPath<Mesh>(towerData.modelPath);
|
||||
if (mesh != null)
|
||||
{
|
||||
meshFilter.sharedMesh = mesh;
|
||||
|
||||
modelTransform = renderer.transform;
|
||||
modelTransform.localScale = new Vector3(towerData.sizeX, towerData.sizeZ, towerData.sizeY);
|
||||
|
||||
Debug.Log($"[TowerPrefabSetup] Applied mesh: {towerData.modelPath} with scale {towerData.sizeX}x{towerData.sizeZ}x{towerData.sizeY}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[TowerPrefabSetup] Could not load mesh: {towerData.modelPath}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var collider = prefab.GetComponent<BoxCollider>();
|
||||
if (collider == null)
|
||||
{
|
||||
collider = prefab.AddComponent<BoxCollider>();
|
||||
}
|
||||
collider.size = new Vector3(towerData.sizeX, towerData.sizeZ, towerData.sizeY);
|
||||
collider.center = new Vector3(0f, towerData.sizeZ / 2f, 0f);
|
||||
|
||||
var navObstacle = prefab.GetComponent<NavMeshObstacle>();
|
||||
if (navObstacle == null)
|
||||
{
|
||||
navObstacle = prefab.AddComponent<NavMeshObstacle>();
|
||||
navObstacle.shape = NavMeshObstacleShape.Box;
|
||||
}
|
||||
navObstacle.size = new Vector3(towerData.sizeX, towerData.sizeZ, towerData.sizeY);
|
||||
navObstacle.center = new Vector3(0f, towerData.sizeZ / 2f, 0f);
|
||||
}
|
||||
|
||||
private void RemoveOldModel(GameObject prefab)
|
||||
{
|
||||
Transform oldModel = prefab.transform.Find("Model");
|
||||
if (oldModel != null)
|
||||
{
|
||||
GameObject.DestroyImmediate(oldModel.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Editor/TowerPrefabSetup.cs.meta
Normal file
2
Assets/Scripts/Editor/TowerPrefabSetup.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea17487cde4842d45baf5eb92943142a
|
||||
Reference in New Issue
Block a user