Working MVP

This commit is contained in:
Michal Pikulski
2025-12-03 22:17:12 +01:00
parent d5ab69d944
commit 0b8d2a279f
58 changed files with 11037 additions and 1299 deletions

View File

@@ -15,7 +15,7 @@ MonoBehaviour:
m_DefaultGroup: 6f3207429a65b3e4b83935ac19791077
m_currentHash:
serializedVersion: 2
Hash: 94be6fe6efc6ce35e614dcae21e98818
Hash: ab5e2545873f5b7934dc716832e70d83
m_OptimizeCatalogSize: 0
m_BuildRemoteCatalog: 0
m_CatalogRequestsTimeout: 0

View File

@@ -12,9 +12,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 973f02063e5446598db4cbffdbf8f113, type: 3}
m_Name: CeilingFan
m_EditorClassIdentifier: AppleHillsScripts::Minigames.FortFight.Data.ProjectileData
projectileName: CeilingFan
prefab: {fileID: 0}
baseDamage: 25
prefab: {fileID: 4342087378442690536, guid: ff8b62fb437256043aa6bd0b5441316b, type: 3}
cooldownTime: 4
icon: {fileID: -765527507412255412, guid: f70246e6148769846aaea223ec0c2a55, type: 3}
displayName:
description:

View File

@@ -12,9 +12,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 973f02063e5446598db4cbffdbf8f113, type: 3}
m_Name: Toaster
m_EditorClassIdentifier: AppleHillsScripts::Minigames.FortFight.Data.ProjectileData
projectileName: Toaster
prefab: {fileID: 0}
baseDamage: 20
prefab: {fileID: 4820392328973485589, guid: a4b194a56edefa541b7c3bd7d70c8ba5, type: 3}
cooldownTime: 3
icon: {fileID: 6674386295937086461, guid: 3bd1c178a78fcd144965cd1731dc309b, type: 3}
displayName:
description:

View File

@@ -12,9 +12,9 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 973f02063e5446598db4cbffdbf8f113, type: 3}
m_Name: TrashBag
m_EditorClassIdentifier: AppleHillsScripts::Minigames.FortFight.Data.ProjectileData
projectileName: TrashBag
prefab: {fileID: 0}
baseDamage: 15
cooldownTime: 6
icon: {fileID: 3452003437791708593, guid: 4c13556eeb918624c9dd3d7e4086242e, type: 3}
projectileId: trash-bag
prefab: {fileID: 4015519405310386481, guid: 177c683542fd63a4a9d7e7ecacea596f, type: 3}
cooldownTurns: 2
icon: {fileID: 8766740682603709380, guid: b0a0abcb5fec95649b581307eca6a444, type: 3}
displayName:
description:

View File

@@ -12,9 +12,9 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 973f02063e5446598db4cbffdbf8f113, type: 3}
m_Name: Vacumm
m_EditorClassIdentifier: AppleHillsScripts::Minigames.FortFight.Data.ProjectileData
projectileName: Vacumm
prefab: {fileID: 0}
baseDamage: 30
cooldownTime: 5
icon: {fileID: 8766740682603709380, guid: b0a0abcb5fec95649b581307eca6a444, type: 3}
projectileId: vacumm
prefab: {fileID: 4015519405310386481, guid: 4ffc718ecbe281041bc8354567f6e940, type: 3}
cooldownTurns: 2
icon: {fileID: 3452003437791708593, guid: 4c13556eeb918624c9dd3d7e4086242e, type: 3}
displayName:
description:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4c0e7378c10fea5438fb9161dcb55165
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8872d26b5cf881c48b49f19f62f057f0
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,174 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &4820392328973485589
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7720680877080653511}
- component: {fileID: 7443668876430426293}
- component: {fileID: 7264884308852669058}
- component: {fileID: 4427156681582364024}
- component: {fileID: 5656006159940088837}
m_Layer: 0
m_Name: Projecticle_Toaster
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &7720680877080653511
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4820392328973485589}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -14.73, y: -5.69, z: 0}
m_LocalScale: {x: 2.12, y: 2.12, z: 2.12}
m_ConstrainProportionsScale: 1
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!50 &7443668876430426293
Rigidbody2D:
serializedVersion: 5
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4820392328973485589}
m_BodyType: 0
m_Simulated: 1
m_UseFullKinematicContacts: 0
m_UseAutoMass: 0
m_Mass: 1
m_LinearDamping: 0
m_AngularDamping: 0.05
m_GravityScale: 1
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_Interpolate: 0
m_SleepingMode: 1
m_CollisionDetection: 0
m_Constraints: 0
--- !u!58 &7264884308852669058
CircleCollider2D:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4820392328973485589}
m_Enabled: 1
serializedVersion: 3
m_Density: 1
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_ForceSendLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ForceReceiveLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ContactCaptureLayers:
serializedVersion: 2
m_Bits: 4294967295
m_CallbackLayers:
serializedVersion: 2
m_Bits: 4294967295
m_IsTrigger: 0
m_UsedByEffector: 0
m_CompositeOperation: 0
m_CompositeOrder: 0
m_Offset: {x: 0, y: 0}
m_Radius: 0.5
--- !u!212 &4427156681582364024
SpriteRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4820392328973485589}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 0
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: 9dfc825aed78fcd4ba02077103263b40, 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: 0
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_Sprite: {fileID: 6674386295937086461, guid: 3bd1c178a78fcd144965cd1731dc309b, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
m_FlipY: 0
m_DrawMode: 0
m_Size: {x: 0.79, y: 0.62}
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!114 &5656006159940088837
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4820392328973485589}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6ecf658b5965496abda845de1a28e227, type: 3}
m_Name:
m_EditorClassIdentifier: AppleHillsScripts::Minigames.FortFight.Projectiles.ToasterProjectile
damage: 20
mass: 1
spriteRenderer: {fileID: 4427156681582364024}
impactEffectPrefab: {fileID: 8132850146457957189, guid: 8872d26b5cf881c48b49f19f62f057f0, type: 3}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a4b194a56edefa541b7c3bd7d70c8ba5
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,266 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &4342087378442690536
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6135800783835399381}
- component: {fileID: 8716398811558848928}
- component: {fileID: 4840876230127075284}
- component: {fileID: 5483057232976436363}
- component: {fileID: 924610570851376059}
m_Layer: 0
m_Name: Projectile_Fan
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &6135800783835399381
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4342087378442690536}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -14.73, y: -5.69, z: 0}
m_LocalScale: {x: 2.12, y: 2.12, z: 2.12}
m_ConstrainProportionsScale: 1
m_Children:
- {fileID: 1193836914283369334}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!50 &8716398811558848928
Rigidbody2D:
serializedVersion: 5
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4342087378442690536}
m_BodyType: 0
m_Simulated: 1
m_UseFullKinematicContacts: 0
m_UseAutoMass: 0
m_Mass: 1
m_LinearDamping: 0
m_AngularDamping: 0.05
m_GravityScale: 1
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_Interpolate: 0
m_SleepingMode: 1
m_CollisionDetection: 0
m_Constraints: 0
--- !u!58 &4840876230127075284
CircleCollider2D:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4342087378442690536}
m_Enabled: 1
serializedVersion: 3
m_Density: 1
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_ForceSendLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ForceReceiveLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ContactCaptureLayers:
serializedVersion: 2
m_Bits: 4294967295
m_CallbackLayers:
serializedVersion: 2
m_Bits: 4294967295
m_IsTrigger: 0
m_UsedByEffector: 0
m_CompositeOperation: 0
m_CompositeOrder: 0
m_Offset: {x: 0, y: 0}
m_Radius: 0.5
--- !u!212 &5483057232976436363
SpriteRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4342087378442690536}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 0
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: 9dfc825aed78fcd4ba02077103263b40, 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: 0
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_Sprite: {fileID: -765527507412255412, guid: f70246e6148769846aaea223ec0c2a55, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
m_FlipY: 0
m_DrawMode: 0
m_Size: {x: 0.79, y: 0.62}
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!114 &924610570851376059
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4342087378442690536}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e10ba9bd4bcd40da87ecb3efe5b78467, type: 3}
m_Name:
m_EditorClassIdentifier: AppleHillsScripts::Minigames.FortFight.Projectiles.CeilingFanProjectile
spriteRenderer: {fileID: 5483057232976436363}
impactEffectPrefab: {fileID: 8132850146457957189, guid: 8872d26b5cf881c48b49f19f62f057f0, type: 3}
dropSpeed: 20
dropDelay: 0.2
indicator: {fileID: 7427261821782179495}
--- !u!1 &7427261821782179495
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1193836914283369334}
- component: {fileID: 4082675289326321460}
m_Layer: 0
m_Name: ArrowDown
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1193836914283369334
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7427261821782179495}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: -1.09, z: 0}
m_LocalScale: {x: 0.4078, y: 0.4078, z: 0.4078}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 6135800783835399381}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &4082675289326321460
SpriteRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7427261821782179495}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 0
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: 9dfc825aed78fcd4ba02077103263b40, 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: 0
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_Sprite: {fileID: -4346244404228752641, guid: 7b5d036a9fa30484e911f4752e3a64c8, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
m_FlipY: 0
m_DrawMode: 0
m_Size: {x: 1.61, y: 3.08}
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ff8b62fb437256043aa6bd0b5441316b
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,173 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &4015519405310386481
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1820106441296487268}
- component: {fileID: 5065973586175064819}
- component: {fileID: 5096150048676858183}
- component: {fileID: 6069829950902409272}
- component: {fileID: 6431354022734802106}
m_Layer: 0
m_Name: Projectile_Trash
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1820106441296487268
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4015519405310386481}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -14.73, y: -5.69, z: 0}
m_LocalScale: {x: 2.12, y: 2.12, z: 2.12}
m_ConstrainProportionsScale: 1
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!50 &5065973586175064819
Rigidbody2D:
serializedVersion: 5
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4015519405310386481}
m_BodyType: 0
m_Simulated: 1
m_UseFullKinematicContacts: 0
m_UseAutoMass: 0
m_Mass: 1
m_LinearDamping: 0
m_AngularDamping: 0.05
m_GravityScale: 1
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_Interpolate: 0
m_SleepingMode: 1
m_CollisionDetection: 0
m_Constraints: 0
--- !u!58 &5096150048676858183
CircleCollider2D:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4015519405310386481}
m_Enabled: 1
serializedVersion: 3
m_Density: 1
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_ForceSendLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ForceReceiveLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ContactCaptureLayers:
serializedVersion: 2
m_Bits: 4294967295
m_CallbackLayers:
serializedVersion: 2
m_Bits: 4294967295
m_IsTrigger: 0
m_UsedByEffector: 0
m_CompositeOperation: 0
m_CompositeOrder: 0
m_Offset: {x: 0, y: 0}
m_Radius: 0.5
--- !u!212 &6069829950902409272
SpriteRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4015519405310386481}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 0
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: 9dfc825aed78fcd4ba02077103263b40, 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: 0
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_Sprite: {fileID: 8766740682603709380, guid: b0a0abcb5fec95649b581307eca6a444, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
m_FlipY: 0
m_DrawMode: 0
m_Size: {x: 0.79, y: 0.62}
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!114 &6431354022734802106
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4015519405310386481}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: b0996e59b91e48f8a542ab9294b11a74, type: 3}
m_Name:
m_EditorClassIdentifier: AppleHillsScripts::Minigames.FortFight.Projectiles.TrashBagProjectile
spriteRenderer: {fileID: 6069829950902409272}
impactEffectPrefab: {fileID: 0}
trashPiecePrefab: {fileID: 2420282101973676341, guid: da828432c72519c41af1f118c1d2d32a, type: 3}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 177c683542fd63a4a9d7e7ecacea596f
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,179 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &4015519405310386481
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1820106441296487268}
- component: {fileID: 5065973586175064819}
- component: {fileID: 5096150048676858183}
- component: {fileID: 6069829950902409272}
- component: {fileID: 6444071677531371543}
m_Layer: 0
m_Name: Projectile_Vacuum
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1820106441296487268
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4015519405310386481}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -14.73, y: -5.69, z: 0}
m_LocalScale: {x: 0.55, y: 0.55, z: 0.55}
m_ConstrainProportionsScale: 1
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!50 &5065973586175064819
Rigidbody2D:
serializedVersion: 5
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4015519405310386481}
m_BodyType: 0
m_Simulated: 1
m_UseFullKinematicContacts: 0
m_UseAutoMass: 0
m_Mass: 1
m_LinearDamping: 0
m_AngularDamping: 0.05
m_GravityScale: 1
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_Interpolate: 0
m_SleepingMode: 1
m_CollisionDetection: 0
m_Constraints: 0
--- !u!58 &5096150048676858183
CircleCollider2D:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4015519405310386481}
m_Enabled: 1
serializedVersion: 3
m_Density: 1
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_ForceSendLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ForceReceiveLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ContactCaptureLayers:
serializedVersion: 2
m_Bits: 4294967295
m_CallbackLayers:
serializedVersion: 2
m_Bits: 4294967295
m_IsTrigger: 0
m_UsedByEffector: 0
m_CompositeOperation: 0
m_CompositeOrder: 0
m_Offset: {x: 0, y: 0}
m_Radius: 1.47
--- !u!212 &6069829950902409272
SpriteRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4015519405310386481}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 0
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: 9dfc825aed78fcd4ba02077103263b40, 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: 0
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_Sprite: {fileID: 3452003437791708593, guid: 4c13556eeb918624c9dd3d7e4086242e, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
m_FlipY: 0
m_DrawMode: 0
m_Size: {x: 0.79, y: 0.62}
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!114 &6444071677531371543
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4015519405310386481}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bb85d181808c411b8bd1335aa7d35257, type: 3}
m_Name:
m_EditorClassIdentifier: AppleHillsScripts::Minigames.FortFight.Projectiles.VacuumProjectile
damage: 20
mass: 5
spriteRenderer: {fileID: 6069829950902409272}
impactEffectPrefab: {fileID: 8132850146457957189, guid: 8872d26b5cf881c48b49f19f62f057f0, type: 3}
slideSpeed: 10
slideDuration: 2
groundLayer:
serializedVersion: 2
m_Bits: 16385

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4ffc718ecbe281041bc8354567f6e940
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,170 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &2420282101973676341
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 241074338358760369}
- component: {fileID: 5429206645950534442}
- component: {fileID: 2897071451541676558}
- component: {fileID: 5662209331708671128}
- component: {fileID: 4567591556028898529}
m_Layer: 15
m_Name: TrashPiece
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &241074338358760369
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2420282101973676341}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -7.14251, y: -4.81934, z: 0}
m_LocalScale: {x: 0.41, y: 0.41, z: 0.41}
m_ConstrainProportionsScale: 1
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &5429206645950534442
SpriteRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2420282101973676341}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 0
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: 9dfc825aed78fcd4ba02077103263b40, 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: 0
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_Sprite: {fileID: 4056058344551517612, guid: 389219560116e714283bd8edd52f125f, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
m_FlipY: 0
m_DrawMode: 0
m_Size: {x: 2.05, y: 1.36}
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!50 &2897071451541676558
Rigidbody2D:
serializedVersion: 5
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2420282101973676341}
m_BodyType: 0
m_Simulated: 1
m_UseFullKinematicContacts: 0
m_UseAutoMass: 0
m_Mass: 1
m_LinearDamping: 0
m_AngularDamping: 0.05
m_GravityScale: 1
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_Interpolate: 0
m_SleepingMode: 1
m_CollisionDetection: 0
m_Constraints: 0
--- !u!58 &5662209331708671128
CircleCollider2D:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2420282101973676341}
m_Enabled: 1
serializedVersion: 3
m_Density: 1
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_ForceSendLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ForceReceiveLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ContactCaptureLayers:
serializedVersion: 2
m_Bits: 4294967295
m_CallbackLayers:
serializedVersion: 2
m_Bits: 4294967295
m_IsTrigger: 0
m_UsedByEffector: 0
m_CompositeOperation: 0
m_CompositeOrder: 0
m_Offset: {x: 0, y: 0}
m_Radius: 1.025
--- !u!114 &4567591556028898529
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2420282101973676341}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 516daf2ce7384aaa94fd5e0f7a3cf078, type: 3}
m_Name:
m_EditorClassIdentifier: AppleHillsScripts::Minigames.FortFight.Projectiles.TrashPiece

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: da828432c72519c41af1f118c1d2d32a
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3ea69ab311a50bf4fa62ee52b49ec12c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,617 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &2531541943888059757
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5547347229024929185}
- component: {fileID: 5401206366902621396}
m_Layer: 5
m_Name: AmmoButton
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5547347229024929185
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2531541943888059757}
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: 8404601832845600546}
- {fileID: 5209091951854750408}
- {fileID: 7509790308074872949}
- {fileID: 5308022048675937646}
- {fileID: 5860665860160112256}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 250}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &5401206366902621396
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2531541943888059757}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d18726bad651464fbc4e49f8c95c0c37, type: 3}
m_Name:
m_EditorClassIdentifier: AppleHillsScripts::Minigames.FortFight.UI.AmmoButton
iconImage: {fileID: 1292715515741235591}
cooldownBackgroundImage: {fileID: 6649587367082175822}
cooldownFillImage: {fileID: 4230072852917573804}
turnsRemainingText: {fileID: 9017755476257925041}
button: {fileID: 7156561986366282969}
selectedIndicator: {fileID: 4902599675820783363}
--- !u!1 &3901870519506060674
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7509790308074872949}
- component: {fileID: 2705585925341768566}
- component: {fileID: 6649587367082175822}
- component: {fileID: 8175154043102998346}
m_Layer: 5
m_Name: CooldownBackground
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &7509790308074872949
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3901870519506060674}
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: 5547347229024929185}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &2705585925341768566
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3901870519506060674}
m_CullTransparentMesh: 1
--- !u!114 &6649587367082175822
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3901870519506060674}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
m_Material: {fileID: 0}
m_Color: {r: 0, g: 0, b: 0, a: 0.39215687}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: -375496539, guid: 91cb3ae9a614f914997704a638d8b514, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 0
m_FillOrigin: 2
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &8175154043102998346
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3901870519506060674}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 86710e43de46f6f4bac7c8e50813a599, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.AspectRatioFitter
m_AspectMode: 3
m_AspectRatio: 1
--- !u!1 &4902599675820783363
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8404601832845600546}
- component: {fileID: 7897441411349867904}
- component: {fileID: 7539021912128058554}
- component: {fileID: 8444687236839044743}
m_Layer: 5
m_Name: Glow
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &8404601832845600546
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4902599675820783363}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1.73, y: 1.73, z: 1.73}
m_ConstrainProportionsScale: 1
m_Children: []
m_Father: {fileID: 5547347229024929185}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &7897441411349867904
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4902599675820783363}
m_CullTransparentMesh: 1
--- !u!114 &7539021912128058554
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4902599675820783363}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: -8836962644236845764, guid: c5cc7367a37a7944abb3876352b0e0ff, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &8444687236839044743
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4902599675820783363}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 86710e43de46f6f4bac7c8e50813a599, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.AspectRatioFitter
m_AspectMode: 3
m_AspectRatio: 1
--- !u!1 &5631747237242774678
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5860665860160112256}
- component: {fileID: 553452135861179838}
- component: {fileID: 9017755476257925041}
- component: {fileID: 3204967838938883920}
m_Layer: 5
m_Name: CooldownCount
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5860665860160112256
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5631747237242774678}
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: 5547347229024929185}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &553452135861179838
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5631747237242774678}
m_CullTransparentMesh: 1
--- !u!114 &9017755476257925041
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5631747237242774678}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: 5
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 4aca0db6ec111b5418bdc747168f9474, type: 2}
m_sharedMaterial: {fileID: -1441574381962284772, guid: 4aca0db6ec111b5418bdc747168f9474, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4294967295
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 100
m_fontSizeBase: 100
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 1
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!114 &3204967838938883920
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5631747237242774678}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 86710e43de46f6f4bac7c8e50813a599, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.AspectRatioFitter
m_AspectMode: 3
m_AspectRatio: 1
--- !u!1 &5744229847348998137
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5308022048675937646}
- component: {fileID: 7806188825550789684}
- component: {fileID: 4230072852917573804}
- component: {fileID: 5298362292334641366}
m_Layer: 5
m_Name: CooldownFill
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5308022048675937646
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5744229847348998137}
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: 5547347229024929185}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &7806188825550789684
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5744229847348998137}
m_CullTransparentMesh: 1
--- !u!114 &4230072852917573804
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5744229847348998137}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
m_Material: {fileID: 0}
m_Color: {r: 0, g: 0, b: 0, a: 0.39215687}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: -375496539, guid: 91cb3ae9a614f914997704a638d8b514, type: 3}
m_Type: 3
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 0
m_FillOrigin: 2
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &5298362292334641366
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5744229847348998137}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 86710e43de46f6f4bac7c8e50813a599, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.AspectRatioFitter
m_AspectMode: 3
m_AspectRatio: 1
--- !u!1 &6375846952096027156
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5209091951854750408}
- component: {fileID: 333739704463047820}
- component: {fileID: 2948614565164427980}
- component: {fileID: 1292715515741235591}
- component: {fileID: 7156561986366282969}
m_Layer: 5
m_Name: Visual
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5209091951854750408
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6375846952096027156}
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: 5547347229024929185}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &333739704463047820
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6375846952096027156}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 86710e43de46f6f4bac7c8e50813a599, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.AspectRatioFitter
m_AspectMode: 3
m_AspectRatio: 1
--- !u!222 &2948614565164427980
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6375846952096027156}
m_CullTransparentMesh: 1
--- !u!114 &1292715515741235591
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6375846952096027156}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &7156561986366282969
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6375846952096027156}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Button
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 1292715515741235591}
m_OnClick:
m_PersistentCalls:
m_Calls: []

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 009a94a95f1662441bf9e52311bfbd70
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,863 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &6730781524121181368
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2148236734266076239}
- component: {fileID: 1621117865532798199}
- component: {fileID: 1107058815159810064}
m_Layer: 5
m_Name: Player_AmmoPanel
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &2148236734266076239
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6730781524121181368}
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: 4741534808117833349}
- {fileID: 807375318505295058}
- {fileID: 4535308774383573099}
- {fileID: 3766327015481308810}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0}
m_AnchorMax: {x: 1, y: 0}
m_AnchoredPosition: {x: -50, y: 50}
m_SizeDelta: {x: 700, y: 150}
m_Pivot: {x: 1, y: 0}
--- !u!114 &1621117865532798199
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6730781524121181368}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.HorizontalLayoutGroup
m_Padding:
m_Left: 0
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 4
m_Spacing: 50
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 1
m_ChildControlWidth: 1
m_ChildControlHeight: 0
m_ChildScaleWidth: 0
m_ChildScaleHeight: 0
m_ReverseArrangement: 0
--- !u!114 &1107058815159810064
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6730781524121181368}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1963617e4d104c199c3a66d671b8d8a2, type: 3}
m_Name:
m_EditorClassIdentifier: AppleHillsScripts::Minigames.FortFight.UI.AmmunitionPanel
playerIndex: 0
ammunitionManager: {fileID: 0}
slingshotController: {fileID: 0}
turnManager: {fileID: 0}
ammoButtons:
- {fileID: 5171683449295814640}
- {fileID: 953793249169202599}
- {fileID: 4105159935502846238}
- {fileID: 3624408192042149887}
panelRoot: {fileID: 6730781524121181368}
--- !u!1001 &950666481065274148
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 2148236734266076239}
m_Modifications:
- target: {fileID: 2531541943888059757, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_Name
value: AmmoButton
objectReference: {fileID: 0}
- target: {fileID: 5209091951854750408, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5209091951854750408, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5209091951854750408, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5209091951854750408, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5308022048675937646, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5308022048675937646, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5308022048675937646, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5308022048675937646, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_Pivot.x
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_Pivot.y
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMin.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMin.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 250
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5860665860160112256, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5860665860160112256, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5860665860160112256, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5860665860160112256, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7509790308074872949, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7509790308074872949, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7509790308074872949, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7509790308074872949, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8404601832845600546, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8404601832845600546, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8404601832845600546, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8404601832845600546, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
--- !u!224 &4741534808117833349 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
m_PrefabInstance: {fileID: 950666481065274148}
m_PrefabAsset: {fileID: 0}
--- !u!114 &5171683449295814640 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 5401206366902621396, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
m_PrefabInstance: {fileID: 950666481065274148}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d18726bad651464fbc4e49f8c95c0c37, type: 3}
m_Name:
m_EditorClassIdentifier: AppleHillsScripts::Minigames.FortFight.UI.AmmoButton
--- !u!1001 &5172522139070908787
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 2148236734266076239}
m_Modifications:
- target: {fileID: 2531541943888059757, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_Name
value: AmmoButton2
objectReference: {fileID: 0}
- target: {fileID: 5209091951854750408, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5209091951854750408, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5209091951854750408, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5209091951854750408, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5308022048675937646, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5308022048675937646, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5308022048675937646, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5308022048675937646, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_Pivot.x
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_Pivot.y
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMin.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMin.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 250
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalRotation.x
value: -0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalRotation.y
value: -0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalRotation.z
value: -0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5860665860160112256, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5860665860160112256, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5860665860160112256, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5860665860160112256, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7509790308074872949, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7509790308074872949, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7509790308074872949, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7509790308074872949, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8404601832845600546, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8404601832845600546, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8404601832845600546, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8404601832845600546, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
--- !u!224 &807375318505295058 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
m_PrefabInstance: {fileID: 5172522139070908787}
m_PrefabAsset: {fileID: 0}
--- !u!114 &953793249169202599 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 5401206366902621396, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
m_PrefabInstance: {fileID: 5172522139070908787}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d18726bad651464fbc4e49f8c95c0c37, type: 3}
m_Name:
m_EditorClassIdentifier: AppleHillsScripts::Minigames.FortFight.UI.AmmoButton
--- !u!1001 &8218090363695341002
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 2148236734266076239}
m_Modifications:
- target: {fileID: 2531541943888059757, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_Name
value: AmmoButton3
objectReference: {fileID: 0}
- target: {fileID: 5209091951854750408, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5209091951854750408, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5209091951854750408, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5209091951854750408, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5308022048675937646, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5308022048675937646, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5308022048675937646, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5308022048675937646, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_Pivot.x
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_Pivot.y
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMin.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMin.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 250
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalRotation.x
value: -0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalRotation.y
value: -0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalRotation.z
value: -0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5860665860160112256, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5860665860160112256, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5860665860160112256, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5860665860160112256, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7509790308074872949, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7509790308074872949, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7509790308074872949, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7509790308074872949, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8404601832845600546, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8404601832845600546, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8404601832845600546, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8404601832845600546, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
--- !u!114 &4105159935502846238 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 5401206366902621396, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
m_PrefabInstance: {fileID: 8218090363695341002}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d18726bad651464fbc4e49f8c95c0c37, type: 3}
m_Name:
m_EditorClassIdentifier: AppleHillsScripts::Minigames.FortFight.UI.AmmoButton
--- !u!224 &4535308774383573099 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
m_PrefabInstance: {fileID: 8218090363695341002}
m_PrefabAsset: {fileID: 0}
--- !u!1001 &8698857294231712555
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 2148236734266076239}
m_Modifications:
- target: {fileID: 2531541943888059757, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_Name
value: AmmoButton4
objectReference: {fileID: 0}
- target: {fileID: 5209091951854750408, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5209091951854750408, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5209091951854750408, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5209091951854750408, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5308022048675937646, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5308022048675937646, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5308022048675937646, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5308022048675937646, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_Pivot.x
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_Pivot.y
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMin.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMin.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 250
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalRotation.x
value: -0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalRotation.y
value: -0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalRotation.z
value: -0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5860665860160112256, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5860665860160112256, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5860665860160112256, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5860665860160112256, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7509790308074872949, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7509790308074872949, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7509790308074872949, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7509790308074872949, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8404601832845600546, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8404601832845600546, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8404601832845600546, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8404601832845600546, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
--- !u!114 &3624408192042149887 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 5401206366902621396, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
m_PrefabInstance: {fileID: 8698857294231712555}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d18726bad651464fbc4e49f8c95c0c37, type: 3}
m_Name:
m_EditorClassIdentifier: AppleHillsScripts::Minigames.FortFight.UI.AmmoButton
--- !u!224 &3766327015481308810 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 5547347229024929185, guid: 009a94a95f1662441bf9e52311bfbd70, type: 3}
m_PrefabInstance: {fileID: 8698857294231712555}
m_PrefabAsset: {fileID: 0}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2aa2fb2d3da8f3b4e9d1058cea4e418d
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -232,6 +232,42 @@ namespace AppleHills.Core.Settings
float FortDefeatThreshold { get; }
float PhysicsGravityScale { get; }
// Turn & Projectile timing
float ProjectileSettleDelay { get; } // Time to wait after projectile stops moving before ending turn
float TurnTransitionDelay { get; } // Additional delay during turn transition (wide view camera)
// Physics Settings
float BlockGravityScale { get; } // Gravity scale for fort blocks
float ProjectileGravityScale { get; } // Gravity scale for projectiles
// Physics Layers
int FortBlockLayer { get; } // Layer index for fort blocks
int ProjectileLayer { get; } // Layer index for projectiles
// Slingshot Settings
float BaseLaunchForce { get; } // Base launch force multiplier
float MinForceMultiplier { get; } // Minimum force required to launch (0-1)
float MaxForceMultiplier { get; } // Maximum force cap (0-2, usually 1)
float TrajectoryLockDuration { get; } // How long to show trajectory after launch
// Projectile Abilities
float VacuumSlideSpeed { get; } // Constant velocity for vacuum sliding (m/s)
int VacuumDestroyBlockCount { get; } // Blocks to destroy while sliding
float VacuumBlockDamage { get; } // Damage dealt to blocks while sliding
int TrashBagPieceCount { get; } // Pieces spawned on trash bag impact
float TrashBagPieceForce { get; } // Force per trash piece
float TrashBagSpreadAngle { get; } // Trash bag spread cone angle
float TrashPieceDamage { get; } // Damage per trash piece on collision
float TrashPieceLifetime { get; } // How long trash pieces persist (seconds)
float CeilingFanActivationDelay { get; } // Delay before tap-to-drop becomes available
float CeilingFanDropDelay { get; } // Pause before ceiling fan starts dropping
float CeilingFanDropSpeed { get; } // Downward velocity when dropping (m/s)
// Projectile Configurations
System.Collections.Generic.IReadOnlyList<Minigames.FortFight.Data.ProjectileConfig> ProjectileConfigs { get; }
Minigames.FortFight.Data.ProjectileConfig GetProjectileConfig(Minigames.FortFight.Data.ProjectileType type);
Minigames.FortFight.Data.ProjectileConfig GetProjectileConfigById(string projectileId);
// Visual settings
Color DamageColorTint { get; }

View File

@@ -73,13 +73,15 @@ namespace Minigames.FortFight.AI
// STUBBED: Perform AI action
Logging.Debug("[FortFightAIController] AI takes action! (STUBBED - no actual projectile fired yet)");
// End AI turn
isThinking = false;
// TODO Phase 4: AI should trigger its slingshot to fire projectile here
// Turn will automatically advance when AI's projectile settles (via ProjectileTurnAction)
// Do NOT manually call EndTurn() - it's now private and automatic
if (turnManager != null)
{
turnManager.EndTurn();
}
// NOTE: For now, AI turn will hang until Phase 4 AI projectile system is implemented
// To test without AI, use TwoPlayer mode
isThinking = false;
Logging.Warning("[FortFightAIController] AI turn stubbed - Phase 4 needed for AI projectile firing");
}
#endregion

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using AppleHills.Core.Settings;
using Core;
using Core.Lifecycle;
using Minigames.FortFight.Data;
@@ -13,47 +14,75 @@ namespace Minigames.FortFight.Core
/// </summary>
public class AmmunitionManager : ManagedBehaviour
{
#region Constants
private const int MaxPlayers = 2; // Support 2 players (indices 0 and 1)
#endregion
#region Inspector Properties
[Header("Available Ammunition")]
[Tooltip("All projectile types available in this game")]
[SerializeField] private List<ProjectileData> availableAmmo = new List<ProjectileData>();
[Header("Starting Ammo")]
[Tooltip("Default selected ammo at game start")]
[SerializeField] private ProjectileData defaultAmmo;
[Header("Configuration")]
[Tooltip("Default projectile type selected at game start")]
[SerializeField] private ProjectileType defaultProjectileType = ProjectileType.Toaster;
[Header("Debug")]
[SerializeField] private bool showDebugLogs = true;
#endregion
#region Settings
private IFortFightSettings cachedSettings;
private IFortFightSettings CachedSettings
{
get
{
if (cachedSettings == null)
{
cachedSettings = GameManager.GetSettingsObject<IFortFightSettings>();
}
return cachedSettings;
}
}
private List<ProjectileConfig> AvailableConfigs
{
get
{
var settings = CachedSettings;
return settings != null ? new List<ProjectileConfig>(settings.ProjectileConfigs) : new List<ProjectileConfig>();
}
}
#endregion
#region Events
/// <summary>
/// Fired when ammo selection changes. Parameters: (ProjectileData selectedAmmo)
/// Fired when ammo selection changes. Parameters: (ProjectileType selectedType, int playerIndex)
/// </summary>
public event Action<ProjectileData> OnAmmoSelected;
public event Action<ProjectileType, int> OnAmmoSelected;
/// <summary>
/// Fired when ammo is used and enters cooldown. Parameters: (ProjectileData ammo, float cooldownTime)
/// Fired when ammo is used and enters cooldown. Parameters: (ProjectileType type, int cooldownTurns)
/// </summary>
public event Action<ProjectileData, float> OnAmmoCooldownStarted;
public event Action<ProjectileType, int> OnAmmoCooldownStarted;
/// <summary>
/// Fired when ammo cooldown completes. Parameters: (ProjectileData ammo)
/// Fired when ammo cooldown completes. Parameters: (ProjectileType type)
/// </summary>
public event Action<ProjectileData> OnAmmoCooldownCompleted;
public event Action<ProjectileType> OnAmmoCooldownCompleted;
#endregion
#region State
private Dictionary<ProjectileData, float> cooldowns = new Dictionary<ProjectileData, float>();
private ProjectileData selectedAmmo;
// Per-player turn-based cooldowns: projectileType -> playerIndex -> turnsRemaining
private Dictionary<ProjectileType, Dictionary<int, int>> cooldowns = new Dictionary<ProjectileType, Dictionary<int, int>>();
public ProjectileData SelectedAmmo => selectedAmmo;
public IReadOnlyList<ProjectileData> AvailableAmmo => availableAmmo;
// Per-player selected ammo: playerIndex -> ProjectileType
private Dictionary<int, ProjectileType> selectedAmmoByPlayer = new Dictionary<int, ProjectileType>();
#endregion
@@ -63,112 +92,148 @@ namespace Minigames.FortFight.Core
{
base.OnManagedStart();
// Initialize cooldowns to 0
foreach (var ammo in availableAmmo)
// Initialize per-player turn-based cooldowns to 0 for all players
var configs = AvailableConfigs;
foreach (var config in configs)
{
cooldowns[ammo] = 0f;
cooldowns[config.projectileType] = new Dictionary<int, int>();
for (int playerIndex = 0; playerIndex < MaxPlayers; playerIndex++)
{
cooldowns[config.projectileType][playerIndex] = 0;
}
}
// Select default ammo
if (defaultAmmo != null)
// Select default ammo for all players
for (int playerIndex = 0; playerIndex < MaxPlayers; playerIndex++)
{
SelectAmmo(defaultAmmo);
}
else if (availableAmmo.Count > 0)
{
SelectAmmo(availableAmmo[0]);
SelectAmmo(defaultProjectileType, playerIndex);
}
}
private void Update()
/// <summary>
/// Called when a player's turn ends - decrements that player's cooldowns by 1 turn.
/// Should be called by TurnManager on OnTurnEnded event.
/// </summary>
public void DecrementCooldowns(int playerIndex)
{
// Update cooldown timers
List<ProjectileData> completedCooldowns = new List<ProjectileData>();
List<ProjectileType> completedCooldowns = new List<ProjectileType>();
List<ProjectileType> projectileTypes = new List<ProjectileType>(cooldowns.Keys);
foreach (var kvp in cooldowns)
foreach (var type in projectileTypes)
{
if (kvp.Value > 0f)
if (cooldowns[type].ContainsKey(playerIndex) && cooldowns[type][playerIndex] > 0)
{
cooldowns[kvp.Key] = Mathf.Max(0f, kvp.Value - Time.deltaTime);
cooldowns[type][playerIndex]--;
// Check if cooldown just completed
if (cooldowns[kvp.Key] == 0f)
if (cooldowns[type][playerIndex] == 0)
{
completedCooldowns.Add(kvp.Key);
completedCooldowns.Add(type);
}
}
}
// Fire events for completed cooldowns
foreach (var ammo in completedCooldowns)
var settings = CachedSettings;
foreach (var type in completedCooldowns)
{
string ammoName = GetAmmoName(ammo);
if (showDebugLogs) Logging.Debug($"[AmmunitionManager] {ammoName} cooldown completed");
OnAmmoCooldownCompleted?.Invoke(ammo);
var config = settings?.GetProjectileConfig(type);
if (config != null)
{
if (showDebugLogs) Logging.Debug($"[AmmunitionManager] Player {playerIndex}: {config.displayName} cooldown completed");
OnAmmoCooldownCompleted?.Invoke(type);
}
}
}
#endregion
#region Ammo Selection
/// <summary>
/// Select ammunition type (if available - not on cooldown)
/// Select ammunition type for a specific player (if available - not on cooldown)
/// </summary>
public bool SelectAmmo(ProjectileData ammo)
public bool SelectAmmo(ProjectileType type, int playerIndex)
{
if (ammo == null)
var settings = CachedSettings;
var config = settings?.GetProjectileConfig(type);
if (config == null)
{
Logging.Warning("[AmmunitionManager] Attempted to select null ammo");
Logging.Warning($"[AmmunitionManager] Projectile type {type} not found in settings");
return false;
}
if (!availableAmmo.Contains(ammo))
if (!IsAmmoAvailable(type, playerIndex))
{
string ammoName = GetAmmoName(ammo);
Logging.Warning($"[AmmunitionManager] {ammoName} not in available ammo list");
if (showDebugLogs) Logging.Debug($"[AmmunitionManager] Player {playerIndex}: {config.displayName} is on cooldown");
return false;
}
if (!IsAmmoAvailable(ammo))
{
string ammoName = GetAmmoName(ammo);
if (showDebugLogs) Logging.Debug($"[AmmunitionManager] {ammoName} is on cooldown");
return false;
}
selectedAmmoByPlayer[playerIndex] = type;
if (showDebugLogs) Logging.Debug($"[AmmunitionManager] Player {playerIndex} selected: {config.displayName}");
selectedAmmo = ammo;
string selectedName = GetAmmoName(ammo);
if (showDebugLogs) Logging.Debug($"[AmmunitionManager] Selected ammo: {selectedName}");
OnAmmoSelected?.Invoke(ammo);
OnAmmoSelected?.Invoke(type, playerIndex);
return true;
}
/// <summary>
/// Check if ammo is available (not on cooldown)
/// Get currently selected projectile type for a specific player
/// </summary>
public bool IsAmmoAvailable(ProjectileData ammo)
public ProjectileType GetSelectedAmmoType(int playerIndex)
{
if (!cooldowns.ContainsKey(ammo))
if (selectedAmmoByPlayer.ContainsKey(playerIndex))
{
return selectedAmmoByPlayer[playerIndex];
}
return defaultProjectileType;
}
/// <summary>
/// Get currently selected projectile config for a specific player
/// </summary>
public ProjectileConfig GetSelectedAmmoConfig(int playerIndex)
{
var type = GetSelectedAmmoType(playerIndex);
return CachedSettings?.GetProjectileConfig(type);
}
/// <summary>
/// Check if ammo is available for a specific player (not on cooldown)
/// </summary>
public bool IsAmmoAvailable(ProjectileType type, int playerIndex)
{
if (!cooldowns.ContainsKey(type))
{
return true;
}
return cooldowns[ammo] <= 0f;
if (!cooldowns[type].ContainsKey(playerIndex))
{
return true;
}
return cooldowns[type][playerIndex] <= 0;
}
/// <summary>
/// Get remaining cooldown time for ammo
/// Get remaining cooldown turns for ammo for a specific player
/// </summary>
public float GetCooldownRemaining(ProjectileData ammo)
public int GetCooldownRemaining(ProjectileType type, int playerIndex)
{
if (!cooldowns.ContainsKey(ammo))
if (!cooldowns.ContainsKey(type))
{
return 0f;
return 0;
}
return cooldowns[ammo];
if (!cooldowns[type].ContainsKey(playerIndex))
{
return 0;
}
return cooldowns[type][playerIndex];
}
#endregion
@@ -176,38 +241,36 @@ namespace Minigames.FortFight.Core
#region Ammo Usage
/// <summary>
/// Use current ammo (trigger cooldown)
/// Use specific ammo for a specific player (trigger turn-based cooldown)
/// </summary>
public void UseAmmo()
public void UseAmmo(ProjectileType type, int playerIndex)
{
if (selectedAmmo == null)
var settings = CachedSettings;
var config = settings?.GetProjectileConfig(type);
if (config == null)
{
Logging.Warning("[AmmunitionManager] No ammo selected to use");
Logging.Warning($"[AmmunitionManager] Projectile type {type} not found in settings");
return;
}
UseAmmo(selectedAmmo);
}
/// <summary>
/// Use specific ammo (trigger cooldown)
/// </summary>
public void UseAmmo(ProjectileData ammo)
{
if (ammo == null) return;
if (!cooldowns.ContainsKey(ammo))
// Initialize cooldowns dict if needed
if (!cooldowns.ContainsKey(type))
{
cooldowns[ammo] = 0f;
cooldowns[type] = new Dictionary<int, int>();
for (int i = 0; i < MaxPlayers; i++)
{
cooldowns[type][i] = 0;
}
}
// Start cooldown
cooldowns[ammo] = ammo.cooldownTime;
// Start turn-based cooldown for this player
cooldowns[type][playerIndex] = config.cooldownTurns;
string ammoName = GetAmmoName(ammo);
if (showDebugLogs) Logging.Debug($"[AmmunitionManager] {ammoName} used - cooldown: {ammo.cooldownTime}s");
if (showDebugLogs) Logging.Debug($"[AmmunitionManager] Player {playerIndex}: {config.displayName} used - cooldown: {config.cooldownTurns} turns");
OnAmmoCooldownStarted?.Invoke(ammo, ammo.cooldownTime);
OnAmmoCooldownStarted?.Invoke(type, config.cooldownTurns);
}
#endregion
@@ -215,67 +278,36 @@ namespace Minigames.FortFight.Core
#region Public API
/// <summary>
/// Add ammo to available list (for unlocks/powerups)
/// </summary>
public void AddAmmo(ProjectileData ammo)
{
if (!availableAmmo.Contains(ammo))
{
availableAmmo.Add(ammo);
cooldowns[ammo] = 0f;
string ammoName = GetAmmoName(ammo);
if (showDebugLogs) Logging.Debug($"[AmmunitionManager] Added ammo: {ammoName}");
}
}
/// <summary>
/// Remove ammo from available list
/// </summary>
public void RemoveAmmo(ProjectileData ammo)
{
if (availableAmmo.Contains(ammo))
{
availableAmmo.Remove(ammo);
cooldowns.Remove(ammo);
// If this was selected, select first available
if (selectedAmmo == ammo && availableAmmo.Count > 0)
{
SelectAmmo(availableAmmo[0]);
}
string ammoName = GetAmmoName(ammo);
if (showDebugLogs) Logging.Debug($"[AmmunitionManager] Removed ammo: {ammoName}");
}
}
/// <summary>
/// Reset all cooldowns
/// Reset all cooldowns for all players
/// </summary>
public void ResetAllCooldowns()
{
foreach (var ammo in cooldowns.Keys)
foreach (var projectileType in cooldowns.Keys)
{
cooldowns[ammo] = 0f;
for (int playerIndex = 0; playerIndex < MaxPlayers; playerIndex++)
{
if (cooldowns[projectileType].ContainsKey(playerIndex))
{
cooldowns[projectileType][playerIndex] = 0;
}
}
}
if (showDebugLogs) Logging.Debug("[AmmunitionManager] All cooldowns reset");
if (showDebugLogs) Logging.Debug("[AmmunitionManager] All cooldowns reset for all players");
}
#endregion
#region Helpers
/// <summary>
/// Get display name for ammo (uses displayName or prefab name as fallback)
/// Get all available projectile types from settings
/// </summary>
private string GetAmmoName(ProjectileData ammo)
public List<ProjectileType> GetAvailableProjectileTypes()
{
if (ammo == null) return "Unknown";
if (!string.IsNullOrEmpty(ammo.displayName)) return ammo.displayName;
if (ammo.prefab != null) return ammo.prefab.name;
return "Unknown Ammo";
var types = new List<ProjectileType>();
var configs = AvailableConfigs;
foreach (var config in configs)
{
types.Add(config.projectileType);
}
return types;
}
#endregion

View File

@@ -25,14 +25,13 @@ namespace Minigames.FortFight.Core
[Tooltip("Player Two's dedicated camera (position this in the scene for Player 2's view)")]
[SerializeField] private CinemachineCamera playerTwoCamera;
[Tooltip("Camera that follows projectiles in flight (should have CinemachineFollow component)")]
[SerializeField] private CinemachineCamera projectileCamera;
[Header("References")]
[Tooltip("Turn manager to subscribe to turn events")]
[SerializeField] private TurnManager turnManager;
[Header("Settings")]
[Tooltip("Use wide view between turns (optional transition)")]
[SerializeField] private bool useWideViewTransitions;
#endregion
#region Public Properties
@@ -40,6 +39,7 @@ namespace Minigames.FortFight.Core
public CinemachineCamera WideViewCamera => wideViewCamera;
public CinemachineCamera PlayerOneCamera => playerOneCamera;
public CinemachineCamera PlayerTwoCamera => playerTwoCamera;
public CinemachineCamera ProjectileCamera => projectileCamera;
#endregion
@@ -65,6 +65,11 @@ namespace Minigames.FortFight.Core
Logging.Error("[CameraController] Player Two camera not assigned!");
}
if (projectileCamera == null)
{
Logging.Warning("[CameraController] Projectile camera not assigned - projectiles won't be followed!");
}
if (turnManager == null)
{
Logging.Error("[CameraController] Turn manager not assigned!");
@@ -109,7 +114,14 @@ namespace Minigames.FortFight.Core
/// </summary>
private void HandleTurnStarted(PlayerData player, TurnState turnState)
{
Logging.Debug($"[CameraController] Turn started for {player.PlayerName} (Index: {player.PlayerIndex})");
Logging.Debug($"[CameraController] Turn started for {player.PlayerName} (Index: {player.PlayerIndex}, State: {turnState})");
// If transitioning, show wide view
if (turnState == TurnState.TransitioningTurn)
{
ActivateCamera(wideViewCamera);
return;
}
// Activate the appropriate player camera based on player index
if (player.PlayerIndex == 0)
@@ -130,17 +142,12 @@ namespace Minigames.FortFight.Core
}
/// <summary>
/// Called when a player's turn ends - optionally switch to wide view for transition
/// Called when a player's turn ends - camera switches handled by turn state changes
/// </summary>
private void HandleTurnEnded(PlayerData player)
{
Logging.Debug($"[CameraController] Turn ended for {player.PlayerName}");
// Optional: briefly show wide view between turns
if (useWideViewTransitions)
{
ActivateCamera(wideViewCamera);
}
// Camera switching happens via OnTurnStarted when state changes to TransitioningTurn
}
/// <summary>
@@ -154,6 +161,7 @@ namespace Minigames.FortFight.Core
if (wideViewCamera != null) wideViewCamera.Priority.Value = 10;
if (playerOneCamera != null) playerOneCamera.Priority.Value = 10;
if (playerTwoCamera != null) playerTwoCamera.Priority.Value = 10;
if (projectileCamera != null) projectileCamera.Priority.Value = 10;
// Set target camera to high priority
camera.Priority.Value = 20;
@@ -163,6 +171,62 @@ namespace Minigames.FortFight.Core
#endregion
#region Projectile Tracking
/// <summary>
/// Start following a projectile with the projectile camera.
/// Called when a projectile is launched.
/// </summary>
public void StartFollowingProjectile(Transform projectileTransform)
{
if (projectileCamera == null)
{
Logging.Warning("[CameraController] Cannot follow projectile - projectile camera not assigned!");
return;
}
if (projectileTransform == null)
{
Logging.Warning("[CameraController] Cannot follow null projectile transform!");
return;
}
// Verify CinemachineFollow component exists (optional check)
var followComponent = projectileCamera.GetComponent<CinemachineFollow>();
if (followComponent == null)
{
Logging.Error("[CameraController] Projectile camera missing CinemachineFollow component!");
return;
}
// Set the follow target on the CinemachineCamera's Target property
projectileCamera.Target.TrackingTarget = projectileTransform;
// Activate the projectile camera
ActivateCamera(projectileCamera);
Logging.Debug($"[CameraController] Now following projectile: {projectileTransform.gameObject.name}");
}
/// <summary>
/// Stop following the projectile and return to wide view.
/// Called when projectile has settled.
/// </summary>
public void StopFollowingProjectile()
{
if (projectileCamera == null) return;
// Clear the follow target on the CinemachineCamera's Target property
projectileCamera.Target.TrackingTarget = null;
// Return to wide view
ActivateCamera(wideViewCamera);
Logging.Debug("[CameraController] Stopped following projectile, returned to wide view");
}
#endregion
#region Public API
/// <summary>

View File

@@ -46,8 +46,83 @@ namespace Minigames.FortFight.Core
[Tooltip("HP percentage threshold for fort defeat (0.3 = 30%)")]
[SerializeField] private float fortDefeatThreshold = 0.3f;
[Tooltip("Global gravity scale for all blocks")]
[SerializeField] private float physicsGravityScale = 1f;
[Header("Physics Settings")]
[Tooltip("Gravity scale for fort blocks (1.0 = normal Unity gravity)")]
[SerializeField] private float blockGravityScale = 1f;
[Tooltip("Gravity scale for projectiles (1.0 = normal Unity gravity)")]
[SerializeField] private float projectileGravityScale = 1f;
[Header("Turn & Projectile Timing")]
[Tooltip("Time to wait after projectile stops moving before ending turn")]
[SerializeField] private float projectileSettleDelay = 2.5f;
[Tooltip("Additional delay during turn transition with wide view camera")]
[SerializeField] private float turnTransitionDelay = 1.5f;
[Header("BASE Projectile Configurations")]
[Tooltip("All available projectile types and their base configurations (damage, mass, cooldown)")]
[SerializeField] private List<ProjectileConfig> projectileConfigs = new List<ProjectileConfig>();
[Header("Projectile Ability - Vacuum Cleaner")]
[Tooltip("Constant sliding velocity in meters per second")]
[SerializeField] private float vacuumSlideSpeed = 10f;
[Tooltip("Number of blocks to destroy while sliding")]
[SerializeField] private int vacuumDestroyBlockCount = 3;
[Tooltip("Damage dealt to blocks while sliding (high value for instant destruction)")]
[SerializeField] private float vacuumBlockDamage = 999f;
[Header("Projectile Ability - Trash Bag")]
[Tooltip("Number of trash pieces to spawn on impact")]
[SerializeField] private int trashBagPieceCount = 8;
[Tooltip("Force applied to each trash piece")]
[SerializeField] private float trashBagPieceForce = 10f;
[Tooltip("Spread cone angle for trash pieces (degrees)")]
[SerializeField] private float trashBagSpreadAngle = 60f;
[Tooltip("Damage each trash piece deals on collision with blocks")]
[SerializeField] private float trashPieceDamage = 5f;
[Tooltip("How long trash pieces persist before auto-cleanup (seconds)")]
[SerializeField] private float trashPieceLifetime = 5f;
[Header("Projectile Ability - Ceiling Fan")]
[Tooltip("Delay before tap-to-drop becomes available (seconds)")]
[SerializeField] private float ceilingFanActivationDelay = 0.5f;
[Tooltip("Brief pause before ceiling fan starts dropping (seconds)")]
[SerializeField] private float ceilingFanDropDelay = 0.2f;
[Tooltip("Downward velocity when dropping (m/s)")]
[SerializeField] private float ceilingFanDropSpeed = 20f;
[Header("Slingshot Settings")]
[Tooltip("Base launch force multiplier - higher values = projectiles fly farther")]
[SerializeField] private float baseLaunchForce = 20f;
[Tooltip("Minimum force multiplier (0-1, e.g. 0.1 = 10% of max force required to launch)")]
[Range(0f, 1f)]
[SerializeField] private float minForceMultiplier = 0.1f;
[Tooltip("Maximum force multiplier (0-1, e.g. 1.0 = 100% at max drag distance)")]
[Range(0f, 2f)]
[SerializeField] private float maxForceMultiplier = 1f;
[Tooltip("How long to keep trajectory visible after launching (seconds)")]
[SerializeField] private float trajectoryLockDuration = 2f;
[Header("Physics Layers")]
[Tooltip("Layer for fort blocks - projectiles will collide with these (Default: Layer 8 'FortBlock')")]
[AppleHills.Core.Settings.Layer]
[SerializeField] private int fortBlockLayer = 8;
[Tooltip("Layer for projectiles - for filtering projectile-to-projectile collisions (Default: Layer 9 'Projectile')")]
[AppleHills.Core.Settings.Layer]
[SerializeField] private int projectileLayer = 9;
[Header("Visual Settings")]
[Tooltip("Color tint applied to damaged blocks")]
@@ -63,10 +138,67 @@ namespace Minigames.FortFight.Core
public float WeakPointExplosionForce => weakPointExplosionForce;
public float FortDefeatThreshold => fortDefeatThreshold;
public float PhysicsGravityScale => physicsGravityScale;
public float PhysicsGravityScale => blockGravityScale; // Kept for backwards compatibility
public float BlockGravityScale => blockGravityScale;
public float ProjectileGravityScale => projectileGravityScale;
public float ProjectileSettleDelay => projectileSettleDelay;
public float TurnTransitionDelay => turnTransitionDelay;
public int FortBlockLayer => fortBlockLayer;
public int ProjectileLayer => projectileLayer;
public Color DamageColorTint => damageColorTint;
public float BaseLaunchForce => baseLaunchForce;
public float MinForceMultiplier => minForceMultiplier;
public float MaxForceMultiplier => maxForceMultiplier;
public float TrajectoryLockDuration => trajectoryLockDuration;
public float VacuumSlideSpeed => vacuumSlideSpeed;
public int VacuumDestroyBlockCount => vacuumDestroyBlockCount;
public float VacuumBlockDamage => vacuumBlockDamage;
public int TrashBagPieceCount => trashBagPieceCount;
public float TrashBagPieceForce => trashBagPieceForce;
public float TrashBagSpreadAngle => trashBagSpreadAngle;
public float TrashPieceDamage => trashPieceDamage;
public float TrashPieceLifetime => trashPieceLifetime;
public float CeilingFanActivationDelay => ceilingFanActivationDelay;
public float CeilingFanDropDelay => ceilingFanDropDelay;
public float CeilingFanDropSpeed => ceilingFanDropSpeed;
public IReadOnlyList<ProjectileConfig> ProjectileConfigs => projectileConfigs;
/// <summary>
/// Get projectile configuration by type
/// </summary>
public ProjectileConfig GetProjectileConfig(ProjectileType type)
{
foreach (var config in projectileConfigs)
{
if (config.projectileType == type)
{
return config;
}
}
return null;
}
/// <summary>
/// Get projectile configuration by ID string
/// </summary>
public ProjectileConfig GetProjectileConfigById(string projectileId)
{
foreach (var config in projectileConfigs)
{
if (config.projectileId == projectileId)
{
return config;
}
}
return null;
}
public BlockMaterialConfig GetMaterialConfig(BlockMaterial material)
{
return materialConfigs.FirstOrDefault(c => c.material == material);
@@ -83,6 +215,11 @@ namespace Minigames.FortFight.Core
private void OnValidate()
{
// Validate projectile configs
foreach (var config in projectileConfigs)
{
config?.Validate();
}
// Ensure defeat threshold is between 0 and 1
fortDefeatThreshold = Mathf.Clamp01(fortDefeatThreshold);

View File

@@ -1,4 +1,6 @@
using Core;
using AppleHills.Core.Settings;
using Core;
using Minigames.FortFight.Data;
using Minigames.FortFight.Projectiles;
using UnityEngine;
@@ -12,18 +14,34 @@ namespace Minigames.FortFight.Core
{
private SlingshotController slingshot;
private AmmunitionManager ammoManager;
private CameraController cameraController;
private int playerIndex;
private ProjectileBase activeProjectile;
private bool launchComplete = false;
private bool projectileSettled = false;
private float settleTimer = 0f;
private float settleDelay = 2.5f; // Wait 2.5s after impact before ending turn
private IFortFightSettings _cachedSettings;
private IFortFightSettings CachedSettings
{
get
{
if (_cachedSettings == null)
{
_cachedSettings = GameManager.GetSettingsObject<IFortFightSettings>();
}
return _cachedSettings;
}
}
public bool IsComplete => projectileSettled;
public ProjectileTurnAction(SlingshotController slingshot, AmmunitionManager ammoManager)
public ProjectileTurnAction(SlingshotController slingshot, AmmunitionManager ammoManager, CameraController cameraController, int playerIndex)
{
this.slingshot = slingshot;
this.ammoManager = ammoManager;
this.cameraController = cameraController;
this.playerIndex = playerIndex;
}
/// <summary>
@@ -61,9 +79,17 @@ namespace Minigames.FortFight.Core
settleTimer += Time.deltaTime;
float settleDelay = CachedSettings?.ProjectileSettleDelay ?? 2.5f;
if (settleTimer >= settleDelay)
{
projectileSettled = true;
// Stop camera tracking when projectile settles
if (cameraController != null)
{
cameraController.StopFollowingProjectile();
}
Logging.Debug("[ProjectileTurnAction] Turn action complete");
}
}
@@ -75,9 +101,17 @@ namespace Minigames.FortFight.Core
{
settleTimer += Time.deltaTime;
float settleDelay = CachedSettings?.ProjectileSettleDelay ?? 2.5f;
if (settleTimer >= settleDelay)
{
projectileSettled = true;
// Stop camera tracking when projectile settles
if (cameraController != null)
{
cameraController.StopFollowingProjectile();
}
Logging.Debug("[ProjectileTurnAction] Projectile settled - turn action complete");
}
}
@@ -114,10 +148,17 @@ namespace Minigames.FortFight.Core
slingshot.Disable();
}
// Trigger cooldown for used ammo
// Trigger cooldown for used ammo for this player
if (ammoManager != null)
{
ammoManager.UseAmmo();
ProjectileType usedAmmoType = ammoManager.GetSelectedAmmoType(playerIndex);
ammoManager.UseAmmo(usedAmmoType, playerIndex);
}
// Start camera tracking the projectile
if (cameraController != null && projectile != null)
{
cameraController.StartFollowingProjectile(projectile.transform);
}
}
}

View File

@@ -1,25 +1,23 @@
using System;
using AppleHills.Core.Settings;
using Core;
using Core.Lifecycle;
using Minigames.FortFight.Data;
using Minigames.FortFight.Projectiles;
using UnityEngine;
using UnityEngine.InputSystem;
namespace Minigames.FortFight.Core
{
/// <summary>
/// Controls slingshot aiming and projectile launching.
/// Angry Birds-style drag-to-aim mechanic with trajectory preview.
/// Implements ITouchInputConsumer for InputManager integration.
/// </summary>
public class SlingshotController : ManagedBehaviour
public class SlingshotController : ManagedBehaviour, ITouchInputConsumer
{
#region Inspector Properties
[Header("Launch Settings")]
[Tooltip("Maximum launch force")]
[SerializeField] private float maxForce = 20f;
[Tooltip("Drag distance to reach max force")]
[SerializeField] private float maxDragDistance = 5f;
@@ -33,6 +31,25 @@ namespace Minigames.FortFight.Core
[Header("Debug")]
[SerializeField] private bool showDebugLogs = true;
#endregion
#region Settings
private IFortFightSettings cachedSettings;
private IFortFightSettings CachedSettings
{
get
{
if (cachedSettings == null)
{
cachedSettings = GameManager.GetSettingsObject<IFortFightSettings>();
}
return cachedSettings;
}
}
private float MaxForce => CachedSettings?.BaseLaunchForce ?? 20f;
#endregion
#region Events
@@ -46,11 +63,10 @@ namespace Minigames.FortFight.Core
#region State
private bool isDragging = false;
private bool isDragging;
private Vector2 dragStartPosition;
private ProjectileData currentAmmo;
private Projectiles.ProjectileBase activeProjectile;
private Camera mainCamera;
private ProjectileConfig currentAmmo;
private ProjectileBase activeProjectile;
public bool IsDragging => isDragging;
public bool IsEnabled { get; private set; } = true;
@@ -63,8 +79,6 @@ namespace Minigames.FortFight.Core
{
base.OnManagedAwake();
mainCamera = Camera.main;
if (projectileSpawnPoint == null)
{
projectileSpawnPoint = transform;
@@ -87,62 +101,38 @@ namespace Minigames.FortFight.Core
}
}
private void Update()
#endregion
#region ITouchInputConsumer Implementation
public void OnTap(Vector2 worldPosition)
{
// Slingshot uses hold/drag, not tap
}
public void OnHoldStart(Vector2 worldPosition)
{
if (!IsEnabled) return;
HandleInput();
StartDrag(worldPosition);
}
public void OnHoldMove(Vector2 worldPosition)
{
if (!IsEnabled || !isDragging) return;
UpdateDrag(worldPosition);
}
public void OnHoldEnd(Vector2 worldPosition)
{
if (!IsEnabled || !isDragging) return;
EndDrag(worldPosition);
}
#endregion
#region Input Handling
#region Drag Handling
private void HandleInput()
{
// Check for mouse/touch input
if (Mouse.current != null)
{
// Mouse down - start drag
if (Mouse.current.leftButton.wasPressedThisFrame)
{
StartDrag(Mouse.current.position.ReadValue());
}
// Mouse held - update drag
if (Mouse.current.leftButton.isPressed && isDragging)
{
UpdateDrag(Mouse.current.position.ReadValue());
}
// Mouse up - release
if (Mouse.current.leftButton.wasReleasedThisFrame && isDragging)
{
EndDrag();
}
}
// Touch input (for mobile)
if (Touchscreen.current != null && Touchscreen.current.primaryTouch.press.isPressed)
{
var touch = Touchscreen.current.primaryTouch;
if (touch.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Began)
{
StartDrag(touch.position.ReadValue());
}
else if (touch.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Moved && isDragging)
{
UpdateDrag(touch.position.ReadValue());
}
else if (touch.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Ended && isDragging)
{
EndDrag();
}
}
}
private void StartDrag(Vector2 screenPosition)
private void StartDrag(Vector2 worldPosition)
{
if (currentAmmo == null)
{
@@ -151,7 +141,9 @@ namespace Minigames.FortFight.Core
}
isDragging = true;
dragStartPosition = screenPosition;
// Use the projectile spawn point as the anchor, not the touch position
// This makes it work like Angry Birds - pull back from slingshot to launch forward
dragStartPosition = projectileSpawnPoint.position;
// Show trajectory preview
if (trajectoryPreview != null)
@@ -159,28 +151,43 @@ namespace Minigames.FortFight.Core
trajectoryPreview.Show();
}
if (showDebugLogs) Logging.Debug($"[SlingshotController] Started drag at {screenPosition}");
if (showDebugLogs) Logging.Debug($"[SlingshotController] Started drag at {worldPosition}, anchor at spawn point {dragStartPosition}");
}
private void UpdateDrag(Vector2 currentScreenPosition)
private void UpdateDrag(Vector2 currentWorldPosition)
{
// Calculate drag vector
Vector2 dragVector = dragStartPosition - currentScreenPosition;
// Calculate drag vector from spawn point to current drag position
// Pull back (away from spawn) = launch forward (toward spawn direction)
Vector2 dragVector = dragStartPosition - currentWorldPosition;
// Calculate force and direction
float dragDistance = dragVector.magnitude;
float force = Mathf.Min(dragDistance / maxDragDistance, 1f) * maxForce;
float dragRatio = Mathf.Clamp01(dragDistance / maxDragDistance);
// Apply configurable max force multiplier
float maxMultiplier = CachedSettings?.MaxForceMultiplier ?? 1f;
float forceMultiplier = dragRatio * maxMultiplier;
float force = forceMultiplier * MaxForce;
Vector2 direction = dragVector.normalized;
// Update trajectory preview
if (trajectoryPreview != null)
// Update trajectory preview with projectile mass
if (trajectoryPreview != null && currentAmmo != null)
{
Vector2 worldStartPos = projectileSpawnPoint.position;
trajectoryPreview.UpdateTrajectory(worldStartPos, direction, force);
float mass = currentAmmo.GetMass();
// Debug: Log trajectory calculation (uncomment for debugging)
// if (showDebugLogs && Time.frameCount % 30 == 0) // Log every 30 frames to avoid spam
// {
// Logging.Debug($"[Slingshot] Preview - Force: {force:F2}, Mass: {mass:F2}, Velocity: {force/mass:F2}, Dir: {direction}");
// }
trajectoryPreview.UpdateTrajectory(worldStartPos, direction, force, mass);
}
}
private void EndDrag()
private void EndDrag(Vector2 currentWorldPosition)
{
isDragging = false;
@@ -190,21 +197,37 @@ namespace Minigames.FortFight.Core
trajectoryPreview.Hide();
}
// Calculate final launch parameters
Vector2 currentScreenPosition = Mouse.current != null ? Mouse.current.position.ReadValue() : Vector2.zero;
Vector2 dragVector = dragStartPosition - currentScreenPosition;
// Calculate final launch parameters from spawn point to final drag position
Vector2 dragVector = dragStartPosition - currentWorldPosition;
float dragDistance = dragVector.magnitude;
float force = Mathf.Min(dragDistance / maxDragDistance, 1f) * maxForce;
float dragRatio = Mathf.Clamp01(dragDistance / maxDragDistance);
// Apply configurable max force multiplier
float maxMultiplier = CachedSettings?.MaxForceMultiplier ?? 1f;
float forceMultiplier = dragRatio * maxMultiplier;
float force = forceMultiplier * MaxForce;
Vector2 direction = dragVector.normalized;
// Launch projectile
if (force > 0.1f) // Minimum drag threshold
// Check against configurable minimum force threshold
float minMultiplier = CachedSettings?.MinForceMultiplier ?? 0.1f;
float minForce = minMultiplier * MaxForce;
// Launch projectile if force exceeds minimum
if (force >= minForce)
{
if (showDebugLogs && currentAmmo != null)
{
float mass = currentAmmo.GetMass();
float velocity = force / mass;
Logging.Debug($"[Slingshot] Launch - Force: {force:F2}, Mass: {mass:F2}, Velocity: {velocity:F2}, Dir: {direction}");
}
LaunchProjectile(direction, force);
}
else
{
if (showDebugLogs) Logging.Debug("[SlingshotController] Drag too short - no launch");
if (showDebugLogs) Logging.Debug($"[SlingshotController] Drag too short - force {force:F2} < min {minForce:F2}");
}
}
@@ -215,11 +238,10 @@ namespace Minigames.FortFight.Core
/// <summary>
/// Set the current ammunition type
/// </summary>
public void SetAmmo(ProjectileData ammoData)
public void SetAmmo(ProjectileConfig ammoConfig)
{
currentAmmo = ammoData;
string ammoName = GetAmmoName(ammoData);
if (showDebugLogs) Logging.Debug($"[SlingshotController] Ammo set to: {ammoName}");
currentAmmo = ammoConfig;
if (showDebugLogs) Logging.Debug($"[SlingshotController] Ammo set to: {ammoConfig?.displayName ?? "null"}");
}
/// <summary>
@@ -244,11 +266,20 @@ namespace Minigames.FortFight.Core
return;
}
// Initialize projectile with its type (loads damage and mass from settings)
activeProjectile.Initialize(currentAmmo.projectileType);
// Launch it
activeProjectile.Launch(direction, force);
string ammoName = GetAmmoName(currentAmmo);
if (showDebugLogs) Logging.Debug($"[SlingshotController] Launched {ammoName} with force {force}");
// Lock trajectory to show the shot path
if (trajectoryPreview != null)
{
float lockDuration = CachedSettings?.TrajectoryLockDuration ?? 2f;
trajectoryPreview.LockTrajectory(lockDuration);
}
if (showDebugLogs) Logging.Debug($"[SlingshotController] Launched {currentAmmo?.displayName ?? "projectile"} with force {force}");
// Fire event
OnProjectileLaunched?.Invoke(activeProjectile);
@@ -257,7 +288,7 @@ namespace Minigames.FortFight.Core
/// <summary>
/// Get currently active projectile (in flight)
/// </summary>
public Projectiles.ProjectileBase GetActiveProjectile()
public ProjectileBase GetActiveProjectile()
{
return activeProjectile;
}
@@ -292,21 +323,6 @@ namespace Minigames.FortFight.Core
}
#endregion
#region Helpers
/// <summary>
/// Get display name for ammo (uses displayName or prefab name as fallback)
/// </summary>
private string GetAmmoName(ProjectileData ammo)
{
if (ammo == null) return "None";
if (!string.IsNullOrEmpty(ammo.displayName)) return ammo.displayName;
if (ammo.prefab != null) return ammo.prefab.name;
return "Unknown";
}
#endregion
}
}

View File

@@ -11,17 +11,8 @@ namespace Minigames.FortFight.Core
public class TrajectoryPreview : MonoBehaviour
{
[Header("Trajectory Settings")]
[Tooltip("Number of points to simulate")]
[SerializeField] private int simulationSteps = 30;
[Tooltip("Time step for each simulation point")]
[SerializeField] private float timeStep = 0.1f;
[Tooltip("Mass to use for simulation (should match projectile mass)")]
[SerializeField] private float projectileMass = 1f;
[Tooltip("Drag to use for simulation")]
[SerializeField] private float drag = 0f;
[Tooltip("Number of points to simulate (physics steps)")]
[SerializeField] private int simulationSteps = 50;
[Header("Visual")]
[Tooltip("Color of trajectory line")]
@@ -31,6 +22,9 @@ namespace Minigames.FortFight.Core
[SerializeField] private float lineWidth = 0.1f;
private LineRenderer lineRenderer;
private bool isLocked = false;
private float lockTimer = 0f;
private float lockDuration = 0f;
private void Awake()
{
@@ -48,8 +42,21 @@ namespace Minigames.FortFight.Core
}
}
private void Update()
{
if (isLocked)
{
lockTimer += Time.deltaTime;
if (lockTimer >= lockDuration)
{
isLocked = false;
Hide();
}
}
}
/// <summary>
/// Show the trajectory line
/// Show the trajectory preview
/// </summary>
public void Show()
{
@@ -60,10 +67,14 @@ namespace Minigames.FortFight.Core
}
/// <summary>
/// Hide the trajectory line
/// Hide the trajectory preview (unless locked)
/// </summary>
public void Hide()
{
// Don't hide if trajectory is locked
if (isLocked)
return;
if (lineRenderer != null)
{
lineRenderer.enabled = false;
@@ -71,35 +82,64 @@ namespace Minigames.FortFight.Core
}
/// <summary>
/// Update trajectory preview with new launch parameters
/// Lock the current trajectory display for a duration
/// </summary>
public void UpdateTrajectory(Vector2 startPosition, Vector2 direction, float force)
public void LockTrajectory(float duration)
{
isLocked = true;
lockTimer = 0f;
lockDuration = duration;
// Ensure line is visible
if (lineRenderer != null)
{
lineRenderer.enabled = true;
}
}
/// <summary>
/// Update the trajectory preview with new parameters.
/// Uses Physics.fixedDeltaTime for accurate simulation matching Unity's physics.
/// </summary>
/// <param name="startPosition">Starting position of trajectory</param>
/// <param name="direction">Launch direction (normalized)</param>
/// <param name="force">Launch force (impulse)</param>
/// <param name="mass">Projectile mass</param>
public void UpdateTrajectory(Vector2 startPosition, Vector2 direction, float force, float mass = 1f)
{
if (lineRenderer == null) return;
Vector2 velocity = direction * force;
Vector2 gravity = Physics2D.gravity;
// Calculate initial velocity: impulse force F gives velocity v = F/m
Vector2 startVelocity = (direction * force) / mass;
// Simulate trajectory points
// Get gravity with projectile gravity scale from settings
var settings = GameManager.GetSettingsObject<AppleHills.Core.Settings.IFortFightSettings>();
float gravityScale = settings?.ProjectileGravityScale ?? 1f;
Vector2 gravity = new Vector2(Physics2D.gravity.x, Physics2D.gravity.y) * gravityScale;
// Simulate trajectory using Unity's physics time step
Vector3[] points = new Vector3[simulationSteps];
Vector2 currentPos = startPosition;
Vector2 currentVelocity = velocity;
Vector2 pos = startPosition;
Vector2 vel = startVelocity;
for (int i = 0; i < simulationSteps; i++)
{
points[i] = currentPos;
// Set current position
points[i] = new Vector3(pos.x, pos.y, 0);
// Apply physics simulation
currentVelocity += gravity * timeStep;
currentPos += currentVelocity * timeStep;
// Update velocity (gravity applied over fixedDeltaTime)
vel = vel + gravity * Time.fixedDeltaTime;
// Optional: Stop if hits ground (y < some threshold)
if (currentPos.y < -10f)
// Update position (velocity applied over fixedDeltaTime)
pos = pos + vel * Time.fixedDeltaTime;
// Optional: Stop if hits ground (y < threshold)
if (pos.y < -10f)
{
// Fill remaining points at ground level
for (int j = i + 1; j < simulationSteps; j++)
{
points[j] = new Vector3(currentPos.x, -10f, 0);
points[j] = new Vector3(pos.x, -10f, 0);
}
break;
}

View File

@@ -2,15 +2,35 @@
using Core;
using Core.Lifecycle;
using Minigames.FortFight.Data;
using UnityEngine;
namespace Minigames.FortFight.Core
{
/// <summary>
/// Manages turn order and turn state for Fort Fight minigame.
/// Handles transitions between Player One, Player Two/AI turns.
/// Manages turn actions and input delegation.
/// </summary>
public class TurnManager : ManagedBehaviour
{
#region Inspector References
[Header("Slingshot Controllers")]
[Tooltip("Slingshot for Player One")]
[SerializeField] private SlingshotController playerOneSlingshotController;
[Tooltip("Slingshot for Player Two")]
[SerializeField] private SlingshotController playerTwoSlingshotController;
[Header("Systems")]
[Tooltip("Ammunition manager")]
[SerializeField] private AmmunitionManager ammunitionManager;
[Tooltip("Camera controller for projectile tracking")]
[SerializeField] private CameraController cameraController;
#endregion
#region Events
/// <summary>
@@ -38,6 +58,11 @@ namespace Minigames.FortFight.Core
private PlayerData currentPlayer;
private int turnCount = 0;
// Turn action management
private ProjectileTurnAction currentTurnAction;
private bool isTransitioning = false;
private float transitionTimer = 0f;
public TurnState CurrentTurnState => currentTurnState;
public PlayerData CurrentPlayer => currentPlayer;
public int TurnCount => turnCount;
@@ -46,6 +71,36 @@ namespace Minigames.FortFight.Core
#region Initialization
internal override void OnManagedAwake()
{
base.OnManagedAwake();
// Validate references
if (playerOneSlingshotController == null)
{
Logging.Error("[TurnManager] Player One slingshot controller not assigned!");
}
if (playerTwoSlingshotController == null)
{
Logging.Error("[TurnManager] Player Two slingshot controller not assigned!");
}
if (ammunitionManager == null)
{
Logging.Error("[TurnManager] Ammunition manager not assigned!");
}
if (cameraController == null)
{
Logging.Warning("[TurnManager] Camera controller not assigned - projectiles won't be followed by camera!");
}
// Disable both slingshots initially
if (playerOneSlingshotController != null) playerOneSlingshotController.Disable();
if (playerTwoSlingshotController != null) playerTwoSlingshotController.Disable();
}
/// <summary>
/// Initialize the turn manager with player data
/// </summary>
@@ -66,8 +121,50 @@ namespace Minigames.FortFight.Core
currentTurnState = TurnState.PlayerOneTurn;
currentPlayer = playerOne;
// Set initial input mode to UI
if (Input.InputManager.Instance != null)
{
Input.InputManager.Instance.SetInputMode(Input.InputMode.UI);
}
Logging.Debug($"[TurnManager] Game started. First turn: {currentPlayer.PlayerName}");
OnTurnStarted?.Invoke(currentPlayer, currentTurnState);
// Start turn action for first player
StartTurnAction();
}
#endregion
#region Lifecycle
private void Update()
{
// Update current turn action
if (currentTurnAction != null && !isTransitioning)
{
currentTurnAction.Update();
// Check if action is complete
if (currentTurnAction.IsComplete)
{
EndTurnAction();
}
}
// Handle transition timing
if (isTransitioning)
{
transitionTimer += Time.deltaTime;
var settings = GameManager.GetSettingsObject<AppleHills.Core.Settings.IFortFightSettings>();
float transitionDelay = settings?.TurnTransitionDelay ?? 1.5f;
if (transitionTimer >= transitionDelay)
{
CompleteTransition();
}
}
}
#endregion
@@ -75,9 +172,76 @@ namespace Minigames.FortFight.Core
#region Turn Management
/// <summary>
/// End the current turn and advance to the next player
/// Start turn action for current player (projectile launch)
/// </summary>
public void EndTurn()
private void StartTurnAction()
{
// Get the appropriate slingshot for current player
SlingshotController activeSlingshot = GetSlingshotForPlayer(currentPlayer);
if (activeSlingshot == null)
{
Logging.Error($"[TurnManager] No slingshot found for {currentPlayer.PlayerName}!");
return;
}
// Create and execute turn action with player index
currentTurnAction = new ProjectileTurnAction(activeSlingshot, ammunitionManager, cameraController, currentPlayer.PlayerIndex);
// Set current ammo on slingshot for this player
if (ammunitionManager != null)
{
ProjectileConfig currentAmmo = ammunitionManager.GetSelectedAmmoConfig(currentPlayer.PlayerIndex);
if (currentAmmo != null)
{
activeSlingshot.SetAmmo(currentAmmo);
}
}
// Execute the action (enables slingshot)
currentTurnAction.Execute();
// Register slingshot as input consumer and switch to Game mode
if (Input.InputManager.Instance != null)
{
Input.InputManager.Instance.RegisterOverrideConsumer(activeSlingshot);
Input.InputManager.Instance.SetInputMode(Input.InputMode.Game);
}
Logging.Debug($"[TurnManager] Started turn action for {currentPlayer.PlayerName}");
}
/// <summary>
/// End current turn action (projectile has settled)
/// </summary>
private void EndTurnAction()
{
Logging.Debug($"[TurnManager] Ending turn action for {currentPlayer.PlayerName}");
// Get active slingshot and unregister from input
SlingshotController activeSlingshot = GetSlingshotForPlayer(currentPlayer);
if (activeSlingshot != null && Input.InputManager.Instance != null)
{
Input.InputManager.Instance.UnregisterOverrideConsumer(activeSlingshot);
}
// Restore UI input mode
if (Input.InputManager.Instance != null)
{
Input.InputManager.Instance.SetInputMode(Input.InputMode.UI);
}
// Clear turn action
currentTurnAction = null;
// End the turn
EndTurn();
}
/// <summary>
/// End the current turn and begin transition to next player
/// </summary>
private void EndTurn()
{
if (currentTurnState == TurnState.GameOver)
{
@@ -88,16 +252,35 @@ namespace Minigames.FortFight.Core
Logging.Debug($"[TurnManager] Turn ended for {currentPlayer.PlayerName}");
OnTurnEnded?.Invoke(currentPlayer);
// Transition state
// Decrement ammunition cooldowns for this player
if (ammunitionManager != null)
{
ammunitionManager.DecrementCooldowns(currentPlayer.PlayerIndex);
}
// Enter transition state (triggers wide view camera via OnTurnStarted)
currentTurnState = TurnState.TransitioningTurn;
OnTurnTransitioning?.Invoke();
OnTurnStarted?.Invoke(currentPlayer, currentTurnState); // Fire for camera switch to wide view
// Start transition timer
isTransitioning = true;
transitionTimer = 0f;
}
/// <summary>
/// Complete transition and advance to next player
/// </summary>
private void CompleteTransition()
{
isTransitioning = false;
transitionTimer = 0f;
// Advance to next player
AdvanceToNextPlayer();
}
/// <summary>
/// Advance to the next player's turn
/// Advance to the next player's turn (called after transition delay)
/// </summary>
private void AdvanceToNextPlayer()
{
@@ -117,6 +300,26 @@ namespace Minigames.FortFight.Core
Logging.Debug($"[TurnManager] Advanced to turn {turnCount}. Current player: {currentPlayer.PlayerName} (State: {currentTurnState})");
OnTurnStarted?.Invoke(currentPlayer, currentTurnState);
// Start turn action for next player
StartTurnAction();
}
/// <summary>
/// Get the slingshot controller for a specific player
/// </summary>
private SlingshotController GetSlingshotForPlayer(PlayerData player)
{
if (player == playerOne)
{
return playerOneSlingshotController;
}
else if (player == playerTwo)
{
return playerTwoSlingshotController;
}
return null;
}
/// <summary>

View File

@@ -1,6 +1,4 @@
using System;
namespace Minigames.FortFight.Data
namespace Minigames.FortFight.Data
{
/// <summary>
/// Game mode for Fort Fight minigame
@@ -19,7 +17,7 @@ namespace Minigames.FortFight.Data
PlayerOneTurn,
PlayerTwoTurn,
AITurn,
TransitioningTurn,
TransitioningTurn, // Transitioning between turns (projectile in flight, waiting for settle)
GameOver
}

View File

@@ -0,0 +1,94 @@
using System;
using UnityEngine;
namespace Minigames.FortFight.Data
{
/// <summary>
/// Configuration data for a projectile type.
/// Stored centrally in FortFightSettings instead of individual ScriptableObject assets.
/// </summary>
[Serializable]
public class ProjectileConfig
{
[Header("Identity")]
[Tooltip("Type of projectile this config represents")]
public ProjectileType projectileType;
[Tooltip("Unique string identifier (auto-generated from type)")]
public string projectileId;
[Header("Prefab")]
[Tooltip("Prefab for this projectile (should have ProjectileBase component)")]
public GameObject prefab;
[Header("Ammunition System")]
[Tooltip("Cooldown in turns after use")]
public int cooldownTurns = 2;
[Header("UI")]
[Tooltip("Icon sprite for ammunition UI")]
public Sprite icon;
[Tooltip("Display name for this projectile type")]
public string displayName;
[Tooltip("Description of projectile behavior")]
[TextArea(2, 4)]
public string description;
[Header("Combat Stats")]
[Tooltip("Damage dealt on impact")]
public float damage = 20f;
[Header("Physics")]
[Tooltip("Mass for physics simulation (affects trajectory and force)")]
public float mass = 1f;
/// <summary>
/// Get the ProjectileBase component from the prefab
/// </summary>
public Projectiles.ProjectileBase GetProjectileComponent()
{
if (prefab == null) return null;
return prefab.GetComponent<Projectiles.ProjectileBase>();
}
/// <summary>
/// Get damage value from config
/// </summary>
public float GetDamage()
{
return damage;
}
/// <summary>
/// Get mass value from config
/// </summary>
public float GetMass()
{
return mass;
}
/// <summary>
/// Validate and auto-generate projectileId from type
/// </summary>
public void Validate()
{
if (string.IsNullOrEmpty(projectileId))
{
projectileId = GenerateIdFromType(projectileType);
}
if (string.IsNullOrEmpty(displayName))
{
displayName = projectileType.ToString();
}
}
private string GenerateIdFromType(ProjectileType type)
{
return type.ToString().ToLower();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9d60235e77c7456380c10f9c145750bf
timeCreated: 1764778577

View File

@@ -1,50 +0,0 @@
using UnityEngine;
namespace Minigames.FortFight.Data
{
/// <summary>
/// ScriptableObject defining a projectile type for the ammunition system.
/// Only stores prefab reference and UI data - stats come from the prefab's ProjectileBase component.
/// </summary>
[CreateAssetMenu(fileName = "ProjectileData", menuName = "AppleHills/Fort Fight/Projectile Data", order = 1)]
public class ProjectileData : ScriptableObject
{
[Header("Prefab")]
[Tooltip("Prefab for this projectile (should have ProjectileBase component)")]
public GameObject prefab;
[Header("Ammunition System")]
[Tooltip("Cooldown time in seconds after use")]
public float cooldownTime = 5f;
[Header("UI")]
[Tooltip("Icon sprite for ammunition UI")]
public Sprite icon;
[Tooltip("Display name for this projectile type")]
public string displayName;
[Tooltip("Description of projectile behavior (for tutorial/UI)")]
[TextArea(2, 4)]
public string description;
/// <summary>
/// Get the ProjectileBase component from the prefab (for reading stats)
/// </summary>
public Projectiles.ProjectileBase GetProjectileComponent()
{
if (prefab == null) return null;
return prefab.GetComponent<Projectiles.ProjectileBase>();
}
/// <summary>
/// Get damage value from prefab
/// </summary>
public float GetDamage()
{
var component = GetProjectileComponent();
return component != null ? component.Damage : 0f;
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 973f02063e5446598db4cbffdbf8f113
timeCreated: 1764682274

View File

@@ -102,6 +102,14 @@ namespace Minigames.FortFight.Fort
/// </summary>
public void Initialize()
{
// Automatically assign block to correct layer from settings
var settings = CachedSettings;
if (settings != null && settings.FortBlockLayer >= 0 && gameObject.layer != settings.FortBlockLayer)
{
gameObject.layer = settings.FortBlockLayer;
Logging.Debug($"[FortBlock] Assigned {gameObject.name} to layer {LayerMask.LayerToName(settings.FortBlockLayer)}");
}
// Cache components
rb2D = GetComponent<Rigidbody2D>();
blockCollider = GetComponent<Collider2D>();
@@ -260,7 +268,10 @@ namespace Minigames.FortFight.Fort
{
Logging.Debug($"[FortBlock] Spawning explosion effect prefab");
GameObject explosion = Instantiate(explosionEffectPrefab, transform.position, Quaternion.identity);
Destroy(explosion, 3f); // Auto-cleanup after 3 seconds
// Dynamically determine cleanup time from particle system
float lifetime = GetEffectLifetime(explosion);
Destroy(explosion, lifetime);
}
else
{
@@ -360,6 +371,30 @@ namespace Minigames.FortFight.Fort
Logging.Debug($"[FortBlock] Spawning destruction effect for {material} block");
}
/// <summary>
/// Get the lifetime of an effect by reading particle system StartLifetime.
/// Falls back to 3 seconds if no particle system found.
/// </summary>
private float GetEffectLifetime(GameObject effect)
{
// Try to read from ParticleSystem
ParticleSystem ps = effect.GetComponent<ParticleSystem>();
if (ps != null)
{
return ps.main.startLifetime.constantMax + 0.5f; // Add small buffer
}
// Try to read from child particle systems
ParticleSystem childPs = effect.GetComponentInChildren<ParticleSystem>();
if (childPs != null)
{
return childPs.main.startLifetime.constantMax + 0.5f;
}
// Fallback for non-particle effects
return 3f;
}
#endregion
#region Debug Helpers

View File

@@ -1,139 +0,0 @@
using Core;
using UnityEngine;
using Core.Lifecycle;
using Minigames.FortFight.Core;
using Minigames.FortFight.Data;
namespace Minigames.FortFight
{
/// <summary>
/// Debug script to test Phase 1 implementation without full UI setup.
/// Attach to a GameObject in the scene to run automated tests.
/// </summary>
public class FortFightPhase1Tester : ManagedBehaviour
{
[Header("Test Settings")]
[SerializeField] private bool runAutomatedTest = true;
[SerializeField] private FortFightGameMode testMode = FortFightGameMode.SinglePlayer;
[SerializeField] private int numberOfTurnsToTest = 6;
private FortFightGameManager gameManager;
private TurnManager turnManager;
private int playerActionsExecuted = 0;
internal override void OnManagedStart()
{
base.OnManagedStart();
if (!runAutomatedTest)
{
Logging.Debug("[FortFightPhase1Tester] Automated test disabled");
return;
}
// Find managers
gameManager = FindFirstObjectByType<FortFightGameManager>();
turnManager = FindFirstObjectByType<TurnManager>();
if (gameManager == null)
{
Logging.Error("[FortFightPhase1Tester] FortFightGameManager not found!");
return;
}
if (turnManager == null)
{
Logging.Error("[FortFightPhase1Tester] TurnManager not found!");
return;
}
// Subscribe to events for testing
gameManager.OnGameModeSelected += OnGameModeSelected;
gameManager.OnGameStarted += OnGameStarted;
turnManager.OnTurnStarted += OnTurnStarted;
turnManager.OnTurnEnded += OnTurnEnded;
// Start test
Logging.Debug("=== STARTING PHASE 1 AUTOMATED TEST ===");
Logging.Debug($"Testing mode: {testMode}");
Logging.Debug($"Will execute {numberOfTurnsToTest} turns total");
// Simulate mode selection
gameManager.SelectGameMode(testMode);
}
private void OnGameModeSelected(FortFightGameMode mode)
{
Logging.Debug($"[TEST] Game mode selected: {mode}");
}
private void OnGameStarted()
{
Logging.Debug("[TEST] Game started!");
}
private void OnTurnStarted(PlayerData currentPlayer, TurnState turnState)
{
Logging.Debug($"[TEST] Turn started - Player: {currentPlayer.PlayerName}, State: {turnState}, Turn #: {turnManager.TurnCount + 1}");
// If it's a human player's turn (not AI), simulate taking action after a delay
if (turnState == TurnState.PlayerOneTurn || turnState == TurnState.PlayerTwoTurn)
{
Invoke(nameof(SimulatePlayerAction), 0.5f);
}
// Check if we've reached the test limit
if (turnManager.TurnCount >= numberOfTurnsToTest)
{
Logging.Debug("=== TEST COMPLETE ===");
Logging.Debug($"Successfully completed {numberOfTurnsToTest} turns!");
Logging.Debug($"Player actions executed: {playerActionsExecuted}");
// End the game
gameManager.EndGame();
}
}
private void OnTurnEnded(PlayerData player)
{
Logging.Debug($"[TEST] Turn ended for {player.PlayerName}");
}
private void SimulatePlayerAction()
{
if (turnManager == null) return;
TurnState state = turnManager.CurrentTurnState;
// Only simulate if it's still a player turn (not transitioned yet)
if (state == TurnState.PlayerOneTurn || state == TurnState.PlayerTwoTurn)
{
PlayerData currentPlayer = turnManager.CurrentPlayer;
Logging.Debug($"[TEST] Simulating action for {currentPlayer.PlayerName}");
playerActionsExecuted++;
// End the turn
turnManager.EndTurn();
}
}
internal override void OnManagedDestroy()
{
base.OnManagedDestroy();
// Unsubscribe from events
if (gameManager != null)
{
gameManager.OnGameModeSelected -= OnGameModeSelected;
gameManager.OnGameStarted -= OnGameStarted;
}
if (turnManager != null)
{
turnManager.OnTurnStarted -= OnTurnStarted;
turnManager.OnTurnEnded -= OnTurnEnded;
}
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 756ba6afb97885c43a3d0eac023b3797

View File

@@ -1,184 +0,0 @@
using Core;
using UnityEngine;
using UnityEngine.InputSystem;
using Core.Lifecycle;
using Minigames.FortFight.Core;
using Minigames.FortFight.Fort;
namespace Minigames.FortFight
{
/// <summary>
/// Debug script to test Phase 2 fort system.
/// Attach to a GameObject in the scene to manually trigger fort damage for testing.
/// </summary>
public class FortFightPhase2Tester : ManagedBehaviour
{
[Header("Test Settings")]
[SerializeField] private bool enableKeyboardControls = true;
[SerializeField] private float testDamageAmount = 25f;
[SerializeField] private bool autoTestOnStart = false;
[SerializeField] private float autoTestDelay = 2f;
private FortManager fortManager;
private FortController playerFort;
private FortController enemyFort;
internal override void OnManagedStart()
{
base.OnManagedStart();
// Find fort manager
fortManager = FindFirstObjectByType<FortManager>();
if (fortManager == null)
{
Logging.Error("[FortFightPhase2Tester] FortManager not found!");
return;
}
// Subscribe to fort spawn events
fortManager.OnPlayerFortSpawned += OnPlayerFortSpawned;
fortManager.OnEnemyFortSpawned += OnEnemyFortSpawned;
Logging.Debug("=== PHASE 2 TESTING CONTROLS ===");
Logging.Debug("Press '1' to damage random PLAYER fort block");
Logging.Debug("Press '2' to damage random ENEMY fort block");
Logging.Debug("Press '3' to damage PLAYER fort weak point");
Logging.Debug("Press '4' to damage ENEMY fort weak point");
Logging.Debug("Press '5' to destroy random PLAYER block");
Logging.Debug("Press '6' to destroy random ENEMY block");
Logging.Debug("================================");
if (autoTestOnStart)
{
InvokeRepeating(nameof(AutoTest), autoTestDelay, autoTestDelay);
}
}
private void OnPlayerFortSpawned(FortController fort)
{
playerFort = fort;
Logging.Debug($"[Phase2Tester] Player fort spawned: {fort.FortName}");
}
private void OnEnemyFortSpawned(FortController fort)
{
enemyFort = fort;
Logging.Debug($"[Phase2Tester] Enemy fort spawned: {fort.FortName}");
}
private void Update()
{
if (!enableKeyboardControls) return;
if (Keyboard.current == null) return;
// Test controls
if (Keyboard.current.digit1Key.wasPressedThisFrame)
{
DamageRandomBlock(playerFort, testDamageAmount);
}
if (Keyboard.current.digit2Key.wasPressedThisFrame)
{
DamageRandomBlock(enemyFort, testDamageAmount);
}
if (Keyboard.current.digit3Key.wasPressedThisFrame)
{
DamageWeakPoint(playerFort);
}
if (Keyboard.current.digit4Key.wasPressedThisFrame)
{
DamageWeakPoint(enemyFort);
}
if (Keyboard.current.digit5Key.wasPressedThisFrame)
{
DestroyRandomBlock(playerFort);
}
if (Keyboard.current.digit6Key.wasPressedThisFrame)
{
DestroyRandomBlock(enemyFort);
}
}
private void AutoTest()
{
// Alternate between player and enemy
if (Random.value > 0.5f)
{
DamageRandomBlock(playerFort, testDamageAmount);
}
else
{
DamageRandomBlock(enemyFort, testDamageAmount);
}
}
private void DamageRandomBlock(FortController fort, float damage)
{
if (fort == null || fort.TotalBlockCount == 0)
{
Logging.Warning("[Phase2Tester] No fort or blocks available to damage!");
return;
}
FortBlock randomBlock = fort.GetRandomBlock();
if (randomBlock != null)
{
Logging.Debug($"[Phase2Tester] Damaging {fort.FortName} block '{randomBlock.gameObject.name}' for {damage} damage");
randomBlock.TakeDamage(damage);
}
}
private void DamageWeakPoint(FortController fort)
{
if (fort == null)
{
Logging.Warning("[Phase2Tester] Fort is null!");
return;
}
var weakPoints = fort.GetWeakPoints();
if (weakPoints.Count == 0)
{
Logging.Warning($"[Phase2Tester] {fort.FortName} has no weak points!");
return;
}
FortBlock weakPoint = weakPoints[Random.Range(0, weakPoints.Count)];
Logging.Debug($"[Phase2Tester] Destroying {fort.FortName} WEAK POINT '{weakPoint.gameObject.name}'");
weakPoint.TakeDamage(999f); // Instant destruction
}
private void DestroyRandomBlock(FortController fort)
{
if (fort == null || fort.TotalBlockCount == 0)
{
Logging.Warning("[Phase2Tester] No fort or blocks available to destroy!");
return;
}
FortBlock randomBlock = fort.GetRandomBlock();
if (randomBlock != null)
{
Logging.Debug($"[Phase2Tester] DESTROYING {fort.FortName} block '{randomBlock.gameObject.name}'");
randomBlock.TakeDamage(999f); // Instant destruction
}
}
internal override void OnManagedDestroy()
{
base.OnManagedDestroy();
if (fortManager != null)
{
fortManager.OnPlayerFortSpawned -= OnPlayerFortSpawned;
fortManager.OnEnemyFortSpawned -= OnEnemyFortSpawned;
}
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 74f26236978245cdaf33909a7c242cbf
timeCreated: 1764592117

View File

@@ -5,17 +5,59 @@ using UnityEngine;
namespace Minigames.FortFight.Projectiles
{
/// <summary>
/// Ceiling Fan projectile - drops straight down when ability is activated.
/// Player taps screen mid-flight to activate drop.
/// Ceiling Fan projectile - drops straight down when player taps screen.
/// Implements ITouchInputConsumer to capture tap input mid-flight.
/// </summary>
public class CeilingFanProjectile : ProjectileBase
public class CeilingFanProjectile : ProjectileBase, ITouchInputConsumer
{
[Header("Ceiling Fan Specific")]
[Tooltip("Speed of downward drop")]
[SerializeField] private float dropSpeed = 20f;
[Tooltip("Visual indicator showing drop is available (arrow down)")]
[SerializeField] private GameObject indicator;
[Tooltip("Delay before dropping")]
[SerializeField] private float dropDelay = 0.2f;
private bool isDropping = false;
private bool inputEnabled = false;
public override void Launch(Vector2 direction, float force)
{
base.Launch(direction, force);
// Hide indicator initially
if (indicator != null)
{
indicator.SetActive(false);
}
// Start activation delay coroutine
StartCoroutine(ActivationDelayCoroutine());
}
private IEnumerator ActivationDelayCoroutine()
{
// Get activation delay from settings
var settings = GameManager.GetSettingsObject<AppleHills.Core.Settings.IFortFightSettings>();
float activationDelay = settings?.CeilingFanActivationDelay ?? 0.5f;
// Wait for delay
yield return new WaitForSeconds(activationDelay);
// Enable input and show indicator (if not already dropped)
if (!isDropping && !AbilityActivated)
{
inputEnabled = true;
if (indicator != null)
{
indicator.SetActive(true);
}
// Register with InputManager to capture tap-to-drop
if (Input.InputManager.Instance != null)
{
Input.InputManager.Instance.RegisterOverrideConsumer(this);
Logging.Debug("[CeilingFanProjectile] Tap-to-drop now available");
}
}
}
public override void ActivateAbility()
{
@@ -30,6 +72,8 @@ namespace Minigames.FortFight.Projectiles
private IEnumerator DropCoroutine()
{
isDropping = true;
// Stop all velocity
if (rb2D != null)
{
@@ -37,6 +81,11 @@ namespace Minigames.FortFight.Projectiles
rb2D.angularVelocity = 0f;
}
// Get drop configuration from settings
var settings = GameManager.GetSettingsObject<AppleHills.Core.Settings.IFortFightSettings>();
float dropDelay = settings?.CeilingFanDropDelay ?? 0.2f;
float dropSpeed = settings?.CeilingFanDropSpeed ?? 20f;
// Wait brief moment
yield return new WaitForSeconds(dropDelay);
@@ -47,6 +96,88 @@ namespace Minigames.FortFight.Projectiles
Logging.Debug($"[CeilingFanProjectile] Dropping with velocity: {rb2D.linearVelocity}");
}
}
protected override void OnHit(Collision2D collision)
{
// Spawn impact effect only if dropped (not on normal arc hit)
if (isDropping)
{
SpawnImpactEffect(collision.contacts[0].point);
}
// Deal damage to blocks
var block = collision.gameObject.GetComponent<Fort.FortBlock>();
if (block != null)
{
block.TakeDamage(Damage);
Logging.Debug($"[CeilingFanProjectile] Dealt {Damage} damage to {block.gameObject.name}");
}
// Destroy projectile
DestroyProjectile();
}
#region ITouchInputConsumer Implementation
public void OnTap(Vector2 worldPosition)
{
// Only respond if input is enabled
if (inputEnabled && !AbilityActivated && !isDropping)
{
Logging.Debug("[CeilingFanProjectile] Tap detected - activating drop");
// Hide indicator
if (indicator != null)
{
indicator.SetActive(false);
}
ActivateAbility();
// Unregister immediately after tap
UnregisterFromInput();
}
}
public void OnHoldStart(Vector2 worldPosition)
{
// Not used for ceiling fan
}
public void OnHoldMove(Vector2 worldPosition)
{
// Not used for ceiling fan
}
public void OnHoldEnd(Vector2 worldPosition)
{
// Not used for ceiling fan
}
#endregion
private void UnregisterFromInput()
{
inputEnabled = false;
if (indicator != null)
{
indicator.SetActive(false);
}
if (Input.InputManager.Instance != null)
{
Input.InputManager.Instance.UnregisterOverrideConsumer(this);
Logging.Debug("[CeilingFanProjectile] Unregistered from input");
}
}
protected override void DestroyProjectile()
{
// Make sure we unregister when destroyed
UnregisterFromInput();
base.DestroyProjectile();
}
}
}

View File

@@ -16,13 +16,6 @@ namespace Minigames.FortFight.Projectiles
{
#region Inspector Properties
[Header("Projectile Stats")]
[Tooltip("Base damage dealt on impact")]
[SerializeField] protected float damage = 20f;
[Tooltip("Mass for physics (affects trajectory)")]
[SerializeField] protected float mass = 1f;
[Header("Visuals")]
[Tooltip("Sprite renderer for projectile")]
[SerializeField] protected SpriteRenderer spriteRenderer;
@@ -54,7 +47,10 @@ namespace Minigames.FortFight.Projectiles
#region Properties
public float Damage => damage;
public float Damage { get; protected set; }
public float Mass { get; protected set; }
public Data.ProjectileType ProjectileType { get; protected set; }
public bool IsLaunched { get; protected set; }
public bool AbilityActivated { get; protected set; }
public Vector2 LaunchDirection { get; protected set; }
@@ -71,10 +67,59 @@ namespace Minigames.FortFight.Projectiles
#region Lifecycle
/// <summary>
/// Initialize the projectile with its type and load stats from settings.
/// Must be called after instantiation, before Launch.
/// </summary>
public void Initialize(Data.ProjectileType projectileType)
{
ProjectileType = projectileType;
// Load damage and mass from settings
var settings = GameManager.GetSettingsObject<AppleHills.Core.Settings.IFortFightSettings>();
if (settings != null)
{
var config = settings.GetProjectileConfig(projectileType);
if (config != null)
{
Damage = config.damage;
Mass = config.mass;
// Update rigidbody mass if already initialized
if (rb2D != null)
{
rb2D.mass = Mass;
}
Logging.Debug($"[ProjectileBase] Initialized {projectileType} - Damage: {Damage}, Mass: {Mass}");
}
else
{
Logging.Warning($"[ProjectileBase] No config found for {projectileType}, using defaults");
Damage = 20f;
Mass = 1f;
}
}
else
{
Logging.Warning($"[ProjectileBase] Settings not found, using default damage and mass");
Damage = 20f;
Mass = 1f;
}
}
internal override void OnManagedAwake()
{
base.OnManagedAwake();
// Automatically assign projectile to correct layer from settings
var settings = GameManager.GetSettingsObject<AppleHills.Core.Settings.IFortFightSettings>();
if (settings != null && settings.ProjectileLayer >= 0 && gameObject.layer != settings.ProjectileLayer)
{
gameObject.layer = settings.ProjectileLayer;
Logging.Debug($"[ProjectileBase] Assigned {gameObject.name} to layer {LayerMask.LayerToName(settings.ProjectileLayer)}");
}
// Cache components
rb2D = GetComponent<Rigidbody2D>();
projectileCollider = GetComponent<Collider2D>();
@@ -84,11 +129,18 @@ namespace Minigames.FortFight.Projectiles
spriteRenderer = GetComponent<SpriteRenderer>();
}
// Configure rigidbody
// Configure rigidbody (mass will be set by Initialize if called, otherwise use defaults)
if (rb2D != null)
{
rb2D.mass = mass;
rb2D.gravityScale = 1f;
// If Initialize hasn't been called yet, use default mass
if (Mass == 0f)
{
Mass = 1f;
Damage = 20f;
}
rb2D.mass = Mass;
rb2D.gravityScale = settings?.ProjectileGravityScale ?? 1f;
rb2D.collisionDetectionMode = CollisionDetectionMode2D.Continuous;
}
}
@@ -117,7 +169,14 @@ namespace Minigames.FortFight.Projectiles
if (rb2D != null)
{
rb2D.AddForce(LaunchDirection * LaunchForce, ForceMode2D.Impulse);
Logging.Debug($"[ProjectileBase] Launched {gameObject.name} with force {LaunchForce} in direction {LaunchDirection}");
// Debug: Log actual mass and resulting velocity for trajectory verification
float actualMass = rb2D.mass;
float expectedVelocity = LaunchForce / actualMass;
Logging.Debug($"[Projectile] Launched {gameObject.name} - Force: {LaunchForce:F2}, Mass: {actualMass:F2}, Expected Velocity: {expectedVelocity:F2}, Dir: {LaunchDirection}");
// After physics applies, log actual velocity (next frame would show it, but we log expectation)
// Note: Actual velocity will be set by Unity physics engine as: velocity = impulse / mass
}
// Fire event
@@ -163,36 +222,32 @@ namespace Minigames.FortFight.Projectiles
Logging.Debug($"[ProjectileBase] {gameObject.name} hit {collision.gameObject.name}");
// Check if hit a fort block
FortBlock block = collision.gameObject.GetComponent<FortBlock>();
if (block != null)
{
// Deal damage to block
block.TakeDamage(damage);
Logging.Debug($"[ProjectileBase] Dealt {damage} damage to {block.gameObject.name}");
}
// Spawn impact effect
SpawnImpactEffect(collision.contacts[0].point);
// Fire impact event
OnImpact?.Invoke(this, collision.collider);
// Call subclass-specific hit behavior
OnHit(collision.collider);
// Destroy projectile after hit (subclasses can override)
DestroyProjectile();
// Delegate to subclass - they handle everything (damage, effects, destruction)
OnHit(collision);
}
/// <summary>
/// Called when projectile hits something.
/// Override in subclasses for projectile-specific behavior.
/// Override in subclasses to implement full projectile behavior.
/// Default implementation: Deal damage to blocks and destroy projectile.
/// Subclasses should call DestroyProjectile() when they want to be destroyed.
/// </summary>
protected virtual void OnHit(Collider2D hit)
/// <param name="collision">Collision data including contact points and normals</param>
protected virtual void OnHit(Collision2D collision)
{
// Subclasses override for special behavior
// e.g., Vacuum continues sliding, TrashBag splits, etc.
// Default behavior: Deal damage to blocks and destroy
FortBlock block = collision.gameObject.GetComponent<FortBlock>();
if (block != null)
{
block.TakeDamage(Damage);
Logging.Debug($"[ProjectileBase] Dealt {Damage} damage to {block.gameObject.name}");
}
// Default: Destroy on hit
DestroyProjectile();
}
#endregion
@@ -207,10 +262,37 @@ namespace Minigames.FortFight.Projectiles
if (impactEffectPrefab != null)
{
GameObject effect = Instantiate(impactEffectPrefab, position, Quaternion.identity);
Destroy(effect, 2f); // Auto-cleanup
// Dynamically determine cleanup time from particle system
float lifetime = GetEffectLifetime(effect);
Destroy(effect, lifetime);
}
}
/// <summary>
/// Get the lifetime of an effect by reading particle system StartLifetime.
/// Falls back to 2 seconds if no particle system found.
/// </summary>
private float GetEffectLifetime(GameObject effect)
{
// Try to read from ParticleSystem
ParticleSystem ps = effect.GetComponent<ParticleSystem>();
if (ps != null)
{
return ps.main.startLifetime.constantMax + 0.5f; // Add small buffer
}
// Try to read from child particle systems
ParticleSystem childPs = effect.GetComponentInChildren<ParticleSystem>();
if (childPs != null)
{
return childPs.main.startLifetime.constantMax + 0.5f;
}
// Fallback for non-particle effects (sprites, etc.)
return 2f;
}
#endregion
#region Destruction

View File

@@ -12,6 +12,23 @@ namespace Minigames.FortFight.Projectiles
// Toaster is the basic projectile - uses base class behavior
// No special ability needed
protected override void OnHit(Collision2D collision)
{
// Spawn impact effect
SpawnImpactEffect(collision.contacts[0].point);
// Deal damage to blocks
var block = collision.gameObject.GetComponent<Fort.FortBlock>();
if (block != null)
{
block.TakeDamage(Damage);
Logging.Debug($"[ToasterProjectile] Dealt {Damage} damage to {block.gameObject.name}");
}
// Destroy projectile
DestroyProjectile();
}
public override void ActivateAbility()
{
// Toaster has no special ability

View File

@@ -10,33 +10,41 @@ namespace Minigames.FortFight.Projectiles
public class TrashBagProjectile : ProjectileBase
{
[Header("Trash Bag Specific")]
[Tooltip("Number of trash pieces to spawn on impact")]
[SerializeField] private int trashPieceCount = 6;
[Tooltip("Prefab for individual trash pieces")]
[Tooltip("Prefab for individual trash pieces (small debris)")]
[SerializeField] private GameObject trashPiecePrefab;
[Tooltip("Force applied to each trash piece")]
[SerializeField] private float pieceForce = 8f;
[Tooltip("Spread angle for trash pieces (degrees)")]
[SerializeField] private float spreadAngle = 30f;
[Tooltip("Damage dealt by each trash piece")]
[SerializeField] private float pieceDamage = 8f;
protected override void OnHit(Collider2D hit)
protected override void OnHit(Collision2D collision)
{
base.OnHit(hit);
// Deal initial damage from trash bag itself
var block = collision.gameObject.GetComponent<Fort.FortBlock>();
if (block != null)
{
block.TakeDamage(Damage);
Logging.Debug($"[TrashBagProjectile] Dealt {Damage} damage to {block.gameObject.name}");
}
Logging.Debug($"[TrashBagProjectile] Splitting into {trashPieceCount} pieces");
SpawnTrashPieces(hit.transform.position);
// Get settings for trash pieces
var settings = GameManager.GetSettingsObject<AppleHills.Core.Settings.IFortFightSettings>();
int pieceCount = settings?.TrashBagPieceCount ?? 8;
Logging.Debug($"[TrashBagProjectile] Splitting into {pieceCount} pieces");
// Get contact normal and impact point
Vector2 hitNormal = collision.contacts[0].normal;
Vector2 impactPoint = collision.contacts[0].point;
// Spawn trash pieces (NOT parented, so they persist as debris)
SpawnTrashPieces(impactPoint, hitNormal);
// Destroy trash bag after spawning pieces
DestroyProjectile();
}
/// <summary>
/// Spawn multiple trash pieces in a forward cone
/// Spawn multiple trash pieces in a cone away from the hit surface.
/// Uses hit normal + projectile momentum for realistic splash effect.
/// </summary>
private void SpawnTrashPieces(Vector2 impactPoint)
private void SpawnTrashPieces(Vector2 impactPoint, Vector2 hitNormal)
{
if (trashPiecePrefab == null)
{
@@ -44,77 +52,56 @@ namespace Minigames.FortFight.Projectiles
return;
}
// Calculate forward direction from velocity
Vector2 forwardDirection = rb2D.linearVelocity.normalized;
if (forwardDirection == Vector2.zero)
// Get settings
var settings = GameManager.GetSettingsObject<AppleHills.Core.Settings.IFortFightSettings>();
int pieceCount = settings?.TrashBagPieceCount ?? 8;
float pieceForce = settings?.TrashBagPieceForce ?? 10f;
float spreadAngle = settings?.TrashBagSpreadAngle ?? 60f;
// Calculate projectile's incoming direction (momentum)
Vector2 incomingDirection = rb2D.linearVelocity.normalized;
if (incomingDirection == Vector2.zero)
{
forwardDirection = LaunchDirection;
incomingDirection = LaunchDirection;
}
// Spawn pieces in a cone
for (int i = 0; i < trashPieceCount; i++)
// Calculate reflection direction from hit normal
// This creates a bounce-like effect
Vector2 reflectDirection = Vector2.Reflect(incomingDirection, hitNormal);
// Blend between reflection and pure normal for more variety
// 70% normal (splash away from surface) + 30% reflection (maintain some momentum direction)
Vector2 baseDirection = (hitNormal * 0.7f + reflectDirection * 0.3f).normalized;
// Spawn pieces in a cone around the base direction
for (int i = 0; i < pieceCount; i++)
{
// Calculate angle for this piece
float angleOffset = Mathf.Lerp(-spreadAngle, spreadAngle, i / (float)(trashPieceCount - 1));
float angleRadians = Mathf.Atan2(forwardDirection.y, forwardDirection.x) + angleOffset * Mathf.Deg2Rad;
// Calculate angle offset for this piece within the spread cone
float t = pieceCount > 1 ? i / (float)(pieceCount - 1) : 0.5f;
float angleOffset = Mathf.Lerp(-spreadAngle / 2f, spreadAngle / 2f, t);
float angleRadians = Mathf.Atan2(baseDirection.y, baseDirection.x) + angleOffset * Mathf.Deg2Rad;
Vector2 pieceDirection = new Vector2(Mathf.Cos(angleRadians), Mathf.Sin(angleRadians));
// Spawn trash piece
GameObject piece = Instantiate(trashPiecePrefab, impactPoint, Quaternion.identity);
// Spawn trash piece slightly offset from impact point
Vector2 spawnOffset = pieceDirection * 0.2f; // Small offset to prevent clipping
GameObject piece = Instantiate(trashPiecePrefab, (Vector2)impactPoint + spawnOffset, Quaternion.identity);
// Setup trash piece physics
Rigidbody2D pieceRb = piece.GetComponent<Rigidbody2D>();
if (pieceRb != null)
{
pieceRb.AddForce(pieceDirection * pieceForce, ForceMode2D.Impulse);
// Apply force with some randomness for more natural spread
float randomForce = pieceForce * Random.Range(0.8f, 1.2f);
pieceRb.AddForce(pieceDirection * randomForce, ForceMode2D.Impulse);
// Add some random spin
pieceRb.AddTorque(Random.Range(-100f, 100f));
}
// Setup trash piece damage (if it has a component)
TrashPiece trashPieceComponent = piece.GetComponent<TrashPiece>();
if (trashPieceComponent != null)
{
trashPieceComponent.Initialize(pieceDamage);
}
// Auto-destroy after 3 seconds
Destroy(piece, 3f);
Logging.Debug($"[TrashBagProjectile] Spawned trash piece {i} in direction {pieceDirection}");
}
}
}
/// <summary>
/// Component for individual trash pieces spawned by TrashBagProjectile.
/// Deals damage on collision.
/// </summary>
public class TrashPiece : MonoBehaviour
{
private float damage;
private bool hasHit = false;
public void Initialize(float pieceDamage)
{
this.damage = pieceDamage;
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (hasHit) return;
hasHit = true;
// Check if hit a fort block
var block = collision.gameObject.GetComponent<Fort.FortBlock>();
if (block != null)
{
block.TakeDamage(damage);
Logging.Debug($"[TrashPiece] Dealt {damage} damage to {block.gameObject.name}");
}
// Destroy this piece
Destroy(gameObject, 0.1f);
}
}
}

View File

@@ -0,0 +1,81 @@
using Core;
using UnityEngine;
namespace Minigames.FortFight.Projectiles
{
/// <summary>
/// Component for individual trash pieces spawned by TrashBagProjectile.
/// Deals pre-configured damage on collision with blocks, spawns impact effect, then auto-cleans up after timeout.
/// </summary>
public class TrashPiece : MonoBehaviour
{
[Header("Visual Effects")]
[Tooltip("Impact effect prefab spawned on block collision")]
[SerializeField] private GameObject impactEffectPrefab;
private float damage;
private bool hasHit = false;
private void Start()
{
// Get configuration from settings
var settings = GameManager.GetSettingsObject<AppleHills.Core.Settings.IFortFightSettings>();
damage = settings?.TrashPieceDamage ?? 5f;
float lifetime = settings?.TrashPieceLifetime ?? 5f;
// Auto-cleanup after configured timeout
Destroy(gameObject, lifetime);
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (hasHit) return;
// Check if hit a fort block
var block = collision.gameObject.GetComponent<Fort.FortBlock>();
if (block != null)
{
hasHit = true;
// Deal damage
block.TakeDamage(damage);
Logging.Debug($"[TrashPiece] Dealt {damage} damage to {block.gameObject.name}");
// Spawn impact effect at collision point
if (impactEffectPrefab != null && collision.contacts.Length > 0)
{
Vector2 impactPoint = collision.contacts[0].point;
GameObject effect = Instantiate(impactEffectPrefab, impactPoint, Quaternion.identity);
// Dynamically determine cleanup time from particle system
float lifetime = GetEffectLifetime(effect);
Destroy(effect, lifetime);
}
}
}
/// <summary>
/// Get the lifetime of an effect by reading particle system StartLifetime.
/// Falls back to 2 seconds if no particle system found.
/// </summary>
private float GetEffectLifetime(GameObject effect)
{
// Try to read from ParticleSystem
ParticleSystem ps = effect.GetComponent<ParticleSystem>();
if (ps != null)
{
return ps.main.startLifetime.constantMax + 0.5f; // Add small buffer
}
// Try to read from child particle systems
ParticleSystem childPs = effect.GetComponentInChildren<ParticleSystem>();
if (childPs != null)
{
return childPs.main.startLifetime.constantMax + 0.5f;
}
// Fallback for non-particle effects
return 2f;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 516daf2ce7384aaa94fd5e0f7a3cf078
timeCreated: 1764756385

View File

@@ -1,40 +1,59 @@
using System.Collections;
using Core;
using Core;
using UnityEngine;
namespace Minigames.FortFight.Projectiles
{
/// <summary>
/// Vacuum projectile - high mass, slides along ground after landing.
/// On ground impact: disables gravity, moves horizontally for 2 seconds.
/// On floor/block impact: applies constant force to the right and destroys blocks.
/// </summary>
public class VacuumProjectile : ProjectileBase
{
[Header("Vacuum Specific")]
[Tooltip("Speed when sliding on ground")]
[SerializeField] private float slideSpeed = 10f;
[Tooltip("How long to slide before destroying")]
[SerializeField] private float slideDuration = 2f;
[Tooltip("Layer mask for ground detection")]
[SerializeField] private LayerMask groundLayer = 1; // Default layer
private bool isSliding = false;
private int blocksDestroyed = 0;
private int maxBlocksToDestroy = 3;
private Vector2 slideDirection;
protected override void OnHit(Collider2D hit)
protected override void OnHit(Collision2D collision)
{
// Check if hit ground
if (((1 << hit.gameObject.layer) & groundLayer) != 0)
// If already sliding, count block destruction
if (isSliding)
{
Logging.Debug("[VacuumProjectile] Hit ground - starting slide");
StartSliding();
var block = collision.gameObject.GetComponent<Fort.FortBlock>();
if (block != null)
{
// Spawn impact effect on each block hit
SpawnImpactEffect(collision.contacts[0].point);
// Get damage from settings
var settings = GameManager.GetSettingsObject<AppleHills.Core.Settings.IFortFightSettings>();
float blockDamage = settings?.VacuumBlockDamage ?? 999f;
// Deal high damage to destroy block instantly
block.TakeDamage(blockDamage);
blocksDestroyed++;
Logging.Debug($"[VacuumProjectile] Destroyed block {blocksDestroyed}/{maxBlocksToDestroy}");
if (blocksDestroyed >= maxBlocksToDestroy)
{
Logging.Debug("[VacuumProjectile] Destroyed max blocks - stopping");
DestroyProjectile();
}
}
// Don't destroy - keep sliding
return;
}
// If hit wall or fort block, destroy immediately (handled by base class)
// First hit - spawn impact effect and start sliding
SpawnImpactEffect(collision.contacts[0].point);
Logging.Debug("[VacuumProjectile] Hit surface - starting slide");
StartSliding();
// Don't destroy - keep sliding!
}
/// <summary>
/// Start sliding behavior after hitting ground
/// Start sliding behavior after hitting surface
/// </summary>
private void StartSliding()
{
@@ -42,40 +61,44 @@ namespace Minigames.FortFight.Projectiles
isSliding = true;
// Disable gravity
if (rb2D != null)
// Get settings
var settings = GameManager.GetSettingsObject<AppleHills.Core.Settings.IFortFightSettings>();
if (settings != null)
{
rb2D.gravityScale = 0f;
// Set velocity to horizontal only (preserve direction)
Vector2 horizontalVelocity = new Vector2(rb2D.linearVelocity.x, 0f).normalized * slideSpeed;
rb2D.linearVelocity = horizontalVelocity;
Logging.Debug($"[VacuumProjectile] Sliding with velocity: {horizontalVelocity}");
maxBlocksToDestroy = settings.VacuumDestroyBlockCount;
}
// Destroy after slide duration
StartCoroutine(SlideCoroutine());
// Determine slide direction based on horizontal velocity (preserve launch direction)
if (rb2D != null)
{
slideDirection = rb2D.linearVelocity.x >= 0 ? Vector2.right : Vector2.left;
rb2D.gravityScale = 0f;
rb2D.linearVelocity = Vector2.zero; // Stop all momentum
Logging.Debug($"[VacuumProjectile] Started sliding in direction: {slideDirection}");
}
}
private IEnumerator SlideCoroutine()
private void FixedUpdate()
{
yield return new WaitForSeconds(slideDuration);
Logging.Debug("[VacuumProjectile] Slide duration ended - destroying");
DestroyProjectile();
if (isSliding && rb2D != null)
{
// Set constant velocity in slide direction
var settings = GameManager.GetSettingsObject<AppleHills.Core.Settings.IFortFightSettings>();
float slideSpeed = settings?.VacuumSlideSpeed ?? 10f;
rb2D.linearVelocity = slideDirection * slideSpeed;
}
}
/// <summary>
/// Override to NOT destroy immediately on ground hit
/// Clean up when destroyed
/// </summary>
protected override void DestroyProjectile()
{
// Only destroy if we're done sliding or hit a wall
if (!isSliding || rb2D.linearVelocity.magnitude < 1f)
{
base.DestroyProjectile();
}
isSliding = false;
base.DestroyProjectile();
}
}
}

View File

@@ -0,0 +1,252 @@
using Core;
using Core.Lifecycle;
using Minigames.FortFight.Core;
using Minigames.FortFight.Data;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace Minigames.FortFight.UI
{
/// <summary>
/// Generic reusable ammunition button that displays projectile data.
/// Shows icon, availability state, cooldown progress, and turns remaining.
/// </summary>
public class AmmoButton : ManagedBehaviour
{
#region Inspector References
[Header("UI Components")]
[Tooltip("Icon image for the projectile")]
[SerializeField] private Image iconImage;
[Tooltip("Background overlay that greys out the entire button when on cooldown")]
[SerializeField] private Image cooldownBackgroundImage;
[Tooltip("Radial fill overlay for cooldown visualization")]
[SerializeField] private Image cooldownFillImage;
[Tooltip("Text displaying turns remaining")]
[SerializeField] private TextMeshProUGUI turnsRemainingText;
[Tooltip("Button component")]
[SerializeField] private Button button;
[Tooltip("Visual indicator for selected state (optional border/glow)")]
[SerializeField] private GameObject selectedIndicator;
#endregion
#region State
private ProjectileConfig projectileConfig;
private AmmunitionManager ammunitionManager;
private SlingshotController slingshotController;
private int playerIndex;
private bool isSelected;
#endregion
#region Initialization
/// <summary>
/// Initialize the button with projectile config and system references.
/// Call this after instantiation to configure the button.
/// </summary>
public void Initialize(ProjectileConfig config, AmmunitionManager ammoManager, SlingshotController slingshot, int playerIdx)
{
projectileConfig = config;
ammunitionManager = ammoManager;
slingshotController = slingshot;
playerIndex = playerIdx;
// Setup UI from projectile config
if (iconImage != null && config.icon != null)
{
iconImage.sprite = config.icon;
}
// Setup cooldown background (hidden by default)
if (cooldownBackgroundImage != null)
{
cooldownBackgroundImage.gameObject.SetActive(false);
}
// Setup cooldown fill (hidden by default)
if (cooldownFillImage != null)
{
cooldownFillImage.fillAmount = 0f;
cooldownFillImage.type = Image.Type.Filled;
cooldownFillImage.fillMethod = Image.FillMethod.Radial360;
cooldownFillImage.fillOrigin = (int)Image.Origin360.Top;
cooldownFillImage.gameObject.SetActive(false);
}
// Setup turns text (hidden by default)
if (turnsRemainingText != null)
{
turnsRemainingText.gameObject.SetActive(false);
}
// Setup button
if (button != null)
{
button.onClick.AddListener(OnButtonClicked);
}
// Subscribe to ammunition events
if (ammunitionManager != null)
{
ammunitionManager.OnAmmoSelected += HandleAmmoSelected;
ammunitionManager.OnAmmoCooldownStarted += HandleCooldownStarted;
ammunitionManager.OnAmmoCooldownCompleted += HandleCooldownCompleted;
}
// Initial update
UpdateVisuals();
}
internal override void OnManagedDestroy()
{
base.OnManagedDestroy();
// Unsubscribe from events
if (ammunitionManager != null)
{
ammunitionManager.OnAmmoSelected -= HandleAmmoSelected;
ammunitionManager.OnAmmoCooldownStarted -= HandleCooldownStarted;
ammunitionManager.OnAmmoCooldownCompleted -= HandleCooldownCompleted;
}
// Remove button listener
if (button != null)
{
button.onClick.RemoveListener(OnButtonClicked);
}
}
#endregion
#region Update
private void Update()
{
// Update visuals every frame
UpdateVisuals();
}
/// <summary>
/// Update all visual elements based on current state
/// </summary>
private void UpdateVisuals()
{
if (projectileConfig == null || ammunitionManager == null) return;
// Get current cooldown state for this player
int turnsRemaining = ammunitionManager.GetCooldownRemaining(projectileConfig.projectileType, playerIndex);
bool isAvailable = ammunitionManager.IsAmmoAvailable(projectileConfig.projectileType, playerIndex);
bool onCooldown = turnsRemaining > 0;
// Show/hide cooldown background overlay
if (cooldownBackgroundImage != null)
{
cooldownBackgroundImage.gameObject.SetActive(onCooldown);
}
// Update cooldown fill (0 = no fill, 1 = full fill)
if (cooldownFillImage != null)
{
if (onCooldown && projectileConfig.cooldownTurns > 0)
{
float fillAmount = (float)turnsRemaining / projectileConfig.cooldownTurns;
cooldownFillImage.fillAmount = fillAmount;
cooldownFillImage.gameObject.SetActive(true);
}
else
{
cooldownFillImage.gameObject.SetActive(false);
}
}
// Update turns remaining text
if (turnsRemainingText != null)
{
if (onCooldown)
{
turnsRemainingText.text = turnsRemaining.ToString();
turnsRemainingText.gameObject.SetActive(true);
}
else
{
turnsRemainingText.gameObject.SetActive(false);
}
}
// Update button interactability
if (button != null)
{
button.interactable = isAvailable;
}
// Update selected indicator
if (selectedIndicator != null)
{
selectedIndicator.SetActive(isSelected);
}
}
#endregion
#region Button Click
/// <summary>
/// Called when button is clicked - selects this ammo type
/// </summary>
private void OnButtonClicked()
{
if (projectileConfig == null || ammunitionManager == null) return;
// Try to select this ammo type for this player
bool selected = ammunitionManager.SelectAmmo(projectileConfig.projectileType, playerIndex);
if (selected && slingshotController != null)
{
// Update slingshot with new ammo config
slingshotController.SetAmmo(projectileConfig);
Logging.Debug($"[AmmoButton] Player {playerIndex} selected {projectileConfig.displayName}");
}
}
#endregion
#region Event Handlers
private void HandleAmmoSelected(ProjectileType selectedType, int selectedPlayerIndex)
{
// Only update if this event is for our player
if (selectedPlayerIndex != playerIndex)
return;
// Update selected state - check if this is our player's current selection
isSelected = (selectedType == projectileConfig.projectileType);
}
private void HandleCooldownStarted(ProjectileType type, int cooldownTurns)
{
// Visual update handled in UpdateVisuals()
}
private void HandleCooldownCompleted(ProjectileType type)
{
// Visual update handled in UpdateVisuals()
if (type == projectileConfig.projectileType)
{
Logging.Debug($"[AmmoButton] {projectileConfig.displayName} ready!");
}
}
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d18726bad651464fbc4e49f8c95c0c37
timeCreated: 1764770308

View File

@@ -0,0 +1,171 @@
using Core;
using Core.Lifecycle;
using Minigames.FortFight.Core;
using Minigames.FortFight.Data;
using UnityEngine;
namespace Minigames.FortFight.UI
{
/// <summary>
/// Manages ammunition UI panel for a specific player.
/// Shows/hides based on turn state and initializes buttons with player context.
/// </summary>
public class AmmunitionPanel : ManagedBehaviour
{
#region Inspector References
[Header("Player Configuration")]
[Tooltip("Which player this panel belongs to (0 = Player 1, 1 = Player 2)")]
[SerializeField] private int playerIndex = 0;
[Header("References")]
[Tooltip("Ammunition manager (shared between both players)")]
[SerializeField] private AmmunitionManager ammunitionManager;
[Tooltip("This player's slingshot controller")]
[SerializeField] private SlingshotController slingshotController;
[Tooltip("Turn manager to subscribe to turn events")]
[SerializeField] private TurnManager turnManager;
[Header("UI")]
[Tooltip("Array of ammo buttons in this panel")]
[SerializeField] private AmmoButton[] ammoButtons;
[Tooltip("Root GameObject to show/hide entire panel")]
[SerializeField] private GameObject panelRoot;
#endregion
#region Initialization
internal override void OnManagedAwake()
{
base.OnManagedAwake();
// Validate references
if (ammunitionManager == null)
{
Logging.Error($"[AmmunitionPanel] Player {playerIndex}: Ammunition manager not assigned!");
}
if (slingshotController == null)
{
Logging.Error($"[AmmunitionPanel] Player {playerIndex}: Slingshot controller not assigned!");
}
if (turnManager == null)
{
Logging.Error($"[AmmunitionPanel] Player {playerIndex}: Turn manager not assigned!");
}
if (ammoButtons == null || ammoButtons.Length == 0)
{
Logging.Warning($"[AmmunitionPanel] Player {playerIndex}: No ammo buttons assigned!");
}
// Use assigned panelRoot or fall back to this GameObject
if (panelRoot == null)
{
panelRoot = gameObject;
}
}
internal override void OnManagedStart()
{
base.OnManagedStart();
// Initialize ammo buttons with player context
InitializeButtons();
// Subscribe to turn events
if (turnManager != null)
{
turnManager.OnTurnStarted += HandleTurnStarted;
}
// Start hidden
SetPanelVisibility(false);
}
internal override void OnManagedDestroy()
{
base.OnManagedDestroy();
// Unsubscribe from events
if (turnManager != null)
{
turnManager.OnTurnStarted -= HandleTurnStarted;
}
}
/// <summary>
/// Initialize all ammo buttons with player-specific configuration
/// </summary>
private void InitializeButtons()
{
if (ammunitionManager == null || slingshotController == null || ammoButtons == null)
{
return;
}
// Get available projectile types from settings
var availableTypes = ammunitionManager.GetAvailableProjectileTypes();
var settings = GameManager.GetSettingsObject<AppleHills.Core.Settings.IFortFightSettings>();
if (settings == null)
{
Logging.Error($"[AmmunitionPanel] Player {playerIndex}: Could not get FortFightSettings!");
return;
}
for (int i = 0; i < ammoButtons.Length && i < availableTypes.Count; i++)
{
if (ammoButtons[i] != null)
{
var config = settings.GetProjectileConfig(availableTypes[i]);
if (config != null)
{
ammoButtons[i].Initialize(config, ammunitionManager, slingshotController, playerIndex);
Logging.Debug($"[AmmunitionPanel] Player {playerIndex}: Initialized button for {config.displayName}");
}
}
}
}
#endregion
#region Turn Events
/// <summary>
/// Called when any player's turn starts - show/hide panel accordingly
/// </summary>
private void HandleTurnStarted(PlayerData player, TurnState turnState)
{
// Only show panel when it's this player's turn (not during transitions)
bool shouldShow = player.PlayerIndex == playerIndex &&
(turnState == TurnState.PlayerOneTurn || turnState == TurnState.PlayerTwoTurn);
SetPanelVisibility(shouldShow);
if (shouldShow)
{
Logging.Debug($"[AmmunitionPanel] Showing panel for Player {playerIndex}");
}
}
/// <summary>
/// Show or hide the entire panel
/// </summary>
private void SetPanelVisibility(bool visible)
{
if (panelRoot != null)
{
panelRoot.SetActive(visible);
}
}
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1963617e4d104c199c3a66d671b8d8a2
timeCreated: 1764771029

View File

@@ -11,15 +11,13 @@ namespace Minigames.FortFight.UI
{
/// <summary>
/// Main gameplay UI page for Fort Fight minigame.
/// Displays turn info and allows player to take actions (stubbed for Phase 1).
/// Displays turn info. Turn actions now handled via slingshot input system.
/// </summary>
public class GameplayPage : UIPage
{
[Header("UI Elements")]
[SerializeField] private TextMeshProUGUI turnIndicatorText;
[SerializeField] private TextMeshProUGUI currentPlayerText;
[SerializeField] private Button takeActionButton;
[SerializeField] private TextMeshProUGUI actionButtonText;
[Header("Optional Visual Elements")]
[SerializeField] private CanvasGroup canvasGroup;
@@ -37,11 +35,7 @@ namespace Minigames.FortFight.UI
// Validate references
ValidateReferences();
// Set up button
if (takeActionButton != null)
{
takeActionButton.onClick.AddListener(OnTakeActionClicked);
}
// Note: takeActionButton is no longer used - turns handled via slingshot input
// Set up canvas group
if (canvasGroup == null)
@@ -55,7 +49,7 @@ namespace Minigames.FortFight.UI
base.OnManagedStart();
// Get turn manager reference
turnManager = FindObjectOfType<TurnManager>();
turnManager = FindFirstObjectByType<TurnManager>();
if (turnManager != null)
{
@@ -80,15 +74,8 @@ namespace Minigames.FortFight.UI
Logging.Warning("[GameplayPage] Current player text not assigned!");
}
if (takeActionButton == null)
{
Logging.Error("[GameplayPage] Take action button not assigned!");
}
if (actionButtonText == null)
{
Logging.Warning("[GameplayPage] Action button text not assigned!");
}
// Note: takeActionButton and actionButtonText are no longer used
// Turns are now handled automatically via slingshot input system
}
#endregion
@@ -147,11 +134,6 @@ namespace Minigames.FortFight.UI
{
aiTurnPanel.SetActive(true);
}
if (takeActionButton != null)
{
takeActionButton.gameObject.SetActive(false);
}
}
else if (turnState == TurnState.PlayerOneTurn || turnState == TurnState.PlayerTwoTurn)
{
@@ -165,48 +147,11 @@ namespace Minigames.FortFight.UI
{
aiTurnPanel.SetActive(false);
}
if (takeActionButton != null)
{
takeActionButton.gameObject.SetActive(true);
}
if (actionButtonText != null)
{
actionButtonText.text = "Take Action (Stubbed)";
}
}
}
#endregion
#region Button Callbacks
/// <summary>
/// Called when player clicks the "Take Action" button
/// STUBBED for Phase 1 - just logs and ends turn
/// </summary>
private void OnTakeActionClicked()
{
if (turnManager == null)
{
Logging.Error("[GameplayPage] Cannot take action - TurnManager not found!");
return;
}
PlayerData currentPlayer = turnManager.CurrentPlayer;
// STUBBED: Log the action
Logging.Debug($"[GameplayPage] {currentPlayer.PlayerName} takes action! (STUBBED - no actual combat yet)");
// TODO Phase 3: Replace with actual slingshot/shooting interface
// End the turn
turnManager.EndTurn();
}
#endregion
#region Transitions
protected override void DoTransitionIn(System.Action onComplete)
@@ -252,12 +197,6 @@ namespace Minigames.FortFight.UI
turnManager.OnTurnStarted -= OnTurnStarted;
turnManager.OnTurnEnded -= OnTurnEnded;
}
// Unsubscribe from button
if (takeActionButton != null)
{
takeActionButton.onClick.RemoveListener(OnTakeActionClicked);
}
}
#endregion

View File

@@ -36,5 +36,58 @@ MonoBehaviour:
weakPointExplosionDamage: 50
weakPointExplosionForce: 50
fortDefeatThreshold: 0.3
physicsGravityScale: 1
blockGravityScale: 2
projectileGravityScale: 1
projectileSettleDelay: 2.5
turnTransitionDelay: 1.5
projectileConfigs:
- projectileType: 0
projectileId: toaster
prefab: {fileID: 4820392328973485589, guid: a4b194a56edefa541b7c3bd7d70c8ba5, type: 3}
cooldownTurns: 0
icon: {fileID: 6674386295937086461, guid: 3bd1c178a78fcd144965cd1731dc309b, type: 3}
displayName: Toaster
description:
damage: 20
mass: 5
- projectileType: 1
projectileId: vacuum
prefab: {fileID: 4015519405310386481, guid: 4ffc718ecbe281041bc8354567f6e940, type: 3}
cooldownTurns: 3
icon: {fileID: 3452003437791708593, guid: 4c13556eeb918624c9dd3d7e4086242e, type: 3}
displayName: Vacuum
description:
damage: 20
mass: 10
- projectileType: 2
projectileId: ceilingfan
prefab: {fileID: 4342087378442690536, guid: ff8b62fb437256043aa6bd0b5441316b, type: 3}
cooldownTurns: 2
icon: {fileID: -765527507412255412, guid: f70246e6148769846aaea223ec0c2a55, type: 3}
displayName: CeillingFan
description:
damage: 20
mass: 3
- projectileType: 3
projectileId: trashbag
prefab: {fileID: 4015519405310386481, guid: 177c683542fd63a4a9d7e7ecacea596f, type: 3}
cooldownTurns: 3
icon: {fileID: 8766740682603709380, guid: b0a0abcb5fec95649b581307eca6a444, type: 3}
displayName: TrashBag
description:
damage: 20
mass: 5
vacuumSlideForce: 15
vacuumDestroyBlockCount: 2
vacuumBlockDamage: 999
trashBagPieceCount: 5
trashBagPieceForce: 10
trashBagSpreadAngle: 60
ceilingFanActivationDelay: 1
baseLaunchForce: 150
minForceMultiplier: 0.1
maxForceMultiplier: 1
trajectoryLockDuration: 2
fortBlockLayer: 16
projectileLayer: 15
damageColorTint: {r: 1, g: 0, b: 0, a: 1}

View File

@@ -53,4 +53,4 @@ Physics2DSettings:
m_ReuseCollisionCallbacks: 1
m_AutoSyncTransforms: 0
m_GizmoOptions: 10
m_LayerCollisionMatrix: fffffffffffffffffffffffffffffffffffffffffffffffffffefffffff8ffff3ffbffff7fffffff7ffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
m_LayerCollisionMatrix: ff7ffeffff7ffeffff7ffeffffffffffff7ffeffff7ffeffff7efeffff78feff3f7bfeff7f7ffeff7f7efeffff7ffeffff7ffeffff7ffeffffffffff0840ffff08c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

View File

@@ -26,9 +26,9 @@ TagManager:
- QuarryObstacle
- QuarryMonster
- QuarryTrenchTile
-
-
-
- FortFight_Ground
- FortFight_Projectile
- FortFight_Block
-
-
-