From fe046611b01f79a8bb7d504deebd47f7b27bf090 Mon Sep 17 00:00:00 2001 From: dal4segno Date: Sun, 1 Feb 2026 11:31:50 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=ED=8C=8C=EC=9D=B4?= =?UTF-8?q?=ED=94=84=EB=9D=BC=EC=9D=B8=20=ED=83=80=EC=9B=8C=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assembly-CSharp-Editor.csproj | 20 +- Assembly-CSharp.csproj | 18 +- .../Data/ScriptableObjects/Tower/Tower1.asset | 52 +++ .../ScriptableObjects/Tower/Tower1.asset.meta | 8 + .../Data/ScriptableObjects/Tower/Tower2.asset | 52 +++ .../ScriptableObjects/Tower/Tower2.asset.meta | 8 + Assets/Data/Scripts/DataClasses/TowerData.cs | 41 +- Assets/Data/Templates/TowerTemplate.prefab | 146 ++++++++ .../Data/Templates/TowerTemplate.prefab.meta | 7 + Assets/DefaultNetworkPrefabs.asset | 15 + Assets/Models/building_tower_B_blue.fbx | Bin 0 -> 93068 bytes Assets/Models/building_tower_B_blue.fbx.meta | 110 ++++++ Assets/Models/wall_straight.fbx | Bin 0 -> 31292 bytes Assets/Models/wall_straight.fbx.meta | 110 ++++++ Assets/Prefabs/Monster/Monster101.prefab | 2 +- Assets/Prefabs/Monster/Monster105.prefab | 4 +- Assets/Prefabs/Player.prefab | 2 +- Assets/Prefabs/Tower/Tower1.prefab | 342 +++++++++++++++++ Assets/Prefabs/Tower/Tower1.prefab.meta | 7 + Assets/Prefabs/Tower/Tower2.prefab | 251 +++++++++++++ Assets/Prefabs/Tower/Tower2.prefab.meta | 7 + Assets/Scenes/GameMain.unity | 37 +- Assets/ScriptableObjects.meta | 8 + Assets/ScriptableObjects/Monster.meta | 8 + Assets/ScriptableObjects/Tower.meta | 8 + Assets/Scripts/BuildingPlacement.cs | 47 ++- Assets/Scripts/BuildingQuickslotUI.cs | 11 +- Assets/Scripts/Editor/CSVToSOImporter.cs | 353 ++++++++++++++++++ Assets/Scripts/Editor/CSVToSOImporter.cs.meta | 2 + Assets/Scripts/Editor/TemplateCreator.cs | 27 ++ Assets/Scripts/Editor/TowerPopulator.cs | 80 ++++ Assets/Scripts/Editor/TowerPopulator.cs.meta | 2 + Assets/Scripts/Editor/TowerPrefabSetup.cs | 128 +++++++ .../Scripts/Editor/TowerPrefabSetup.cs.meta | 2 + Assets/Scripts/TowerDataComponent.cs | 26 ++ Assets/Scripts/TowerDataComponent.cs.meta | 2 + ExternAttributes.Editor.csproj | 1 + FlatKit.Utils.Editor.csproj | 1 + GameData/.Tower_schema.json | 10 +- GameData/Tower.csv | 6 +- TOWER_CSV_IMPORTER.md | 138 +++++++ TOWER_QUICKSLOT_SETUP.md | 120 ++++++ ...y.RenderPipelines.Universal.Runtime.csproj | 7 +- 43 files changed, 2181 insertions(+), 45 deletions(-) create mode 100644 Assets/Data/ScriptableObjects/Tower/Tower1.asset create mode 100644 Assets/Data/ScriptableObjects/Tower/Tower1.asset.meta create mode 100644 Assets/Data/ScriptableObjects/Tower/Tower2.asset create mode 100644 Assets/Data/ScriptableObjects/Tower/Tower2.asset.meta create mode 100644 Assets/Data/Templates/TowerTemplate.prefab create mode 100644 Assets/Data/Templates/TowerTemplate.prefab.meta create mode 100644 Assets/Models/building_tower_B_blue.fbx create mode 100644 Assets/Models/building_tower_B_blue.fbx.meta create mode 100644 Assets/Models/wall_straight.fbx create mode 100644 Assets/Models/wall_straight.fbx.meta create mode 100644 Assets/Prefabs/Tower/Tower1.prefab create mode 100644 Assets/Prefabs/Tower/Tower1.prefab.meta create mode 100644 Assets/Prefabs/Tower/Tower2.prefab create mode 100644 Assets/Prefabs/Tower/Tower2.prefab.meta create mode 100644 Assets/ScriptableObjects.meta create mode 100644 Assets/ScriptableObjects/Monster.meta create mode 100644 Assets/ScriptableObjects/Tower.meta create mode 100644 Assets/Scripts/Editor/CSVToSOImporter.cs create mode 100644 Assets/Scripts/Editor/CSVToSOImporter.cs.meta create mode 100644 Assets/Scripts/Editor/TowerPopulator.cs create mode 100644 Assets/Scripts/Editor/TowerPopulator.cs.meta create mode 100644 Assets/Scripts/Editor/TowerPrefabSetup.cs create mode 100644 Assets/Scripts/Editor/TowerPrefabSetup.cs.meta create mode 100644 Assets/Scripts/TowerDataComponent.cs create mode 100644 Assets/Scripts/TowerDataComponent.cs.meta create mode 100644 TOWER_CSV_IMPORTER.md create mode 100644 TOWER_QUICKSLOT_SETUP.md diff --git a/Assembly-CSharp-Editor.csproj b/Assembly-CSharp-Editor.csproj index 33273b5..4901f29 100644 --- a/Assembly-CSharp-Editor.csproj +++ b/Assembly-CSharp-Editor.csproj @@ -43,6 +43,7 @@ 6000.3.5f2 + @@ -54,9 +55,12 @@ + + + @@ -1245,14 +1249,14 @@ Library\ScriptAssemblies\PPv2URPConverters.dll False - - Library\ScriptAssemblies\Unity.AI.Navigation.Updater.dll - False - Library\ScriptAssemblies\Unity.2D.Common.Editor.dll False + + Library\ScriptAssemblies\Unity.AI.Navigation.Updater.dll + False + Library\ScriptAssemblies\Unity.AI.Navigation.Editor.dll False @@ -1289,6 +1293,10 @@ Library\ScriptAssemblies\Unity.2D.Aseprite.Common.dll False + + Library\ScriptAssemblies\Unity.Rider.Editor.dll + False + Library\ScriptAssemblies\Unity.AI.Navigation.Editor.ConversionSystem.dll False @@ -1297,10 +1305,6 @@ Library\ScriptAssemblies\Unity.2D.Aseprite.Editor.dll False - - Library\ScriptAssemblies\Unity.Rider.Editor.dll - False - Library\ScriptAssemblies\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll False diff --git a/Assembly-CSharp.csproj b/Assembly-CSharp.csproj index 2006850..99a8509 100644 --- a/Assembly-CSharp.csproj +++ b/Assembly-CSharp.csproj @@ -43,6 +43,7 @@ 6000.3.5f2 + @@ -71,6 +72,7 @@ + @@ -1266,14 +1268,14 @@ Library\ScriptAssemblies\PPv2URPConverters.dll False - - Library\ScriptAssemblies\Unity.AI.Navigation.Updater.dll - False - Library\ScriptAssemblies\Unity.2D.Common.Editor.dll False + + Library\ScriptAssemblies\Unity.AI.Navigation.Updater.dll + False + Library\ScriptAssemblies\Unity.AI.Navigation.Editor.dll False @@ -1310,6 +1312,10 @@ Library\ScriptAssemblies\Unity.2D.Aseprite.Common.dll False + + Library\ScriptAssemblies\Unity.Rider.Editor.dll + False + Library\ScriptAssemblies\Unity.AI.Navigation.Editor.ConversionSystem.dll False @@ -1318,10 +1324,6 @@ Library\ScriptAssemblies\Unity.2D.Aseprite.Editor.dll False - - Library\ScriptAssemblies\Unity.Rider.Editor.dll - False - Library\ScriptAssemblies\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll False diff --git a/Assets/Data/ScriptableObjects/Tower/Tower1.asset b/Assets/Data/ScriptableObjects/Tower/Tower1.asset new file mode 100644 index 0000000..30f963d --- /dev/null +++ b/Assets/Data/ScriptableObjects/Tower/Tower1.asset @@ -0,0 +1,52 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8c40fef5ebc37b743a3f225c1ca57c32, type: 3} + m_Name: Tower1 + m_EditorClassIdentifier: Assembly-CSharp::Northbound.Data.TowerData + buildingName: "\uD0C0\uC6CC" + prefab: {fileID: 8512676738329978770, guid: 3f7838db2c2fc424d9bd9a0d243b43be, type: 3} + icon: {fileID: 0} + width: 3 + length: 3 + height: 4 + placementOffset: {x: 0, y: 0, z: 0} + allowRotation: 1 + requiredWorkAmount: 10 + workPerInteraction: 10 + interactionCooldown: 1 + constructionAnimationTrigger: Build + constructionEquipment: + socketName: RightHand + equipmentPrefab: {fileID: 0} + attachOnStart: 1 + detachOnEnd: 1 + keepEquipped: 0 + attachDelay: 0 + detachDelay: 0 + maxHealth: 50 + isIndestructible: 0 + autoRegenerate: 0 + regenPerSecond: 1 + providesVision: 1 + visionRange: 10 + id: 1 + memo: "\uD0C0\uC6CC" + mana: 25 + manpower: 10 + sizeX: 3 + sizeY: 3 + sizeZ: 3 + maxHp: 50 + atkRange: 10 + atkDamage: 5 + atkIntervalSec: 2 + modelPath: Assets/Models/building_tower_B_blue.fbx diff --git a/Assets/Data/ScriptableObjects/Tower/Tower1.asset.meta b/Assets/Data/ScriptableObjects/Tower/Tower1.asset.meta new file mode 100644 index 0000000..64011f4 --- /dev/null +++ b/Assets/Data/ScriptableObjects/Tower/Tower1.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3e2e145df85a3ee4eb615f87efba4554 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/ScriptableObjects/Tower/Tower2.asset b/Assets/Data/ScriptableObjects/Tower/Tower2.asset new file mode 100644 index 0000000..015e69a --- /dev/null +++ b/Assets/Data/ScriptableObjects/Tower/Tower2.asset @@ -0,0 +1,52 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8c40fef5ebc37b743a3f225c1ca57c32, type: 3} + m_Name: Tower2 + m_EditorClassIdentifier: Assembly-CSharp::Northbound.Data.TowerData + buildingName: "\uBCBD" + prefab: {fileID: 3671057791414486316, guid: ae9a9b515e1792a45887f0d967b943d6, type: 3} + icon: {fileID: 0} + width: 2 + length: 1 + height: 4 + placementOffset: {x: 0, y: 0, z: 0} + allowRotation: 1 + requiredWorkAmount: 5 + workPerInteraction: 10 + interactionCooldown: 1 + constructionAnimationTrigger: Build + constructionEquipment: + socketName: RightHand + equipmentPrefab: {fileID: 0} + attachOnStart: 1 + detachOnEnd: 1 + keepEquipped: 0 + attachDelay: 0 + detachDelay: 0 + maxHealth: 30 + isIndestructible: 0 + autoRegenerate: 0 + regenPerSecond: 1 + providesVision: 1 + visionRange: 0 + id: 2 + memo: "\uBCBD" + mana: 5 + manpower: 5 + sizeX: 2 + sizeY: 2 + sizeZ: 1 + maxHp: 30 + atkRange: 0 + atkDamage: 0 + atkIntervalSec: 0 + modelPath: Assets/Models/wall_straight.fbx diff --git a/Assets/Data/ScriptableObjects/Tower/Tower2.asset.meta b/Assets/Data/ScriptableObjects/Tower/Tower2.asset.meta new file mode 100644 index 0000000..3099776 --- /dev/null +++ b/Assets/Data/ScriptableObjects/Tower/Tower2.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 03a521eb1160745439ba2d0efeb12f3c +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Scripts/DataClasses/TowerData.cs b/Assets/Data/Scripts/DataClasses/TowerData.cs index 59b9751..138d7fb 100644 --- a/Assets/Data/Scripts/DataClasses/TowerData.cs +++ b/Assets/Data/Scripts/DataClasses/TowerData.cs @@ -3,11 +3,12 @@ using UnityEngine; using System.Collections.Generic; // 리스트 지원을 위해 추가 +using Northbound; namespace Northbound.Data { [CreateAssetMenu(fileName = "TowerData", menuName = "Northbound/Tower Data")] - public class TowerData : ScriptableObject + public class TowerData : BuildingData { [Header("기본 정보")] /// 고유 ID @@ -22,6 +23,8 @@ namespace Northbound.Data public int sizeX; /// Y 그리드 차지 공간 public int sizeY; + /// Z 차지 공간 + public int sizeZ; /// 체력 public int maxHp; /// 사정거리 @@ -30,8 +33,40 @@ namespace Northbound.Data public int atkDamage; /// 공격 주기 public float atkIntervalSec; - /// 프리팹/리소스 경로 - public string prefabPath; + /// 모델 경로 + public string modelPath; + private bool fieldsSynced = false; + + private void Awake() + { + SyncFields(); + } + + private void SyncFields() + { + if (fieldsSynced) return; + fieldsSynced = true; + + // Map TowerData fields to BuildingData fields + if (string.IsNullOrEmpty(base.buildingName)) + { + base.buildingName = memo; + } + base.width = sizeX; + base.length = sizeY; + base.height = sizeZ; + base.maxHealth = maxHp; + base.visionRange = atkRange; + base.requiredWorkAmount = manpower; + base.workPerInteraction = 10f; + base.interactionCooldown =1f; + base.providesVision = true; + } + + public void EnsureSynced() + { + SyncFields(); + } } } \ No newline at end of file diff --git a/Assets/Data/Templates/TowerTemplate.prefab b/Assets/Data/Templates/TowerTemplate.prefab new file mode 100644 index 0000000..5c079e2 --- /dev/null +++ b/Assets/Data/Templates/TowerTemplate.prefab @@ -0,0 +1,146 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &7169488976654481418 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4800397361066136527} + - component: {fileID: 4995981673923607444} + - component: {fileID: -5559005308629590716} + - component: {fileID: 8546144977850478548} + - component: {fileID: -4086363217010332088} + - component: {fileID: 4822792797652874450} + m_Layer: 0 + m_Name: TowerTemplate + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4800397361066136527 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7169488976654481418} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &4995981673923607444 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7169488976654481418} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject + GlobalObjectIdHash: 4259369348 + InScenePlacedSourceGlobalObjectIdHash: 0 + DeferredDespawnTick: 0 + Ownership: 1 + AlwaysReplicateAsRoot: 0 + SynchronizeTransform: 1 + ActiveSceneSynchronization: 0 + SceneMigrationSynchronization: 0 + SpawnWithObservers: 1 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 +--- !u!65 &-5559005308629590716 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7169488976654481418} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Size: {x: 1, y: 2, z: 1} + m_Center: {x: 0, y: 1, z: 0} +--- !u!208 &8546144977850478548 +NavMeshObstacle: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7169488976654481418} + m_Enabled: 1 + serializedVersion: 3 + m_Shape: 1 + m_Extents: {x: 0.5, y: 1, z: 0.5} + m_MoveThreshold: 0.1 + m_Carve: 0 + m_CarveOnlyStationary: 1 + m_Center: {x: 0, y: 1, z: 0} + m_TimeToStationary: 0.5 +--- !u!114 &-4086363217010332088 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7169488976654481418} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0ceedb9b012d848478813136b65738ae, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::Northbound.Building + ShowTopMostFoldoutHeaderGroup: 1 + buildingData: {fileID: 0} + gridPosition: {x: 0, y: 0, z: 0} + rotation: 0 + initialTeam: 1 + initialOwnerId: 0 + useInitialOwner: 0 + showHealthBar: 1 + healthBarPrefab: {fileID: 0} + destroyEffectPrefab: {fileID: 0} + damageEffectPrefab: {fileID: 0} + effectSpawnPoint: {fileID: 0} + showGridBounds: 1 + gridBoundsColor: {r: 0, g: 1, b: 1, a: 1} +--- !u!114 &4822792797652874450 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7169488976654481418} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 760137a2fd0da7f458ac4b0ee7f485d6, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::Northbound.FogOfWarVisibility + showInExploredAreas: 0 + updateInterval: 0.2 + renderers: [] + enableDistantVisibility: 1 + heightVisibilityMultiplier: 2 + minHeightForDistantVisibility: 3 + useExploredMaterial: 0 + exploredMaterial: {fileID: 0} diff --git a/Assets/Data/Templates/TowerTemplate.prefab.meta b/Assets/Data/Templates/TowerTemplate.prefab.meta new file mode 100644 index 0000000..eb72a97 --- /dev/null +++ b/Assets/Data/Templates/TowerTemplate.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5cb8ca5552f975e4c88d418d11d28dbc +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/DefaultNetworkPrefabs.asset b/Assets/DefaultNetworkPrefabs.asset index eca1e29..ea8eed0 100644 --- a/Assets/DefaultNetworkPrefabs.asset +++ b/Assets/DefaultNetworkPrefabs.asset @@ -99,3 +99,18 @@ MonoBehaviour: SourcePrefabToOverride: {fileID: 0} SourceHashToOverride: 0 OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 7169488976654481418, guid: 5cb8ca5552f975e4c88d418d11d28dbc, type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 8512676738329978770, guid: 3f7838db2c2fc424d9bd9a0d243b43be, type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 3671057791414486316, guid: ae9a9b515e1792a45887f0d967b943d6, type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} diff --git a/Assets/Models/building_tower_B_blue.fbx b/Assets/Models/building_tower_B_blue.fbx new file mode 100644 index 0000000000000000000000000000000000000000..f067591ff41a15fb166a1701cf39e74b4feee834 GIT binary patch literal 93068 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�oW7UYxrTbvIO`mm2C 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 GRQf+!ss>g7 literal 0 HcmV?d00001 diff --git a/Assets/Models/building_tower_B_blue.fbx.meta b/Assets/Models/building_tower_B_blue.fbx.meta new file mode 100644 index 0000000..7b7b2c9 --- /dev/null +++ b/Assets/Models/building_tower_B_blue.fbx.meta @@ -0,0 +1,110 @@ +fileFormatVersion: 2 +guid: 3dbb43609bf79104da27aad0a7704ed3 +ModelImporter: + serializedVersion: 24200 + internalIDToNameTable: [] + externalObjects: {} + materials: + materialImportMode: 2 + materialName: 0 + materialSearch: 1 + materialLocation: 1 + animations: + legacyGenerateAnimations: 4 + bakeSimulation: 0 + resampleCurves: 1 + optimizeGameObjects: 0 + removeConstantScaleCurves: 0 + motionNodeName: + animationImportErrors: + animationImportWarnings: + animationRetargetingWarnings: + animationDoRetargetingWarnings: 0 + importAnimatedCustomProperties: 0 + importConstraints: 0 + animationCompression: 1 + animationRotationError: 0.5 + animationPositionError: 0.5 + animationScaleError: 0.5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + extraUserProperties: [] + clipAnimations: [] + isReadable: 0 + meshes: + lODScreenPercentages: [] + globalScale: 1 + meshCompression: 0 + addColliders: 0 + useSRGBMaterialColor: 1 + sortHierarchyByName: 1 + importPhysicalCameras: 1 + importVisibility: 1 + importBlendShapes: 1 + importCameras: 1 + importLights: 1 + nodeNameCollisionStrategy: 1 + fileIdsGeneration: 2 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 1 + keepQuads: 0 + weldVertices: 1 + bakeAxisConversion: 0 + preserveHierarchy: 0 + skinWeightsMode: 0 + maxBonesPerVertex: 4 + minBoneWeight: 0.001 + optimizeBones: 1 + generateMeshLods: 0 + meshLodGenerationFlags: 0 + maximumMeshLod: -1 + meshOptimizationFlags: -1 + indexFormat: 0 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVMarginMethod: 1 + secondaryUVMinLightmapResolution: 40 + secondaryUVMinObjectScale: 1 + secondaryUVPackMargin: 4 + useFileScale: 1 + strictVertexDataChecks: 0 + tangentSpace: + normalSmoothAngle: 60 + normalImportMode: 0 + tangentImportMode: 3 + normalCalculationMode: 4 + legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 + blendShapeNormalImportMode: 1 + normalSmoothingSource: 0 + referencedClips: [] + importAnimation: 1 + humanDescription: + serializedVersion: 3 + human: [] + skeleton: [] + armTwist: 0.5 + foreArmTwist: 0.5 + upperLegTwist: 0.5 + legTwist: 0.5 + armStretch: 0.05 + legStretch: 0.05 + feetSpacing: 0 + globalScale: 1 + rootMotionBoneName: + hasTranslationDoF: 0 + hasExtraRoot: 0 + skeletonHasParents: 1 + lastHumanDescriptionAvatarSource: {instanceID: 0} + autoGenerateAvatarMappingIfUnspecified: 1 + animationType: 2 + humanoidOversampling: 1 + avatarSetup: 0 + addHumanoidExtraRootOnlyWhenUsingAvatar: 1 + importBlendShapeDeformPercent: 1 + remapMaterialsIfMaterialImportModeIsNone: 0 + additionalBone: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Models/wall_straight.fbx b/Assets/Models/wall_straight.fbx new file mode 100644 index 0000000000000000000000000000000000000000..dee05080ed80c36b8c199e6d09e255c47f328822 GIT binary patch literal 31292 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 literal 0 HcmV?d00001 diff --git a/Assets/Models/wall_straight.fbx.meta b/Assets/Models/wall_straight.fbx.meta new file mode 100644 index 0000000..31cf921 --- /dev/null +++ b/Assets/Models/wall_straight.fbx.meta @@ -0,0 +1,110 @@ +fileFormatVersion: 2 +guid: 0204078ba040180418c65c7f09f3bdb2 +ModelImporter: + serializedVersion: 24200 + internalIDToNameTable: [] + externalObjects: {} + materials: + materialImportMode: 2 + materialName: 0 + materialSearch: 1 + materialLocation: 1 + animations: + legacyGenerateAnimations: 4 + bakeSimulation: 0 + resampleCurves: 1 + optimizeGameObjects: 0 + removeConstantScaleCurves: 0 + motionNodeName: + animationImportErrors: + animationImportWarnings: + animationRetargetingWarnings: + animationDoRetargetingWarnings: 0 + importAnimatedCustomProperties: 0 + importConstraints: 0 + animationCompression: 1 + animationRotationError: 0.5 + animationPositionError: 0.5 + animationScaleError: 0.5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + extraUserProperties: [] + clipAnimations: [] + isReadable: 0 + meshes: + lODScreenPercentages: [] + globalScale: 1 + meshCompression: 0 + addColliders: 0 + useSRGBMaterialColor: 1 + sortHierarchyByName: 1 + importPhysicalCameras: 1 + importVisibility: 1 + importBlendShapes: 1 + importCameras: 1 + importLights: 1 + nodeNameCollisionStrategy: 1 + fileIdsGeneration: 2 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 1 + keepQuads: 0 + weldVertices: 1 + bakeAxisConversion: 0 + preserveHierarchy: 0 + skinWeightsMode: 0 + maxBonesPerVertex: 4 + minBoneWeight: 0.001 + optimizeBones: 1 + generateMeshLods: 0 + meshLodGenerationFlags: 0 + maximumMeshLod: -1 + meshOptimizationFlags: -1 + indexFormat: 0 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVMarginMethod: 1 + secondaryUVMinLightmapResolution: 40 + secondaryUVMinObjectScale: 1 + secondaryUVPackMargin: 4 + useFileScale: 1 + strictVertexDataChecks: 0 + tangentSpace: + normalSmoothAngle: 60 + normalImportMode: 0 + tangentImportMode: 3 + normalCalculationMode: 4 + legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 + blendShapeNormalImportMode: 1 + normalSmoothingSource: 0 + referencedClips: [] + importAnimation: 1 + humanDescription: + serializedVersion: 3 + human: [] + skeleton: [] + armTwist: 0.5 + foreArmTwist: 0.5 + upperLegTwist: 0.5 + legTwist: 0.5 + armStretch: 0.05 + legStretch: 0.05 + feetSpacing: 0 + globalScale: 1 + rootMotionBoneName: + hasTranslationDoF: 0 + hasExtraRoot: 0 + skeletonHasParents: 1 + lastHumanDescriptionAvatarSource: {instanceID: 0} + autoGenerateAvatarMappingIfUnspecified: 1 + animationType: 2 + humanoidOversampling: 1 + avatarSetup: 0 + addHumanoidExtraRootOnlyWhenUsingAvatar: 1 + importBlendShapeDeformPercent: 1 + remapMaterialsIfMaterialImportModeIsNone: 0 + additionalBone: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/Monster/Monster101.prefab b/Assets/Prefabs/Monster/Monster101.prefab index 4227abb..e34c056 100644 --- a/Assets/Prefabs/Monster/Monster101.prefab +++ b/Assets/Prefabs/Monster/Monster101.prefab @@ -1285,7 +1285,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} m_Name: m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject - GlobalObjectIdHash: 2991918417 + GlobalObjectIdHash: 209349728 InScenePlacedSourceGlobalObjectIdHash: 0 DeferredDespawnTick: 0 Ownership: 1 diff --git a/Assets/Prefabs/Monster/Monster105.prefab b/Assets/Prefabs/Monster/Monster105.prefab index cc44787..77039a5 100644 --- a/Assets/Prefabs/Monster/Monster105.prefab +++ b/Assets/Prefabs/Monster/Monster105.prefab @@ -964,8 +964,8 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} m_Name: m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject - GlobalObjectIdHash: 3377967349 - InScenePlacedSourceGlobalObjectIdHash: 2825901034 + GlobalObjectIdHash: 209349728 + InScenePlacedSourceGlobalObjectIdHash: 0 DeferredDespawnTick: 0 Ownership: 1 AlwaysReplicateAsRoot: 0 diff --git a/Assets/Prefabs/Player.prefab b/Assets/Prefabs/Player.prefab index 4f292c3..b6ee481 100644 --- a/Assets/Prefabs/Player.prefab +++ b/Assets/Prefabs/Player.prefab @@ -55,7 +55,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} m_Name: m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject - GlobalObjectIdHash: 4211758632 + GlobalObjectIdHash: 1360081626 InScenePlacedSourceGlobalObjectIdHash: 4211758632 DeferredDespawnTick: 0 Ownership: 1 diff --git a/Assets/Prefabs/Tower/Tower1.prefab b/Assets/Prefabs/Tower/Tower1.prefab new file mode 100644 index 0000000..4275411 --- /dev/null +++ b/Assets/Prefabs/Tower/Tower1.prefab @@ -0,0 +1,342 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1289760089446993883 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6062607789191353382} + - component: {fileID: 7470654452104141725} + - component: {fileID: 6347255101590433954} + m_Layer: 0 + m_Name: building_tower_B_top_blue + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &6062607789191353382 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1289760089446993883} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: -0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1872842023463012809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &7470654452104141725 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1289760089446993883} + m_Mesh: {fileID: -2975848345017946836, guid: 3dbb43609bf79104da27aad0a7704ed3, type: 3} +--- !u!23 &6347255101590433954 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1289760089446993883} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: -6545801570897300931, guid: 3dbb43609bf79104da27aad0a7704ed3, type: 3} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!1 &7757785777080043176 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1872842023463012809} + - component: {fileID: 7668707206409267505} + - component: {fileID: 2906673092929627781} + m_Layer: 0 + m_Name: Model + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1872842023463012809 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7757785777080043176} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 3, y: 3, z: 3} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6062607789191353382} + m_Father: {fileID: 5446357005769341236} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &7668707206409267505 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7757785777080043176} + m_Mesh: {fileID: -1867165846391908481, guid: 3dbb43609bf79104da27aad0a7704ed3, type: 3} +--- !u!23 &2906673092929627781 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7757785777080043176} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: -6545801570897300931, guid: 3dbb43609bf79104da27aad0a7704ed3, type: 3} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!1 &8512676738329978770 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5446357005769341236} + - component: {fileID: 6253727954874418700} + - component: {fileID: 1804512144580361968} + - component: {fileID: 100877884298911200} + - component: {fileID: 8485093670801034058} + - component: {fileID: 7262612124217315611} + - component: {fileID: 3089566480349729} + m_Layer: 0 + m_Name: Tower1 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &5446357005769341236 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8512676738329978770} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1872842023463012809} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &6253727954874418700 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8512676738329978770} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject + GlobalObjectIdHash: 4259369348 + InScenePlacedSourceGlobalObjectIdHash: 0 + DeferredDespawnTick: 0 + Ownership: 1 + AlwaysReplicateAsRoot: 0 + SynchronizeTransform: 1 + ActiveSceneSynchronization: 0 + SceneMigrationSynchronization: 0 + SpawnWithObservers: 1 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 +--- !u!65 &1804512144580361968 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8512676738329978770} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Size: {x: 3, y: 3, z: 3} + m_Center: {x: 0, y: 1.5, z: 0} +--- !u!208 &100877884298911200 +NavMeshObstacle: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8512676738329978770} + m_Enabled: 1 + serializedVersion: 3 + m_Shape: 1 + m_Extents: {x: 1.5, y: 1.5, z: 1.5} + m_MoveThreshold: 0.1 + m_Carve: 0 + m_CarveOnlyStationary: 1 + m_Center: {x: 0, y: 1.5, z: 0} + m_TimeToStationary: 0.5 +--- !u!114 &8485093670801034058 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8512676738329978770} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0ceedb9b012d848478813136b65738ae, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::Northbound.Building + ShowTopMostFoldoutHeaderGroup: 1 + buildingData: {fileID: 0} + gridPosition: {x: 0, y: 0, z: 0} + rotation: 0 + initialTeam: 1 + initialOwnerId: 0 + useInitialOwner: 0 + showHealthBar: 1 + healthBarPrefab: {fileID: 0} + destroyEffectPrefab: {fileID: 0} + damageEffectPrefab: {fileID: 0} + effectSpawnPoint: {fileID: 0} + showGridBounds: 1 + gridBoundsColor: {r: 0, g: 1, b: 1, a: 1} +--- !u!114 &7262612124217315611 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8512676738329978770} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 760137a2fd0da7f458ac4b0ee7f485d6, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::Northbound.FogOfWarVisibility + showInExploredAreas: 0 + updateInterval: 0.2 + renderers: [] + enableDistantVisibility: 1 + heightVisibilityMultiplier: 2 + minHeightForDistantVisibility: 3 + useExploredMaterial: 0 + exploredMaterial: {fileID: 0} +--- !u!114 &3089566480349729 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8512676738329978770} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 56c4536effc49fe47af593bf9d17e979, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::Northbound.TowerDataComponent + towerData: {fileID: 11400000, guid: 3e2e145df85a3ee4eb615f87efba4554, type: 2} diff --git a/Assets/Prefabs/Tower/Tower1.prefab.meta b/Assets/Prefabs/Tower/Tower1.prefab.meta new file mode 100644 index 0000000..1abb589 --- /dev/null +++ b/Assets/Prefabs/Tower/Tower1.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3f7838db2c2fc424d9bd9a0d243b43be +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/Tower/Tower2.prefab b/Assets/Prefabs/Tower/Tower2.prefab new file mode 100644 index 0000000..965619e --- /dev/null +++ b/Assets/Prefabs/Tower/Tower2.prefab @@ -0,0 +1,251 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &3671057791414486316 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1657799771882240} + - component: {fileID: 3850164934046790335} + - component: {fileID: 7724449748843190139} + - component: {fileID: 2615519446934682856} + - component: {fileID: 3203720634638459019} + - component: {fileID: 3906797260079127802} + - component: {fileID: 3692219876976097854} + m_Layer: 0 + m_Name: Tower2 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1657799771882240 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3671057791414486316} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8553397989698296005} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &3850164934046790335 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3671057791414486316} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject + GlobalObjectIdHash: 4259369348 + InScenePlacedSourceGlobalObjectIdHash: 0 + DeferredDespawnTick: 0 + Ownership: 1 + AlwaysReplicateAsRoot: 0 + SynchronizeTransform: 1 + ActiveSceneSynchronization: 0 + SceneMigrationSynchronization: 0 + SpawnWithObservers: 1 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 +--- !u!65 &7724449748843190139 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3671057791414486316} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Size: {x: 2, y: 1, z: 2} + m_Center: {x: 0, y: 0.5, z: 0} +--- !u!208 &2615519446934682856 +NavMeshObstacle: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3671057791414486316} + m_Enabled: 1 + serializedVersion: 3 + m_Shape: 1 + m_Extents: {x: 1, y: 0.5, z: 1} + m_MoveThreshold: 0.1 + m_Carve: 0 + m_CarveOnlyStationary: 1 + m_Center: {x: 0, y: 0.5, z: 0} + m_TimeToStationary: 0.5 +--- !u!114 &3203720634638459019 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3671057791414486316} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0ceedb9b012d848478813136b65738ae, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::Northbound.Building + ShowTopMostFoldoutHeaderGroup: 1 + buildingData: {fileID: 0} + gridPosition: {x: 0, y: 0, z: 0} + rotation: 0 + initialTeam: 1 + initialOwnerId: 0 + useInitialOwner: 0 + showHealthBar: 1 + healthBarPrefab: {fileID: 0} + destroyEffectPrefab: {fileID: 0} + damageEffectPrefab: {fileID: 0} + effectSpawnPoint: {fileID: 0} + showGridBounds: 1 + gridBoundsColor: {r: 0, g: 1, b: 1, a: 1} +--- !u!114 &3906797260079127802 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3671057791414486316} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 760137a2fd0da7f458ac4b0ee7f485d6, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::Northbound.FogOfWarVisibility + showInExploredAreas: 0 + updateInterval: 0.2 + renderers: [] + enableDistantVisibility: 1 + heightVisibilityMultiplier: 2 + minHeightForDistantVisibility: 3 + useExploredMaterial: 0 + exploredMaterial: {fileID: 0} +--- !u!114 &3692219876976097854 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3671057791414486316} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 56c4536effc49fe47af593bf9d17e979, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::Northbound.TowerDataComponent + towerData: {fileID: 11400000, guid: 03a521eb1160745439ba2d0efeb12f3c, type: 2} +--- !u!1 &8947776510381915047 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8553397989698296005} + - component: {fileID: 5020570213282043347} + - component: {fileID: 3242347197691888434} + m_Layer: 0 + m_Name: Model + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8553397989698296005 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8947776510381915047} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 2, y: 1, z: 2} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1657799771882240} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &5020570213282043347 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8947776510381915047} + m_Mesh: {fileID: -4423419886561025764, guid: 0204078ba040180418c65c7f09f3bdb2, type: 3} +--- !u!23 &3242347197691888434 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8947776510381915047} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: -6545801570897300931, guid: 0204078ba040180418c65c7f09f3bdb2, type: 3} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} diff --git a/Assets/Prefabs/Tower/Tower2.prefab.meta b/Assets/Prefabs/Tower/Tower2.prefab.meta new file mode 100644 index 0000000..56bc1b7 --- /dev/null +++ b/Assets/Prefabs/Tower/Tower2.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ae9a9b515e1792a45887f0d967b943d6 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/GameMain.unity b/Assets/Scenes/GameMain.unity index ccf40cd..4a60462 100644 --- a/Assets/Scenes/GameMain.unity +++ b/Assets/Scenes/GameMain.unity @@ -1712,6 +1712,7 @@ MonoBehaviour: enableHeightBlocking: 1 viewerEyeHeight: 1.5 minBlockingHeight: 2 + disableInEditor: 1 --- !u!4 &946527919 Transform: m_ObjectHideFlags: 0 @@ -1962,16 +1963,28 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 6859825394817103090, guid: 11e3760dda2c0164abf759c18d918893, type: 3} propertyPath: monsterEntries.Array.size - value: 0 + value: 5 objectReference: {fileID: 0} - target: {fileID: 6859825394817103090, guid: 11e3760dda2c0164abf759c18d918893, type: 3} propertyPath: monsterEntries.Array.data[0].prefab value: - objectReference: {fileID: 8774623643640324048, guid: c92c9f1bf0ae6364f85409ecdc4aeaf3, type: 3} + objectReference: {fileID: 7146441246397375875, guid: eccdace7a7b21a446891da5739b1549f, type: 3} - target: {fileID: 6859825394817103090, guid: 11e3760dda2c0164abf759c18d918893, type: 3} propertyPath: monsterEntries.Array.data[1].prefab value: - objectReference: {fileID: 5176576196123937037, guid: 951b69041a2ace947afd721fefb3eaba, type: 3} + objectReference: {fileID: 9065146123892903723, guid: 4ee9b364dfe9d0949a23374e660d3e13, type: 3} + - target: {fileID: 6859825394817103090, guid: 11e3760dda2c0164abf759c18d918893, type: 3} + propertyPath: monsterEntries.Array.data[2].prefab + value: + objectReference: {fileID: 2347008446492047424, guid: 9cac250ebe8d420469bd4da3ab8cfd86, type: 3} + - target: {fileID: 6859825394817103090, guid: 11e3760dda2c0164abf759c18d918893, type: 3} + propertyPath: monsterEntries.Array.data[3].prefab + value: + objectReference: {fileID: 4973514444862586119, guid: ff2924ffa397a8e44925625790831d25, type: 3} + - target: {fileID: 6859825394817103090, guid: 11e3760dda2c0164abf759c18d918893, type: 3} + propertyPath: monsterEntries.Array.data[4].prefab + value: + objectReference: {fileID: 5710477988932221578, guid: e8d09b814275ad745a427433c28dd53f, type: 3} - target: {fileID: 6859825394817103090, guid: 11e3760dda2c0164abf759c18d918893, type: 3} propertyPath: monsterEntries.Array.data[0].monsterData value: @@ -3315,16 +3328,28 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 6859825394817103090, guid: 11e3760dda2c0164abf759c18d918893, type: 3} propertyPath: monsterEntries.Array.size - value: 0 + value: 5 objectReference: {fileID: 0} - target: {fileID: 6859825394817103090, guid: 11e3760dda2c0164abf759c18d918893, type: 3} propertyPath: monsterEntries.Array.data[0].prefab value: - objectReference: {fileID: 8774623643640324048, guid: c92c9f1bf0ae6364f85409ecdc4aeaf3, type: 3} + objectReference: {fileID: 7146441246397375875, guid: eccdace7a7b21a446891da5739b1549f, type: 3} - target: {fileID: 6859825394817103090, guid: 11e3760dda2c0164abf759c18d918893, type: 3} propertyPath: monsterEntries.Array.data[1].prefab value: - objectReference: {fileID: 5176576196123937037, guid: 951b69041a2ace947afd721fefb3eaba, type: 3} + objectReference: {fileID: 9065146123892903723, guid: 4ee9b364dfe9d0949a23374e660d3e13, type: 3} + - target: {fileID: 6859825394817103090, guid: 11e3760dda2c0164abf759c18d918893, type: 3} + propertyPath: monsterEntries.Array.data[2].prefab + value: + objectReference: {fileID: 2347008446492047424, guid: 9cac250ebe8d420469bd4da3ab8cfd86, type: 3} + - target: {fileID: 6859825394817103090, guid: 11e3760dda2c0164abf759c18d918893, type: 3} + propertyPath: monsterEntries.Array.data[3].prefab + value: + objectReference: {fileID: 4973514444862586119, guid: ff2924ffa397a8e44925625790831d25, type: 3} + - target: {fileID: 6859825394817103090, guid: 11e3760dda2c0164abf759c18d918893, type: 3} + propertyPath: monsterEntries.Array.data[4].prefab + value: + objectReference: {fileID: 5710477988932221578, guid: e8d09b814275ad745a427433c28dd53f, type: 3} - target: {fileID: 6859825394817103090, guid: 11e3760dda2c0164abf759c18d918893, type: 3} propertyPath: monsterEntries.Array.data[0].monsterData value: diff --git a/Assets/ScriptableObjects.meta b/Assets/ScriptableObjects.meta new file mode 100644 index 0000000..1160584 --- /dev/null +++ b/Assets/ScriptableObjects.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b5e2a173b42c98746a251ef1dcb4f1a4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ScriptableObjects/Monster.meta b/Assets/ScriptableObjects/Monster.meta new file mode 100644 index 0000000..6e990d9 --- /dev/null +++ b/Assets/ScriptableObjects/Monster.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: def17a694f320ed4a80ff136df2b01b7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ScriptableObjects/Tower.meta b/Assets/ScriptableObjects/Tower.meta new file mode 100644 index 0000000..8d82dc8 --- /dev/null +++ b/Assets/ScriptableObjects/Tower.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 32bffeae31a205549b9fb32d3674b199 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/BuildingPlacement.cs b/Assets/Scripts/BuildingPlacement.cs index 8022b63..7d6ba65 100644 --- a/Assets/Scripts/BuildingPlacement.cs +++ b/Assets/Scripts/BuildingPlacement.cs @@ -189,6 +189,13 @@ namespace Northbound } Debug.Log($"[BuildingPlacement] 건설 모드 {(isBuildModeActive ? "활성화" : "비활성화")}"); + Debug.Log($"[BuildingPlacement] Preview object: {(previewObject != null ? "CREATED" : "NULL")}"); + if (previewObject != null) + { + Debug.Log($"[BuildingPlacement] Preview position: {previewObject.transform.position}"); + Debug.Log($"[BuildingPlacement] Preview scale: {previewObject.transform.localScale}"); + Debug.Log($"[BuildingPlacement] Preview active: {previewObject.activeSelf}"); + } } ///

@@ -231,6 +238,10 @@ namespace Northbound return; } + Debug.Log($"[BuildingPlacement] Creating preview..."); + Debug.Log($"[BuildingPlacement] BuildingManager.availableBuildings.Count: {BuildingManager.Instance.availableBuildings.Count}"); + Debug.Log($"[BuildingPlacement] selectedBuildingIndex: {selectedBuildingIndex}"); + if (selectedBuildingIndex < 0 || selectedBuildingIndex >= BuildingManager.Instance.availableBuildings.Count) { Debug.LogWarning($"[BuildingPlacement] 유효하지 않은 건물 인덱스: {selectedBuildingIndex}"); @@ -238,12 +249,21 @@ namespace Northbound } BuildingData data = BuildingManager.Instance.availableBuildings[selectedBuildingIndex]; - if (data == null || data.prefab == null) + if (data == null) { - Debug.LogWarning("[BuildingPlacement] BuildingData 또는 Prefab이 없습니다."); + Debug.LogError($"[BuildingPlacement] BuildingData is NULL at index {selectedBuildingIndex}"); return; } + if (data.prefab == null) + { + Debug.LogError($"[BuildingPlacement] BuildingData.prefab is NULL at index {selectedBuildingIndex}. Run 'Northbound > Diagnose Tower System'"); + return; + } + + Debug.Log($"[BuildingPlacement] BuildingData: {data.buildingName}, Prefab: {data.prefab.name}"); + Debug.Log($"[BuildingPlacement] Prefab scale: {data.prefab.transform.localScale}"); + // 완성 건물 프리팹으로 프리뷰 생성 (사용자가 완성 모습을 볼 수 있도록) previewObject = Instantiate(data.prefab); @@ -296,11 +316,17 @@ namespace Northbound if (previewObject == null || BuildingManager.Instance == null) return; + if (selectedBuildingIndex < 0 || selectedBuildingIndex >= BuildingManager.Instance.availableBuildings.Count) + return; + + BuildingData data = BuildingManager.Instance.availableBuildings[selectedBuildingIndex]; + if (data == null || data.prefab == null) + return; + Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue()); if (Physics.Raycast(ray, out RaycastHit hit, maxPlacementDistance, groundLayer)) { - BuildingData data = BuildingManager.Instance.availableBuildings[selectedBuildingIndex]; // Check if placement is valid bool isValid = BuildingManager.Instance.IsValidPlacement(data, hit.point, currentRotation, out Vector3 snappedPosition); @@ -412,13 +438,24 @@ namespace Northbound { if (BuildingManager.Instance == null) return; + if (selectedBuildingIndex < 0 || selectedBuildingIndex >= BuildingManager.Instance.availableBuildings.Count) + { + Debug.LogWarning($"[BuildingPlacement] Invalid building index: {selectedBuildingIndex}"); + return; + } + + BuildingData data = BuildingManager.Instance.availableBuildings[selectedBuildingIndex]; + if (data == null || data.prefab == null) + { + Debug.LogError($"[BuildingPlacement] BuildingData or prefab is null at index {selectedBuildingIndex}. Please run 'Northbound > Populate Towers from Prefabs' and update BuildingManager."); + return; + } + Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue()); if (!Physics.Raycast(ray, out RaycastHit hit, maxPlacementDistance, groundLayer)) { return; } - - BuildingData data = BuildingManager.Instance.availableBuildings[selectedBuildingIndex]; // 드래그 영역 계산 Vector3 dragEndPosition = hit.point; diff --git a/Assets/Scripts/BuildingQuickslotUI.cs b/Assets/Scripts/BuildingQuickslotUI.cs index e4211e8..7658d39 100644 --- a/Assets/Scripts/BuildingQuickslotUI.cs +++ b/Assets/Scripts/BuildingQuickslotUI.cs @@ -99,6 +99,8 @@ namespace Northbound Debug.LogWarning($"[BuildingQuickslotUI] QuickSlot{i + 1} 액션이 null입니다. Input Actions 에셋을 확인하세요."); } } + + Debug.Log($"[BuildingQuickslotUI] {_quickslotActions.Length}개의 퀵슬롯 액션 초기화됨 (최대 8개 키 바인딩)"); } /// @@ -155,6 +157,10 @@ namespace Northbound { SelectBuilding(slotIndex); } + else if (slotIndex >= slotButtons.Count && quickslotPanel != null && quickslotPanel.activeSelf) + { + Debug.LogWarning($"[BuildingQuickslotUI] 슬롯 {slotIndex + 1}은 존재하지 않습니다. 마우스로 클릭하여 선택하세요."); + } } /// @@ -176,11 +182,10 @@ namespace Northbound } slotButtons.Clear(); - // 건물 목록으로 슬롯 생성 (최대 maxSlots개) + // 모든 건물 슬롯 생성 (제한 없음) var buildings = BuildingManager.Instance.availableBuildings; - int slotCount = Mathf.Min(buildings.Count, maxSlots); - for (int i = 0; i < slotCount; i++) + for (int i = 0; i < buildings.Count; i++) { CreateSlot(buildings[i], i); } diff --git a/Assets/Scripts/Editor/CSVToSOImporter.cs b/Assets/Scripts/Editor/CSVToSOImporter.cs new file mode 100644 index 0000000..4bd8d83 --- /dev/null +++ b/Assets/Scripts/Editor/CSVToSOImporter.cs @@ -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 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($"[CSVToSOImporter] Import complete: {successCount} succeeded, {failCount} failed"); + + if (towerImported) + { + AutoConfigureBuildingManager(); + } + + AssetDatabase.Refresh(); + } + + private static void InitializePrefabSetups() + { + prefabSetups = new Dictionary + { + { "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(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($"[CSVToSOImporter] Tower import complete, TowerData extends BuildingData now!"); + } + + 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(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(); + + if (buildingManager == null) + { + Debug.LogError("[CSVToSOImporter] BuildingManager not found in scene! Please add a BuildingManager component to a GameObject in your scene."); + return; + } + + // Load TowerData (which extends BuildingData) + string[] towerDataGuids = AssetDatabase.FindAssets("t:TowerData", new[] { "Assets/Data/ScriptableObjects" }); + List allTowers = new List(); + + Debug.Log($"[CSVToSOImporter] Found {towerDataGuids.Length} TowerData assets"); + + foreach (string guid in towerDataGuids) + { + string assetPath = AssetDatabase.GUIDToAssetPath(guid); + TowerData towerData = AssetDatabase.LoadAssetAtPath(assetPath); + + if (towerData == null) + { + Debug.LogWarning($"[CSVToSOImporter] Failed to load TowerData: {assetPath}"); + continue; + } + + if (towerData.prefab == null) + { + Debug.LogWarning($"[CSVToSOImporter] TowerData {towerData.name} has no prefab reference - skipping"); + continue; + } + + allTowers.Add(towerData); + Debug.Log($"[CSVToSOImporter] Added tower: {towerData.buildingName}"); + } + + if (allTowers.Count == 0) + { + Debug.LogWarning("[CSVToSOImporter] No TowerData with valid prefabs found!"); + Debug.LogWarning("Run 'Northbound > Diagnose Tower System' to see what's wrong"); + 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($"========================================"); + Debug.Log($"🏗️ TOWER IMPORT COMPLETE!"); + Debug.Log($"========================================"); + Debug.Log($"✓ BuildingManager automatically configured!"); + Debug.Log($"✓ Added {allTowers.Count} TowerData to availableBuildings list"); + Debug.Log($"✓ Ready to play - all towers will appear in quickslot!"); + Debug.Log($"========================================"); + foreach (var towerData in allTowers) + { + Debug.Log($" - {towerData.buildingName}"); + } + Debug.Log($"========================================"); + } + + 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 result = new List(); + 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(); + } + } +} diff --git a/Assets/Scripts/Editor/CSVToSOImporter.cs.meta b/Assets/Scripts/Editor/CSVToSOImporter.cs.meta new file mode 100644 index 0000000..275f321 --- /dev/null +++ b/Assets/Scripts/Editor/CSVToSOImporter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c00f900c9a822184dbb4dc85440d40dd \ No newline at end of file diff --git a/Assets/Scripts/Editor/TemplateCreator.cs b/Assets/Scripts/Editor/TemplateCreator.cs index 63cb655..0b66088 100644 --- a/Assets/Scripts/Editor/TemplateCreator.cs +++ b/Assets/Scripts/Editor/TemplateCreator.cs @@ -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() == null) go.AddComponent(); + if (go.GetComponent() == null) + go.AddComponent(); + + if (go.GetComponent() == null) + go.AddComponent(); + + if (go.GetComponent() == null) + { + BoxCollider collider = go.AddComponent(); + collider.size = new Vector3(1f, 2f, 1f); + collider.center = new Vector3(0f, 1f, 0f); + } + + if (go.GetComponent() == null) + { + NavMeshObstacle obstacle = go.AddComponent(); + 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) { diff --git a/Assets/Scripts/Editor/TowerPopulator.cs b/Assets/Scripts/Editor/TowerPopulator.cs new file mode 100644 index 0000000..d4772b1 --- /dev/null +++ b/Assets/Scripts/Editor/TowerPopulator.cs @@ -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($"========================================"); + Debug.Log($"[TowerPopulator] DIAGNOSING TOWER SYSTEM"); + Debug.Log($"========================================"); + + string[] prefabGuids = AssetDatabase.FindAssets("t:Tower", new[] { TOWER_PREFAB_PATH }); + Debug.Log($"Tower Prefabs in Assets/Prefabs/Tower/:"); + if (prefabGuids.Length == 0) + { + Debug.Log($"✗ No tower prefabs found!"); + } + else + { + foreach (string guid in prefabGuids) + { + string assetPath = AssetDatabase.GUIDToAssetPath(guid); + GameObject prefab = AssetDatabase.LoadAssetAtPath(assetPath); + TowerDataComponent tower = prefab?.GetComponent(); + string towerStatus = tower != null && tower.towerData != null ? "✓" : "✗"; + 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($"TowerData assets in Assets/Data/ScriptableObjects/:"); + if (towerDataGuids.Length == 0) + { + Debug.Log($"⚠ No TowerData assets found - Run 'Tools > Data > Import All CSV' first!"); + } + else + { + foreach (string guid in towerDataGuids) + { + string assetPath = AssetDatabase.GUIDToAssetPath(guid); + TowerData data = AssetDatabase.LoadAssetAtPath(assetPath); + string prefabStatus = data?.prefab != null ? "✓" : "✗"; + Debug.Log($" {prefabStatus} {data.name} - Prefab: {data?.prefab?.name ?? "MISSING"}, BuildingName: {data?.buildingName}"); + } + } + + BuildingManager buildingManager = GameObject.FindObjectOfType(); + Debug.Log($"BuildingManager in Scene:"); + if (buildingManager == null) + { + Debug.Log($"✗ BuildingManager not found in scene!"); + } + else + { + Debug.Log($"✓ BuildingManager found: {buildingManager.gameObject.name}"); + Debug.Log($" Available Buildings: {buildingManager.availableBuildings.Count}"); + foreach (var building in buildingManager.availableBuildings) + { + string status = building?.prefab != null ? "✓" : "✗"; + string isTower = building is TowerData ? "[Tower]" : "yellow>[Building]"; + Debug.Log($" {status} {isTower} {building?.name ?? "MISSING"} - {building?.buildingName}"); + } + } + + Debug.Log($"========================================"); + Debug.Log($"[TowerPopulator] DIAGNOSIS COMPLETE"); + Debug.Log($"========================================"); + } + } +} diff --git a/Assets/Scripts/Editor/TowerPopulator.cs.meta b/Assets/Scripts/Editor/TowerPopulator.cs.meta new file mode 100644 index 0000000..d4dd3ed --- /dev/null +++ b/Assets/Scripts/Editor/TowerPopulator.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 069a105319ca9cf4a8323e1d5357960f \ No newline at end of file diff --git a/Assets/Scripts/Editor/TowerPrefabSetup.cs b/Assets/Scripts/Editor/TowerPrefabSetup.cs new file mode 100644 index 0000000..005a462 --- /dev/null +++ b/Assets/Scripts/Editor/TowerPrefabSetup.cs @@ -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(); + if (towerDataComponent == null) + { + towerDataComponent = prefab.AddComponent(); + 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(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(); + if (meshFilter == null) + { + meshFilter = prefab.AddComponent(); + } + + var renderer = prefab.GetComponent(); + if (renderer == null) + { + renderer = prefab.AddComponent(); + } + + Mesh mesh = AssetDatabase.LoadAssetAtPath(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(); + if (collider == null) + { + collider = prefab.AddComponent(); + } + collider.size = new Vector3(towerData.sizeX, towerData.sizeZ, towerData.sizeY); + collider.center = new Vector3(0f, towerData.sizeZ / 2f, 0f); + + var navObstacle = prefab.GetComponent(); + if (navObstacle == null) + { + navObstacle = prefab.AddComponent(); + 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); + } + } + } +} diff --git a/Assets/Scripts/Editor/TowerPrefabSetup.cs.meta b/Assets/Scripts/Editor/TowerPrefabSetup.cs.meta new file mode 100644 index 0000000..026c9ce --- /dev/null +++ b/Assets/Scripts/Editor/TowerPrefabSetup.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: ea17487cde4842d45baf5eb92943142a \ No newline at end of file diff --git a/Assets/Scripts/TowerDataComponent.cs b/Assets/Scripts/TowerDataComponent.cs new file mode 100644 index 0000000..35525e8 --- /dev/null +++ b/Assets/Scripts/TowerDataComponent.cs @@ -0,0 +1,26 @@ +using Northbound.Data; +using Unity.Netcode; +using UnityEngine; + +namespace Northbound +{ + [RequireComponent(typeof(Building))] + [RequireComponent(typeof(NetworkObject))] + public class TowerDataComponent : MonoBehaviour + { + [Header("Data Reference")] + [Tooltip("ScriptableObject containing tower data")] + public TowerData towerData; + + private void Awake() + { + // TowerData now extends BuildingData, so just pass it directly + Building building = GetComponent(); + if (building != null && towerData != null) + { + building.buildingData = towerData; + building.initialTeam = TeamType.Player; + } + } + } +} diff --git a/Assets/Scripts/TowerDataComponent.cs.meta b/Assets/Scripts/TowerDataComponent.cs.meta new file mode 100644 index 0000000..f7f5fa3 --- /dev/null +++ b/Assets/Scripts/TowerDataComponent.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 56c4536effc49fe47af593bf9d17e979 \ No newline at end of file diff --git a/ExternAttributes.Editor.csproj b/ExternAttributes.Editor.csproj index 35f03b0..a9c702c 100644 --- a/ExternAttributes.Editor.csproj +++ b/ExternAttributes.Editor.csproj @@ -43,6 +43,7 @@ 6000.3.5f2 + diff --git a/FlatKit.Utils.Editor.csproj b/FlatKit.Utils.Editor.csproj index 9988b14..850b945 100644 --- a/FlatKit.Utils.Editor.csproj +++ b/FlatKit.Utils.Editor.csproj @@ -43,6 +43,7 @@ 6000.3.5f2 + diff --git a/GameData/.Tower_schema.json b/GameData/.Tower_schema.json index bd677e4..878b8b4 100644 --- a/GameData/.Tower_schema.json +++ b/GameData/.Tower_schema.json @@ -35,6 +35,12 @@ "condition": null, "description": "Y 그리드 차지 공간" }, + { + "name": "size_z", + "type": "int", + "condition": null, + "description": "Z 차지 공간" + }, { "name": "max_hp", "type": "int", @@ -60,9 +66,9 @@ "description": "공격 주기" }, { - "name": "prefab_path", + "name": "model_path", "type": "string", "condition": null, - "description": "프리팹/리소스 경로" + "description": "모델 경로" } ] \ No newline at end of file diff --git a/GameData/Tower.csv b/GameData/Tower.csv index ffbde1e..6dd9fb9 100644 --- a/GameData/Tower.csv +++ b/GameData/Tower.csv @@ -1,3 +1,3 @@ -id,memo,mana,manpower,size_x,size_y,max_hp,atk_range,atk_damage,atk_interval_sec,prefab_path -1,타워,25,10,3,3,50,10,5,2,Assets/Prefabs/TowerArrow -2,벽,5,5,1,1,30,0,0,0,Assets/Prefabs/Wall +id,memo,mana,manpower,size_x,size_y,size_z,max_hp,atk_range,atk_damage,atk_interval_sec,model_path +1,타워,25,10,3,3,3,50,10,5,2,Assets/Models/building_tower_B_blue.fbx +2,벽,5,5,2,2,1,30,0,0,0,Assets/Models/wall_straight.fbx diff --git a/TOWER_CSV_IMPORTER.md b/TOWER_CSV_IMPORTER.md new file mode 100644 index 0000000..b49e3bf --- /dev/null +++ b/TOWER_CSV_IMPORTER.md @@ -0,0 +1,138 @@ +# Tower CSV Importer Guide + +## Overview +The tower CSV importer allows you to create tower prefabs from CSV data in one step, similar to the monster importer. + +## Files Created +1. **TowerDataComponent.cs** - Component that applies TowerData to a GameObject +2. **TowerPrefabSetup.cs** - Implementation of IPrefabSetup for tower prefab generation +3. **CSVToSOImporter.cs** - Generic CSV importer that works with any data type + +## How to Use + +### Step 1: Ensure Tower Template Exists +If you haven't created the TowerTemplate yet: +1. In Unity, go to `Tools > Data > Create Tower Template` +2. This creates `Assets/Data/Templates/TowerTemplate.prefab` with all required components: + - NetworkObject + - Building + - TowerDataComponent + - MeshFilter & MeshRenderer + - BoxCollider + - NavMeshObstacle + +### Step 2: Update Tower.csv +Edit `GameData/Tower.csv` with your tower data. The CSV uses camelCase field names matching TowerData class: + +```csv +id,memo,mana,manpower,sizeX,sizeY,maxHp,atkRange,atkDamage,atkIntervalSec,modelPath +1,타워,25,10,3,3,50,10,5,2,Assets/Meshes/building_tower_B_blue.fbx +2,벽,5,5,1,1,30,0,0,0,Assets/Meshes/building_tower_B_blue.fbx +``` + +**Field Descriptions:** +- `id`: Unique tower ID +- `memo`: Tower name/description +- `mana`: Mana cost to build +- `manpower`: Construction work required +- `sizeX`: Grid width +- `sizeY`: Grid length +- `maxHp`: Maximum health +- `atkRange`: Attack range +- `atkDamage`: Attack damage +- `atkIntervalSec`: Attack interval in seconds +- `modelPath`: Path to FBX model or mesh asset + +### Step 3: Import CSV +In Unity, go to `Tools > Data > Import All CSV` + +The importer will: +1. Create ScriptableObject files in `Assets/Data/ScriptableObjects/Tower/` +2. Create/Update prefabs in `Assets/Prefabs/Tower/` +3. Apply models from `modelPath` column +4. Configure components based on CSV data +5. Link TowerData to TowerDataComponent + +### Step 4: Use Tower Prefabs +Your generated tower prefabs are ready to use in the BuildingManager system! + +## File Structure After Import +``` +Assets/ +├── Data/ +│ ├── ScriptableObjects/ +│ │ └── Tower/ # SO files (generated from CSV) +│ │ ├── Tower1.asset +│ │ └── Tower2.asset +│ └── Templates/ # Template prefabs (created once) +│ └── TowerTemplate.prefab +├── Prefabs/ +│ └── Tower/ # Generated tower prefabs +│ ├── Tower1.prefab +│ └── Tower2.prefab +└── GameData/ + └── Tower.csv # Source data (editable) +``` + +## How It Works + +### CSV Import Pipeline +``` +Tower.csv (CSV data) + ↓ CSVToSOImporter +TowerData (ScriptableObject) + ↓ TowerPrefabSetup +Tower.prefab (GameObject with components) +``` + +### TowerPrefabSetup Logic +1. **TowerDataComponent**: Links TowerData SO to the prefab +2. **Model Application**: Loads and applies FBX model from modelPath +3. **Collider Setup**: Creates BoxCollider sized to tower dimensions +4. **Building Integration**: Converts TowerData to BuildingData for Building component + +## Benefits +- ✅ **One-click import**: Import all towers from CSV at once +- ✅ **Consistent structure**: All towers have the same components +- ✅ **Easy updates**: Edit CSV and re-import to update all towers +- ✅ **Designer-friendly**: Non-programmers can add new towers +- ✅ **Type-safe**: TowerData class ensures data integrity + +## Troubleshooting + +**"No prefab setup found for Tower"** +- Make sure TowerPrefabSetup.cs is in the Assets/Scripts/Editor folder +- Restart Unity Editor to ensure the script is compiled + +**"Template not found"** +- Run `Tools > Data > Create Tower Template` first +- Verify TowerTemplate.prefab exists in Assets/Data/Templates/ + +**Prefabs not created** +- Check the Console for error messages +- Verify Tower.csv exists in GameData folder +- Ensure modelPath in CSV points to valid assets + +**Model not showing** +- Verify modelPath in CSV is correct +- Check that the FBX file exists at the specified path +- Ensure the model has valid materials assigned + +## Customization + +### Adding New Components to All Towers +1. Open `Assets/Data/Templates/TowerTemplate.prefab` +2. Add the component +3. Configure defaults +4. Save template +5. Re-import CSV to apply changes to new towers + +### Modifying Existing Towers +- Edit the prefab directly (changes persist on next import) +- OR modify Tower.csv and re-import (will update SO link and model) + +## Notes +- TowerDataComponent converts TowerData to BuildingData for compatibility with the existing Building system +- The importer creates prefabs if they don't exist, or updates existing ones +- Prefab edits (other than SO and model) are preserved on re-import +- CSV field names must match TowerData class property names exactly (case-sensitive, camelCase) diff --git a/TOWER_QUICKSLOT_SETUP.md b/TOWER_QUICKSLOT_SETUP.md new file mode 100644 index 0000000..060925c --- /dev/null +++ b/TOWER_QUICKSLOT_SETUP.md @@ -0,0 +1,120 @@ +# Tower Quickslot Setup Guide + +## 🎯 ULTRA-SIMPLE 1-CLICK SETUP (For Non-Programmers!) + +### Just ONE Step! + +Edit your `GameData/Tower.csv` file with tower data, then in Unity: + +``` +Tools > Data > Import All CSV +``` + +**THAT'S IT!** This automatically does everything: +- ✅ Creates TowerData from CSV (TowerData now extends BuildingData!) +- ✅ Creates Tower prefabs with TowerDataComponent +- ✅ **Auto-configures BuildingManager with all TowerData!** + +### Testing +Press **B** in-game → All towers appear in quickslot! 🎉 + +--- + +## 📝 Adding New Towers + +1. Add row to `GameData/Tower.csv` +2. Run `Tools > Data > Import All CSV` +3. Done! 🚀 + +Everything is automatic! + +--- + +## 🔧 Troubleshooting + +### Error: "BuildingManager not found in scene" + +**Cause:** Your scene doesn't have a GameObject with BuildingManager component. + +**Fix:** +1. Create a new GameObject (e.g., "BuildingManager") +2. Add BuildingManager component to it +3. Run `Tools > Data > Import All CSV` again +4. Done! + +### Error: "MissingReferenceException: prefab doesn't exist" + +**Cause:** TowerData doesn't have prefab reference. + +**Fix:** +1. Run `Northbound > Diagnose Tower System` +2. Check which TowerData shows `✗ MISSING PREFAB` +3. Run `Tools > Data > Import All CSV` to fix +4. Done! + +### No towers appear in quickslot + +**Cause:** BuildingManager wasn't found or configured. + +**Fix:** +1. Run `Northbound > Diagnose Tower System` +2. Check if BuildingManager is found and has TowerData in list +3. If not, add BuildingManager to your scene +4. Run `Tools > Data > Import All CSV` + +--- + +## 🎮 Menu Commands + +| Command | What it does | When to use | +|---------|--------------|--------------| +| `Tools > Data > Import All CSV` | **ONE-CLICK SETUP** - Import all CSV files, create prefabs, auto-configure BuildingManager with TowerData | After editing Tower.csv or anytime you want to update towers | +| `Northbound > Diagnose Tower System` | Check tower system health and find issues | When something doesn't work | + +--- + +## ✅ Why This is Awesome + +- ✅ **ONE CLICK** - Edit CSV, run importer, done! +- ✅ **One folder for towers** - `Assets/Prefabs/Tower/` only +- ✅ **No duplicates** - No manual copying anywhere +- ✅ **Fully automatic** - BuildingManager configured automatically +- ✅ **Non-programmer friendly** - Just edit CSV and click one button! +- ✅ **Works in builds** - Everything is pre-populated +- ✅ **Instant testing** - Press B and see all towers! +- ✅ **Unified data structure** - TowerData extends BuildingData, no redundant data! + +--- + +## 🎉 Complete Workflow for New Teammates + +1. Open Unity project +2. Add BuildingManager GameObject to scene (once) +3. Edit `GameData/Tower.csv` with tower data +4. Run `Tools > Data > Import All CSV` +5. Play game, press **B**, build towers! 🏗️ + +**That's literally it! No manual configuration needed!** + +--- + +## 🏗️ Technical Details + +### Unified Data Structure + +**Before:** Two separate data systems +- TowerData (CSV, tower-specific stats) +- BuildingData (auto-generated, building stats) + +**Now:** Single unified system +- TowerData extends BuildingData +- TowerData has all tower-specific fields (atkRange, atkDamage, etc.) +- TowerData automatically maps to BuildingData fields (width, length, maxHealth, etc.) +- BuildingManager uses TowerData directly (no conversion needed!) + +### Benefits of Unified Structure +- ✅ No duplicate data +- ✅ Single source of truth +- ✅ Cleaner code +- ✅ Easier to maintain +- ✅ Tower prefabs can be used directly without intermediate BuildingData files diff --git a/Unity.RenderPipelines.Universal.Runtime.csproj b/Unity.RenderPipelines.Universal.Runtime.csproj index c30acff..faa692e 100644 --- a/Unity.RenderPipelines.Universal.Runtime.csproj +++ b/Unity.RenderPipelines.Universal.Runtime.csproj @@ -43,14 +43,15 @@ 6000.3.5f2 + - + @@ -142,8 +143,8 @@ - + @@ -246,8 +247,8 @@ - +