diff --git a/Assets/DefaultNetworkPrefabs.asset b/Assets/DefaultNetworkPrefabs.asset index 57c9179..27abd08 100644 --- a/Assets/DefaultNetworkPrefabs.asset +++ b/Assets/DefaultNetworkPrefabs.asset @@ -34,6 +34,11 @@ MonoBehaviour: SourcePrefabToOverride: {fileID: 0} SourceHashToOverride: 0 OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 7720770984308489338, guid: dff852699e2897b4494fcbc7f7e547d6, type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} - Override: 0 Prefab: {fileID: 2664719039363295382, guid: dc2e4a4108e03874a8b2dab88dcc8fba, type: 3} SourcePrefabToOverride: {fileID: 0} @@ -94,8 +99,3 @@ MonoBehaviour: SourcePrefabToOverride: {fileID: 0} SourceHashToOverride: 0 OverridingTargetPrefab: {fileID: 0} - - Override: 0 - Prefab: {fileID: 7720770984308489338, guid: dff852699e2897b4494fcbc7f7e547d6, type: 3} - SourcePrefabToOverride: {fileID: 0} - SourceHashToOverride: 0 - OverridingTargetPrefab: {fileID: 0} diff --git a/Assets/_Project/Prefabs/Towers/Tower Construction Sets/BuildSiteVisual.prefab b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/BuildSiteVisual.prefab index 6d0724b..b77e65d 100644 --- a/Assets/_Project/Prefabs/Towers/Tower Construction Sets/BuildSiteVisual.prefab +++ b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/BuildSiteVisual.prefab @@ -1,5 +1,117 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: +--- !u!1 &2381228775386571742 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2082013748313019226} + - component: {fileID: 7119837420184958461} + - component: {fileID: 8833246162440246558} + - component: {fileID: 1909402251021719060} + m_Layer: 0 + m_Name: Scale Target + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2082013748313019226 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2381228775386571742} + 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: 1531733800731892084} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &7119837420184958461 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2381228775386571742} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &8833246162440246558 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2381228775386571742} + 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: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2} + 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!65 &1909402251021719060 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2381228775386571742} + 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: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} --- !u!1 &4243270647055755528 GameObject: m_ObjectHideFlags: 0 @@ -138,6 +250,7 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: + - {fileID: 2082013748313019226} - {fileID: 1059634071631389929} - {fileID: 3705223059275757242} m_Father: {fileID: 0} @@ -181,10 +294,14 @@ MonoBehaviour: m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.BuildSiteVisual ShowTopMostFoldoutHeaderGroup: 1 tintedRenderers: [] + scaleTarget: {fileID: 2082013748313019226} queuedMaterial: {fileID: 2100000, guid: f8d951a6841d3f74098bb31255379774, type: 2} constructingMaterial: {fileID: 2100000, guid: 88f1dd7b174716645953857b38fb6948, type: 2} pausedMaterial: {fileID: 0} + defaultPhaseSet: {fileID: 11400000, guid: ed951755c09d6d0479b4fd924b6915da, type: 2} dropReticlePrefab: {fileID: 4110617398237858862, guid: f2a37509f5f2e4d4e86cdaf12f99c6c4, type: 3} + stageCount: 4 + queuedYScale: 0.15 --- !u!65 &6259437393614329336 BoxCollider: m_ObjectHideFlags: 0 diff --git a/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet.meta b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet.meta new file mode 100644 index 0000000..e070754 --- /dev/null +++ b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 82e418e7a5a804747a9a4865648b7793 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstructionSet.asset b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstructionSet.asset new file mode 100644 index 0000000..2272a43 --- /dev/null +++ b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstructionSet.asset @@ -0,0 +1,18 @@ +%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: c8f2a4e1b9d6437052a1e8c4f7b3d069, type: 3} + m_Name: DefaultConstructionSet + m_EditorClassIdentifier: Assembly-CSharp::TD.Towers.ConstructionPhaseSet + phases: + - {fileID: 562891720401665892, guid: e7be86c29087e99439507b508425b612, type: 3} + - {fileID: 3284400382278582069, guid: c6dabc822d0afb746adc08fb8602c2b4, type: 3} + - {fileID: 2161157853692362223, guid: d00c71c0cfc7e8744b9f8c1d48c2d256, type: 3} diff --git a/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstructionSet.asset.meta b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstructionSet.asset.meta new file mode 100644 index 0000000..3832c3f --- /dev/null +++ b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstructionSet.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ed951755c09d6d0479b4fd924b6915da +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_1.prefab b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_1.prefab new file mode 100644 index 0000000..70ca06b --- /dev/null +++ b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_1.prefab @@ -0,0 +1,114 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &562891720401665892 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5433206400477731590} + - component: {fileID: 3041202948021905482} + - component: {fileID: 2318454595080774531} + - component: {fileID: 2971339723339766249} + m_Layer: 0 + m_Name: DefaultConstruction_Phase_1 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &5433206400477731590 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 562891720401665892} + 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: 0.1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &3041202948021905482 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 562891720401665892} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &2318454595080774531 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 562891720401665892} + 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: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2} + 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!65 &2971339723339766249 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 562891720401665892} + 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: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} diff --git a/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_1.prefab.meta b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_1.prefab.meta new file mode 100644 index 0000000..684c909 --- /dev/null +++ b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_1.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e7be86c29087e99439507b508425b612 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_2.prefab b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_2.prefab new file mode 100644 index 0000000..43ed50f --- /dev/null +++ b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_2.prefab @@ -0,0 +1,114 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &3284400382278582069 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3820746952356246079} + - component: {fileID: 3350984935134180217} + - component: {fileID: 6336690892943026752} + - component: {fileID: 2003287843732108245} + m_Layer: 0 + m_Name: DefaultConstruction_Phase_2 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3820746952356246079 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3284400382278582069} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1.5, y: 0.5, z: 1.5} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &3350984935134180217 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3284400382278582069} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &6336690892943026752 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3284400382278582069} + 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: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2} + 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!65 &2003287843732108245 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3284400382278582069} + 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: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} diff --git a/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_2.prefab.meta b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_2.prefab.meta new file mode 100644 index 0000000..bb668c4 --- /dev/null +++ b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_2.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c6dabc822d0afb746adc08fb8602c2b4 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_3.prefab b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_3.prefab new file mode 100644 index 0000000..0c380ed --- /dev/null +++ b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_3.prefab @@ -0,0 +1,114 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &2161157853692362223 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6591719589271492770} + - component: {fileID: 3693505870455731207} + - component: {fileID: 2366594505425509977} + - component: {fileID: 5474707419433840976} + m_Layer: 0 + m_Name: DefaultConstruction_Phase_3 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &6591719589271492770 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2161157853692362223} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1.75, y: 1, z: 1.75} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &3693505870455731207 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2161157853692362223} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &2366594505425509977 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2161157853692362223} + 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: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2} + 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!65 &5474707419433840976 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2161157853692362223} + 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: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} diff --git a/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_3.prefab.meta b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_3.prefab.meta new file mode 100644 index 0000000..dc59d87 --- /dev/null +++ b/Assets/_Project/Prefabs/Towers/Tower Construction Sets/DefaultConstructionSet/DefaultConstruction_Phase_3.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d00c71c0cfc7e8744b9f8c1d48c2d256 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Project/Prefabs/Towers/Tower_BasicArrow.prefab b/Assets/_Project/Prefabs/Towers/Tower_BasicArrow.prefab index f21641d..72ae323 100644 --- a/Assets/_Project/Prefabs/Towers/Tower_BasicArrow.prefab +++ b/Assets/_Project/Prefabs/Towers/Tower_BasicArrow.prefab @@ -70,8 +70,6 @@ GameObject: - component: {fileID: 805962841523123163} - component: {fileID: 8853488620519990682} - component: {fileID: 5360241685303413177} - - component: {fileID: 5793816278935258120} - - component: {fileID: 3412005213656160288} m_Layer: 0 m_Name: Tower_BasicArrow m_TagString: Untagged @@ -214,8 +212,6 @@ MonoBehaviour: ShowTopMostFoldoutHeaderGroup: 1 tintedRenderers: - {fileID: 4028055828417179692} - dropHeight: 15 - landingDuration: 0.4 --- !u!114 &805962841523123163 MonoBehaviour: m_ObjectHideFlags: 0 @@ -256,67 +252,12 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 93bc533262394e1e8b122bbfad89391a, type: 3} - m_Name: + m_Name: m_EditorClassIdentifier: Assembly-CSharp::TD.Visuals.ConeMesh sides: 4 radius: 0.7071068 height: 1.5 angularOffsetDegrees: 45 ---- !u!114 &5793816278935258120 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 6482414459531823157} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 22d67b2aa780d786a93acfe06d1909b0, type: 3} - m_Name: - m_EditorClassIdentifier: Assembly-CSharp::TD.Combat.TowerLandedSound - landedSound: - clip: {fileID: 0} - volume: 0 - minPitch: 0 - maxPitch: 0 ---- !u!114 &3412005213656160288 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 6482414459531823157} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: bf337521317d9e297a652e97c666376f, type: 3} - m_Name: - m_EditorClassIdentifier: Assembly-CSharp::TD.Combat.TowerLandingVisual - fallCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0 - outWeight: 0 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0 - outWeight: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - impactVfxPrefab: {fileID: 0} - impactVfxLifetime: 3 --- !u!1 &7580197837852108944 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/_Project/Prefabs/Towers/Tower_SiegeCannon.prefab b/Assets/_Project/Prefabs/Towers/Tower_SiegeCannon.prefab index f7020d7..1c6e32f 100644 --- a/Assets/_Project/Prefabs/Towers/Tower_SiegeCannon.prefab +++ b/Assets/_Project/Prefabs/Towers/Tower_SiegeCannon.prefab @@ -69,8 +69,6 @@ GameObject: - component: {fileID: 9137031893466587143} - component: {fileID: 805962841523123163} - component: {fileID: 8853488620519990682} - - component: {fileID: 3021373172845454683} - - component: {fileID: 4003901452716391977} m_Layer: 0 m_Name: Tower_SiegeCannon m_TagString: Untagged @@ -183,9 +181,9 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} - m_Name: + m_Name: m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject - GlobalObjectIdHash: 2153184693 + GlobalObjectIdHash: 3344551122 InScenePlacedSourceGlobalObjectIdHash: 0 DeferredDespawnTick: 0 Ownership: 1 @@ -208,13 +206,11 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fb111fc88b3d6a340a3abde5a1502af3, type: 3} - m_Name: + m_Name: m_EditorClassIdentifier: Assembly-CSharp::TD.Gameplay.TowerInstance ShowTopMostFoldoutHeaderGroup: 1 tintedRenderers: - {fileID: 4028055828417179692} - dropHeight: 15 - landingDuration: 0.4 --- !u!114 &805962841523123163 MonoBehaviour: m_ObjectHideFlags: 0 @@ -225,7 +221,7 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 7eb6cce6cd96b23478b7d2173cebf74d, type: 3} - m_Name: + m_Name: m_EditorClassIdentifier: Assembly-CSharp::TD.Combat.TowerCombat ShowTopMostFoldoutHeaderGroup: 1 enemyLayerMask: @@ -241,65 +237,10 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: c0edb0c5206ca454bbd7c300c6cc7574, type: 3} - m_Name: + m_Name: m_EditorClassIdentifier: Assembly-CSharp::TD.Combat.TowerRangeIndicator rangeProjector: {fileID: 8255517343120954594} projectionDepth: 50 ---- !u!114 &3021373172845454683 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 6482414459531823157} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 22d67b2aa780d786a93acfe06d1909b0, type: 3} - m_Name: - m_EditorClassIdentifier: Assembly-CSharp::TD.Combat.TowerLandedSound - landedSound: - clip: {fileID: 0} - volume: 0 - minPitch: 0 - maxPitch: 0 ---- !u!114 &4003901452716391977 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 6482414459531823157} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: bf337521317d9e297a652e97c666376f, type: 3} - m_Name: - m_EditorClassIdentifier: Assembly-CSharp::TD.Combat.TowerLandingVisual - fallCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0 - outWeight: 0 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0 - outWeight: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - impactVfxPrefab: {fileID: 0} - impactVfxLifetime: 3 --- !u!1 &7580197837852108944 GameObject: m_ObjectHideFlags: 0 @@ -342,7 +283,7 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 0777d029ed3dffa4692f417d4aba19ca, type: 3} - m_Name: + m_Name: m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.DecalProjector m_Material: {fileID: 2100000, guid: f99227cbde481ce47a2527e6bca709d2, type: 2} m_DrawDistance: 1000 diff --git a/Assets/_Project/Prefabs/Towers/Tower_TeslaCoil.prefab b/Assets/_Project/Prefabs/Towers/Tower_TeslaCoil.prefab index 3694acf..ede5f43 100644 --- a/Assets/_Project/Prefabs/Towers/Tower_TeslaCoil.prefab +++ b/Assets/_Project/Prefabs/Towers/Tower_TeslaCoil.prefab @@ -101,8 +101,6 @@ GameObject: - component: {fileID: 4524938955752569428} - component: {fileID: -2590971686077483651} - component: {fileID: 1288485127287735786} - - component: {fileID: 1829137298732744432} - - component: {fileID: 8125712573731754244} m_Layer: 0 m_Name: Tower_TeslaCoil m_TagString: Untagged @@ -149,7 +147,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} m_Name: m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject - GlobalObjectIdHash: 1363936954 + GlobalObjectIdHash: 280718094 InScenePlacedSourceGlobalObjectIdHash: 0 DeferredDespawnTick: 0 Ownership: 1 @@ -177,8 +175,6 @@ MonoBehaviour: ShowTopMostFoldoutHeaderGroup: 1 tintedRenderers: - {fileID: 0} - dropHeight: 15 - landingDuration: 0.4 --- !u!114 &805962841523123163 MonoBehaviour: m_ObjectHideFlags: 0 @@ -272,61 +268,6 @@ MonoBehaviour: volume: 0.496 minPitch: 1 maxPitch: 1 ---- !u!114 &1829137298732744432 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 6482414459531823157} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 22d67b2aa780d786a93acfe06d1909b0, type: 3} - m_Name: - m_EditorClassIdentifier: Assembly-CSharp::TD.Combat.TowerLandedSound - landedSound: - clip: {fileID: 0} - volume: 0 - minPitch: 0 - maxPitch: 0 ---- !u!114 &8125712573731754244 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 6482414459531823157} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: bf337521317d9e297a652e97c666376f, type: 3} - m_Name: - m_EditorClassIdentifier: Assembly-CSharp::TD.Combat.TowerLandingVisual - fallCurve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0 - outWeight: 0 - - serializedVersion: 3 - time: 1 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 0 - weightedMode: 0 - inWeight: 0 - outWeight: 0 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - impactVfxPrefab: {fileID: 0} - impactVfxLifetime: 3 --- !u!1 &7101790219931971190 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/_Project/Scripts/Combat/TowerCombat.cs b/Assets/_Project/Scripts/Combat/TowerCombat.cs index 6c1a53f..9c9ac7c 100644 --- a/Assets/_Project/Scripts/Combat/TowerCombat.cs +++ b/Assets/_Project/Scripts/Combat/TowerCombat.cs @@ -58,12 +58,6 @@ namespace TD.Combat // is in range, the tower fires and the timer resets to 1 / AttacksPerSecond. private float attackCooldown; - // Counts down from towerInstance.LandingDuration, set in OnNetworkSpawn. Combat is - // fully inert until it reaches zero, so a tower can't target/fire while its mesh is - // still visually falling (TowerLandingVisual). Server-only; independent of whatever - // the client-side fall visual is doing to the (possibly shared, on a host) transform. - private float landingCooldown; - // Cached on OnNetworkSpawn — avoids GetComponent every Update. private TowerInstance towerInstance; @@ -108,7 +102,6 @@ namespace TD.Combat public override void OnNetworkSpawn() { towerInstance = GetComponent(); - landingCooldown = towerInstance.LandingDuration; replicatedTarget.OnValueChanged += HandleReplicatedTargetChanged; // Late-joining clients receive the NV's current value in the initial @@ -135,12 +128,6 @@ namespace TD.Combat { if (!IsServer) return; - if (landingCooldown > 0f) - { - landingCooldown -= Time.deltaTime; - return; - } - TowerDefinition def = towerInstance?.Definition; if (def == null || def.Range <= 0f || def.AttacksPerSecond <= 0f) return; diff --git a/Assets/_Project/Scripts/Combat/TowerLandedSound.cs b/Assets/_Project/Scripts/Combat/TowerLandedSound.cs deleted file mode 100644 index b650d58..0000000 --- a/Assets/_Project/Scripts/Combat/TowerLandedSound.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Assets/_Project/Scripts/Combat/TowerLandedSound.cs -using TD.Audio; -using TD.Gameplay; -using UnityEngine; - -namespace TD.Combat -{ - /// - /// Local-only audio for the tower's landing impact. Subscribes to - /// and plays a sound on every peer when the - /// tower's fall animation () finishes. - /// Attach to any tower prefab and assign its clip in the Inspector. - /// - [RequireComponent(typeof(TowerInstance))] - public class TowerLandedSound : MonoBehaviour - { - [SerializeField] private SoundConfig landedSound; - - private TowerInstance towerInstance; - - private void Awake() - { - towerInstance = GetComponent(); - } - - private void OnEnable() - { - if (towerInstance != null) towerInstance.OnLandedClient += HandleLanded; - } - - private void OnDisable() - { - if (towerInstance != null) towerInstance.OnLandedClient -= HandleLanded; - } - - private void HandleLanded() - { - AudioManager.Instance?.Play(landedSound.clip, AudioCategory.UI, landedSound.RandomPitch(), landedSound.volume); - } - } -} diff --git a/Assets/_Project/Scripts/Combat/TowerLandedSound.cs.meta b/Assets/_Project/Scripts/Combat/TowerLandedSound.cs.meta deleted file mode 100644 index 2adf2ce..0000000 --- a/Assets/_Project/Scripts/Combat/TowerLandedSound.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 22d67b2aa780d786a93acfe06d1909b0 \ No newline at end of file diff --git a/Assets/_Project/Scripts/Combat/TowerLandingVisual.cs b/Assets/_Project/Scripts/Combat/TowerLandingVisual.cs deleted file mode 100644 index 6031327..0000000 --- a/Assets/_Project/Scripts/Combat/TowerLandingVisual.cs +++ /dev/null @@ -1,104 +0,0 @@ -// Assets/_Project/Scripts/Combat/TowerLandingVisual.cs -using System.Collections; -using TD.Gameplay; -using UnityEngine; - -namespace TD.Combat -{ - /// - /// Local-only "falls from the sky and lands" spawn visual. Subscribes to - /// and, on every client (never on a - /// dedicated server, which has no camera to show it to), animates the tower's - /// transform down from above its already-correct - /// resting position over seconds. - /// - /// - /// No NetworkTransform involved. Tower prefabs have no NetworkTransform — - /// position is a one-shot snapshot sent at spawn. This animation is purely local per - /// peer (same pattern as 's audio cue); each peer computes - /// an identical animation independently from the same replicated landing position and - /// the same authored / - /// values, so no networking is required. - /// - /// Safe on a host despite sharing one Transform with server combat logic. - /// withholds all targeting/attack logic for - /// seconds after spawn (see its - /// landingCooldown field), so it never reads transform.position while this - /// animation is moving it. The two timers start from the same value in the same call - /// ( fires from OnNetworkSpawn), so they - /// finish within a frame of each other. - /// - /// Root transform, not a child wrapper. Tower prefabs render their mesh - /// directly on the root GameObject (no separate "Model" child exists to offset - /// instead), so this animates transform.position directly. Footprint/pathing is - /// unaffected — stamps walkability from its replicated - /// anchor tile (grid data), not from transform.position. - /// - [RequireComponent(typeof(TowerInstance))] - public class TowerLandingVisual : MonoBehaviour - { - [Tooltip("Eases the fall over LandingDuration. X = normalized time, Y = normalized " + - "fraction of DropHeight already descended (0 = still at drop height, 1 = landed).")] - [SerializeField] private AnimationCurve fallCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f); - - [Tooltip("Optional impact VFX (dust burst, etc.) instantiated at the landing point when " + - "the fall finishes. Leave empty for no VFX.")] - [SerializeField] private GameObject impactVfxPrefab; - - [Tooltip("Seconds before the instantiated impact VFX is destroyed. Ignored if " + - "impactVfxPrefab is unassigned.")] - [SerializeField] private float impactVfxLifetime = 3f; - - private TowerInstance towerInstance; - - private void Awake() - { - towerInstance = GetComponent(); - } - - private void OnEnable() - { - if (towerInstance != null) towerInstance.OnBuiltClient += HandleBuilt; - } - - private void OnDisable() - { - if (towerInstance != null) towerInstance.OnBuiltClient -= HandleBuilt; - } - - private void HandleBuilt() - { - // Dedicated (non-host) servers have no camera/visuals and must never move the - // shared transform. TowerCombat's landing gate is fully independent of this - // animation, so skipping it here on a pure server is a harmless no-op. - if (!towerInstance.IsClient) return; - - StartCoroutine(AnimateDrop()); - } - - private IEnumerator AnimateDrop() - { - Vector3 landedPosition = transform.position; // already correct (SeatOnGround, pre-spawn) - float dropHeight = towerInstance.DropHeight; - float duration = towerInstance.LandingDuration; - - transform.position = landedPosition + Vector3.up * dropHeight; - - float t = 0f; - while (t < duration) - { - t += Time.deltaTime; - float u = fallCurve.Evaluate(Mathf.Clamp01(t / duration)); - transform.position = landedPosition + Vector3.up * dropHeight * (1f - u); - yield return null; - } - - transform.position = landedPosition; // snap exactly, avoid float drift - - if (impactVfxPrefab != null) - Destroy(Instantiate(impactVfxPrefab, landedPosition, Quaternion.identity), impactVfxLifetime); - - towerInstance.ClientNotifyLanded(); - } - } -} diff --git a/Assets/_Project/Scripts/Combat/TowerLandingVisual.cs.meta b/Assets/_Project/Scripts/Combat/TowerLandingVisual.cs.meta deleted file mode 100644 index 8ad9019..0000000 --- a/Assets/_Project/Scripts/Combat/TowerLandingVisual.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: bf337521317d9e297a652e97c666376f \ No newline at end of file diff --git a/Assets/_Project/Scripts/Gameplay/BuildSiteVisual.cs b/Assets/_Project/Scripts/Gameplay/BuildSiteVisual.cs index f51b10d..be09946 100644 --- a/Assets/_Project/Scripts/Gameplay/BuildSiteVisual.cs +++ b/Assets/_Project/Scripts/Gameplay/BuildSiteVisual.cs @@ -8,16 +8,15 @@ using TD.VFX; namespace TD.Gameplay { /// - /// Visual representation of an in-flight : a static, non-growing - /// site marker (color-tinted by stage) plus the ground targeting reticle - /// () that shrinks as construction progresses. One - /// NetworkObject per active job. Despawned when the job is cancelled or when the real - /// takes its place at construction-complete, at which point - /// TowerLandingVisual plays the tower's fall-from-sky arrival. + /// Visual representation of an in-flight : the green + /// queued ghost, and the staged construction animation (4 stages of growing + /// height for the testing cube). One NetworkObject per active job. Despawned + /// when the job is cancelled or when the real + /// takes its place at construction-complete. /// /// /// Why a separate prefab from TowerInstance. The build-site visual - /// has different rendering (translucent green site marker), no combat, + /// has different rendering (transparent green or partial-height cube), no combat, /// no grid-stamping (the Builder owns those state transitions), and a much /// shorter lifecycle. Sharing a prefab with TowerInstance would mean adding /// "am I real or a ghost" branching to every TowerInstance code path. Two @@ -28,9 +27,10 @@ namespace TD.Gameplay /// from NetworkManager.ServerTime.TimeAsFloat. Only the server writes; /// clients read. /// - /// Visual model. The site marker's material swaps by stage (queued/ - /// constructing/paused) but never grows or changes shape — construction progress is - /// communicated entirely by the reticle shrinking, not by the marker itself. + /// Visual model. The prefab inspector points at a re-tinted copy + /// of the tower's mesh (the same testing cube). At Stage = Queued, the visual + /// is a translucent green cube at full footprint scale but reduced Y. At + /// Stage = Constructing, the cube grows in 4 sub-stages over BuildTime. /// /// No grid stamping here. Walkability and occupancy stamps are /// driven by the Builder (queue-time stamps occupied=true / walkable=true, @@ -48,6 +48,10 @@ namespace TD.Gameplay "MeshRenderer on the prefab. Auto-populated from children if empty.")] [SerializeField] private MeshRenderer[] tintedRenderers; + [Tooltip("Transform that gets Y-scaled to represent construction progress. " + + "Typically the visual mesh's transform. The growth axis is local Y.")] + [SerializeField] private Transform scaleTarget; + [Tooltip("Material applied while the job is Queued (translucent green).")] [SerializeField] private Material queuedMaterial; @@ -59,6 +63,13 @@ namespace TD.Gameplay "Suggested: muted/grey-tinted variant of the constructing material.")] [SerializeField] private Material pausedMaterial; + [Header("Construction phases")] + [Tooltip("Project-default construction-stage visuals used when the tower being built " + + "doesn't define its own ConstructionPhases. When this (or the tower's set) " + + "has phases, the build site swaps between those phase prefabs as it builds. " + + "Leave empty to fall back to the legacy cube Y-scale growth below.")] + [SerializeField] private ConstructionPhaseSet defaultPhaseSet; + [Header("Drop reticle FX")] [Tooltip("Optional targeting-reticle effect (ground decal + beam + motes) shown for the " + "life of this build. Spawned as a child on every peer and fed construction " + @@ -66,6 +77,16 @@ namespace TD.Gameplay "this visual at completion/cancel. Leave empty to build with no reticle.")] [SerializeField] private TowerDropReticle dropReticlePrefab; + [Header("Construction stages (cube fallback)")] + [Tooltip("FALLBACK ONLY (no phase set assigned): number of discrete growth stages " + + "while constructing. 4 = 1/4 → 2/4 → 3/4 → 4/4 height.")] + [SerializeField] private int stageCount = 4; + + [Tooltip("FALLBACK ONLY: Y-scale applied to scaleTarget when Stage == Queued. " + + "Visually distinct from any constructing height so the queued ghost reads " + + "as 'intent, not progress'.")] + [SerializeField] private float queuedYScale = 0.15f; + // ----- Networked state -------------------------------------------- // Replicated owner slot for color tinting. Mirrors TowerInstance. @@ -112,7 +133,7 @@ namespace TD.Gameplay readPerm: NetworkVariableReadPermission.Everyone, writePerm: NetworkVariableWritePermission.Server); - // Current stage. Drives the site marker's material/tint swap. + // Current stage. Drives material swap and Y-scale animation. private readonly NetworkVariable currentStage = new NetworkVariable( BuildStage.Queued, @@ -223,6 +244,17 @@ namespace TD.Gameplay private int pendingGoldSpent; private bool hasPendingInit; + // ----- Construction-phase runtime (local, all peers) -------------- + + // Resolved on spawn from the tower's ConstructionPhases or the defaultPhaseSet. + // When non-null with PhaseCount > 0, the build site swaps between these + // instantiated phase prefabs instead of Y-scaling the fallback cube. + private ConstructionPhaseSet effectivePhaseSet; + private GameObject[] phaseInstances; // one instantiated child per phase + private MeshRenderer[][] phaseRenderers; // cached renderers per phase, for tinting + private int activePhaseIndex = -1; + private bool usePhases; + // Spawned child targeting-reticle effect (local, all peers). Fed progress in Update; // destroyed automatically with this NetworkObject at completion/cancel. private TowerDropReticle dropReticleInstance; @@ -275,6 +307,10 @@ namespace TD.Gameplay hasPendingInit = false; } + // Resolve and instantiate the construction-phase visuals (or fall back to the + // cube). Depends on towerTypeId, which is replicated by now on every peer. + ResolvePhaseSet(); + // Spawn the targeting-reticle FX as a local child. It reads this build site's // replicated progress (fed in Update) and dies with us at completion/cancel. if (dropReticlePrefab != null) @@ -288,7 +324,7 @@ namespace TD.Gameplay currentStage.OnValueChanged += HandleStageChanged; // Apply initial visual state based on the (now-replicated) values. - ApplyStageMaterialAndTint(currentStage.Value); + ApplyStageVisual(currentStage.Value); } public override void OnNetworkDespawn() @@ -340,10 +376,30 @@ namespace TD.Gameplay { // Drive the targeting reticle on every peer, every stage: 0 while Queued // (full-size reticle, awaiting a builder), shrinking while Constructing, frozen - // while Paused. This is the only per-frame visual effect on the build site — - // nothing about the site's mesh grows or changes shape during construction. + // while Paused. Kept before the Constructing early-return so it also animates + // the queued/paused states. if (dropReticleInstance != null) dropReticleInstance.SetProgress(ComputeProgressNormalized()); + + // While constructing, advance the visual based on server time. Runs on every + // peer so visuals stay synchronized. Paused does NOT update — the visual is + // frozen at the pause point. + if (currentStage.Value != BuildStage.Constructing) return; + + if (usePhases) + { + int index = PhaseIndexFromProgress(); + if (index != activePhaseIndex) + { + ShowPhase(index); + // Renderers changed with the swap — re-apply material + owner tint. + ApplyStageMaterialAndTint(BuildStage.Constructing); + } + return; + } + + // Fallback: smoothly grow the cube's Y-scale through the stages. + ApplyYScale(ComputeConstructingYScale()); } // ----- Server API ------------------------------------------------- @@ -466,9 +522,9 @@ namespace TD.Gameplay /// /// Server-only: transitions Constructing → Paused AND writes the new - /// accumulated construction time (freezing the reticle's shrink progress at that - /// point). After this returns, the visual is fully self-describing — it carries - /// enough state to be shelved and later resumed. + /// accumulated construction time. Y-scale freezes at the level matching + /// the accumulated time. After this returns, the visual is fully self- + /// describing — it carries enough state to be shelved and later resumed. /// public void ServerPauseAndPersistAccumulated(float totalAccumulated) { @@ -486,11 +542,37 @@ namespace TD.Gameplay private void HandleStageChanged(BuildStage previous, BuildStage current) { - ApplyStageMaterialAndTint(current); + ApplyStageVisual(current); } - // Applies the stage's material + owner tint to the site marker's renderers. - // Paused falls back to the constructing material if no paused material is assigned. + private void ApplyStageVisual(BuildStage stage) + { + if (usePhases) + { + // Queued shows the first phase; constructing/paused show the phase + // matching current progress. ShowPhase repoints tintedRenderers at the + // active phase instance, so material + tint are applied AFTER it. + int index = stage == BuildStage.Queued ? 0 : PhaseIndexFromProgress(); + ShowPhase(index); + ApplyStageMaterialAndTint(stage); + return; + } + + // Fallback: legacy cube Y-scale growth (no phase set wired). + ApplyStageMaterialAndTint(stage); + switch (stage) + { + case BuildStage.Queued: ApplyYScale(queuedYScale); break; + case BuildStage.Constructing: ApplyYScale(ComputeConstructingYScale()); break; + // ComputePausedYScale uses accumulatedConstructionTime alone when + // constructionStartServerTime is -1 (the pause sentinel). + case BuildStage.Paused: ApplyYScale(ComputePausedYScale()); break; + } + } + + // Applies the stage's material + owner tint to whatever renderers are currently + // active — the cube fallback, or the active phase instance's renderers. Paused + // falls back to the constructing material if no paused material is assigned. private void ApplyStageMaterialAndTint(BuildStage stage) { switch (stage) @@ -509,6 +591,115 @@ namespace TD.Gameplay } } + // ----- Construction phases ---------------------------------------- + + // Resolves the effective phase set (tower's own, else the project default) and + // instantiates one inactive child per phase. Sets usePhases=false (cube fallback) + // if neither set has any phases. Runs on every peer in OnNetworkSpawn. + private void ResolvePhaseSet() + { + var def = TowerPlacementManager.GetDefinition(towerTypeId.Value); + effectivePhaseSet = + (def != null && def.ConstructionPhases != null && def.ConstructionPhases.PhaseCount > 0) + ? def.ConstructionPhases + : defaultPhaseSet; + + int n = effectivePhaseSet != null ? effectivePhaseSet.PhaseCount : 0; + if (n <= 0) + { + usePhases = false; + return; + } + + usePhases = true; + phaseInstances = new GameObject[n]; + phaseRenderers = new MeshRenderer[n][]; + + // Hide the legacy fallback cube — the instantiated phase prefabs replace it. + if (scaleTarget != null) scaleTarget.gameObject.SetActive(false); + + for (int i = 0; i < n; i++) + { + var prefab = effectivePhaseSet.GetPhase(i); + if (prefab == null) continue; + + var go = Instantiate(prefab, transform); + go.transform.localPosition = Vector3.zero; + go.transform.localRotation = Quaternion.identity; + go.SetActive(false); + + phaseInstances[i] = go; + phaseRenderers[i] = go.GetComponentsInChildren(true); + } + } + + // Activates only phase and points tintedRenderers at its + // renderers so the existing material/tint helpers drive the active phase. + private void ShowPhase(int index) + { + if (phaseInstances == null) return; + index = Mathf.Clamp(index, 0, phaseInstances.Length - 1); + + for (int i = 0; i < phaseInstances.Length; i++) + if (phaseInstances[i] != null) + phaseInstances[i].SetActive(i == index); + + activePhaseIndex = index; + tintedRenderers = phaseRenderers[index]; + } + + // Maps current normalized progress to a phase index (0..PhaseCount-1). + private int PhaseIndexFromProgress() + { + int n = effectivePhaseSet != null ? effectivePhaseSet.PhaseCount : 1; + if (n <= 1) return 0; + float p = ComputeProgressNormalized(); + return Mathf.Clamp(Mathf.FloorToInt(p * n), 0, n - 1); + } + + // Stage index 0..stageCount-1 based on elapsed server time PLUS any accumulated + // time from previous Constructing runs (resume support). + // Returned Y-scale is (stageIndex + 1) / stageCount, so stage 0 = 1/4, + // stage 1 = 2/4, ..., stage stageCount-1 = 4/4 = full height. + private float ComputeConstructingYScale() + { + float bt = buildTime.Value; + if (bt <= 0f || stageCount <= 0) return 1f; + + float currentRunElapsed = (float)NetworkManager.Singleton.ServerTime.Time + - constructionStartServerTime.Value; + float total = currentRunElapsed + accumulatedConstructionTime.Value; + + float perStage = bt / stageCount; + int stageIndex = Mathf.Clamp( + Mathf.FloorToInt(total / perStage), + 0, stageCount - 1); + + return (stageIndex + 1f) / stageCount; + } + + // While Paused, only the accumulated time matters (no current run is in flight). + private float ComputePausedYScale() + { + float bt = buildTime.Value; + if (bt <= 0f || stageCount <= 0) return 1f; + + float total = accumulatedConstructionTime.Value; + float perStage = bt / stageCount; + int stageIndex = Mathf.Clamp( + Mathf.FloorToInt(total / perStage), + 0, stageCount - 1); + + return (stageIndex + 1f) / stageCount; + } + + private void ApplyYScale(float y) + { + if (scaleTarget == null) return; + Vector3 s = scaleTarget.localScale; + scaleTarget.localScale = new Vector3(s.x, y, s.z); + } + // ----- Material handling ------------------------------------------ private void SwapMaterial(Material mat) diff --git a/Assets/_Project/Scripts/Gameplay/TowerInstance.cs b/Assets/_Project/Scripts/Gameplay/TowerInstance.cs index 519ff04..e459f01 100644 --- a/Assets/_Project/Scripts/Gameplay/TowerInstance.cs +++ b/Assets/_Project/Scripts/Gameplay/TowerInstance.cs @@ -55,18 +55,6 @@ namespace TD.Gameplay "to exclude specific children.")] [SerializeField] private MeshRenderer[] tintedRenderers; - [Header("Landing (post-construction drop)")] - [Tooltip("World-unit height the tower visually drops from when construction completes. " + - "Consumed only by the client-side fall visual (TowerLandingVisual).")] - [SerializeField] private float dropHeight = 15f; - - [Tooltip("Seconds the fall-and-land animation takes. Single source of truth: " + - "TowerCombat withholds targeting/attacks for exactly this long " + - "(server-authoritative), and TowerLandingVisual uses the same value to time " + - "its client-side animation, so the two stay in lockstep without duplicating " + - "the number.")] - [SerializeField] private float landingDuration = 0.4f; - // ----- Networked state ------------------------------------------------ // The TowerTypeId (index into TowerPlacementManager's catalog) for this tower. @@ -144,13 +132,6 @@ namespace TD.Gameplay /// The footprint anchor tile (SW corner, world-tile coords). public Vector2Int AnchorTile => anchorTile.Value; - /// World-unit height the post-construction drop animation falls from. - public float DropHeight => dropHeight; - - /// Seconds the drop/land animation takes. Also how long TowerCombat withholds - /// targeting/attacks after construction completes. - public float LandingDuration => landingDuration; - // ----- ISelectable ---------------------------------------------------- // Absolute world-unit margin that the selection ring extends beyond the @@ -190,16 +171,6 @@ namespace TD.Gameplay /// Fired on ALL peers when this tower finishes construction and spawns. public event System.Action OnBuiltClient; - /// Fired locally on this peer when the client-side fall/land animation - /// finishes (see ). Analogous to - /// , but delayed by . - public event System.Action OnLandedClient; - - /// Called by when its local - /// fall/land animation finishes. Purely local — never invoked on a dedicated - /// (non-client) server, which never runs that animation. - public void ClientNotifyLanded() => OnLandedClient?.Invoke(); - // ----- Server-only initialization ------------------------------------- ///