From 2614dab342b0ffeb368ad5058447915a39381e70 Mon Sep 17 00:00:00 2001 From: GanX <2423855310@qq.com> Date: Sat, 18 Oct 2025 10:06:12 +0800 Subject: [PATCH] =?UTF-8?q?feat(TimeCountDown):=20=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=80=92=E8=AE=A1=E6=97=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Prefab/Core/GameCountDownManager.prefab | 54 +++++ .../Core/GameCountDownManager.prefab.meta | 7 + Assets/Prefab/Core/GameFlowManager.prefab | 46 ++++ .../Prefab/Core/GameFlowManager.prefab.meta | 7 + Assets/Scenes/Core.unity | 69 ------ Assets/Scenes/Level1.unity | 207 ++++++++++++++++++ Assets/Scenes/UIScene.unity | 94 ++++++++ Assets/Script/Core/Core.asmdef | 3 +- Assets/Script/Core/UniTimer.cs | 108 +++++++++ Assets/Script/Core/UniTimer.cs.meta | 3 + .../Gameplay/Global/GameCountdownManager.cs | 89 ++++++++ .../Global/GameCountdownManager.cs.meta | 3 + .../Script/Gameplay/Global/GameFlowManager.cs | 24 ++ .../Gameplay/Global/GameFlowManager.cs.meta | 3 + .../Script/Gameplay/UI/GameCountDownViewer.cs | 37 ++++ .../Gameplay/UI/GameCountDownViewer.cs.meta | 3 + 16 files changed, 687 insertions(+), 70 deletions(-) create mode 100644 Assets/Prefab/Core/GameCountDownManager.prefab create mode 100644 Assets/Prefab/Core/GameCountDownManager.prefab.meta create mode 100644 Assets/Prefab/Core/GameFlowManager.prefab create mode 100644 Assets/Prefab/Core/GameFlowManager.prefab.meta create mode 100644 Assets/Script/Core/UniTimer.cs create mode 100644 Assets/Script/Core/UniTimer.cs.meta create mode 100644 Assets/Script/Gameplay/Global/GameCountdownManager.cs create mode 100644 Assets/Script/Gameplay/Global/GameCountdownManager.cs.meta create mode 100644 Assets/Script/Gameplay/Global/GameFlowManager.cs create mode 100644 Assets/Script/Gameplay/Global/GameFlowManager.cs.meta create mode 100644 Assets/Script/Gameplay/UI/GameCountDownViewer.cs create mode 100644 Assets/Script/Gameplay/UI/GameCountDownViewer.cs.meta diff --git a/Assets/Prefab/Core/GameCountDownManager.prefab b/Assets/Prefab/Core/GameCountDownManager.prefab new file mode 100644 index 0000000..c4785a9 --- /dev/null +++ b/Assets/Prefab/Core/GameCountDownManager.prefab @@ -0,0 +1,54 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &3918776012077598679 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4952453861214115371} + - component: {fileID: 593212677835339430} + m_Layer: 0 + m_Name: GameCountDownManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4952453861214115371 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3918776012077598679} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 829.4015, y: 383.09033, z: 3.2512481} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &593212677835339430 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3918776012077598679} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: bdaad0392e5549f0ac761238b649cc70, type: 3} + m_Name: + m_EditorClassIdentifier: + defaultDuration: 60 + useUnscaledTime: 0 + OnTick: + m_PersistentCalls: + m_Calls: [] + OnFinish: + m_PersistentCalls: + m_Calls: [] diff --git a/Assets/Prefab/Core/GameCountDownManager.prefab.meta b/Assets/Prefab/Core/GameCountDownManager.prefab.meta new file mode 100644 index 0000000..15d9b48 --- /dev/null +++ b/Assets/Prefab/Core/GameCountDownManager.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9e2e93bf07726014bac5a458c32e697f +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefab/Core/GameFlowManager.prefab b/Assets/Prefab/Core/GameFlowManager.prefab new file mode 100644 index 0000000..5a3b022 --- /dev/null +++ b/Assets/Prefab/Core/GameFlowManager.prefab @@ -0,0 +1,46 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &2130934091406547798 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8520498794796434433} + - component: {fileID: 3291481944912255915} + m_Layer: 0 + m_Name: GameFlowManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8520498794796434433 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2130934091406547798} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 829.4015, y: 383.09033, z: 3.2512481} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &3291481944912255915 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2130934091406547798} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8ff98d4d16514d27a14dc271bbbd19e7, type: 3} + m_Name: + m_EditorClassIdentifier: diff --git a/Assets/Prefab/Core/GameFlowManager.prefab.meta b/Assets/Prefab/Core/GameFlowManager.prefab.meta new file mode 100644 index 0000000..5c38160 --- /dev/null +++ b/Assets/Prefab/Core/GameFlowManager.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f480e7d630901ad48a69a5df6d2132f2 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/Core.unity b/Assets/Scenes/Core.unity index fd2610f..c7a5ba4 100644 --- a/Assets/Scenes/Core.unity +++ b/Assets/Scenes/Core.unity @@ -258,78 +258,9 @@ PrefabInstance: m_AddedGameObjects: [] m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 03010dd3d718e374098805a9faf408ba, type: 3} ---- !u!1001 &9054644576683853387 -PrefabInstance: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_Modification: - serializedVersion: 3 - m_TransformParent: {fileID: 0} - m_Modifications: - - target: {fileID: 5532734616494925005, guid: 781c629235eee4f4eb34f1e763aa7f67, - type: 3} - propertyPath: m_Name - value: TimePauseManager - objectReference: {fileID: 0} - - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, - type: 3} - propertyPath: m_LocalPosition.x - value: 0.29564962 - objectReference: {fileID: 0} - - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, - type: 3} - propertyPath: m_LocalPosition.y - value: 4.269477 - objectReference: {fileID: 0} - - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, - type: 3} - propertyPath: m_LocalPosition.z - value: -1.7842796 - objectReference: {fileID: 0} - - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, - type: 3} - propertyPath: m_LocalRotation.w - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, - type: 3} - propertyPath: m_LocalRotation.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, - type: 3} - propertyPath: m_LocalRotation.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, - type: 3} - propertyPath: m_LocalRotation.z - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, - type: 3} - propertyPath: m_LocalEulerAnglesHint.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, - type: 3} - propertyPath: m_LocalEulerAnglesHint.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, - type: 3} - propertyPath: m_LocalEulerAnglesHint.z - value: 0 - objectReference: {fileID: 0} - m_RemovedComponents: [] - m_RemovedGameObjects: [] - m_AddedGameObjects: [] - m_AddedComponents: [] - m_SourcePrefab: {fileID: 100100000, guid: 781c629235eee4f4eb34f1e763aa7f67, type: 3} --- !u!1660057539 &9223372036854775807 SceneRoots: m_ObjectHideFlags: 0 m_Roots: - {fileID: 6429745761262824323} - {fileID: 6277645971226662819} - - {fileID: 9054644576683853387} diff --git a/Assets/Scenes/Level1.unity b/Assets/Scenes/Level1.unity index 2546cbb..46f7e52 100644 --- a/Assets/Scenes/Level1.unity +++ b/Assets/Scenes/Level1.unity @@ -367,6 +367,74 @@ MonoBehaviour: m_EditorClassIdentifier: Interactable: 1 lockLevel: 0 +--- !u!1001 &769057572 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 3918776012077598679, guid: 9e2e93bf07726014bac5a458c32e697f, + type: 3} + propertyPath: m_Name + value: GameCountDownManager + objectReference: {fileID: 0} + - target: {fileID: 4952453861214115371, guid: 9e2e93bf07726014bac5a458c32e697f, + type: 3} + propertyPath: m_LocalPosition.x + value: 829.4015 + objectReference: {fileID: 0} + - target: {fileID: 4952453861214115371, guid: 9e2e93bf07726014bac5a458c32e697f, + type: 3} + propertyPath: m_LocalPosition.y + value: 383.09033 + objectReference: {fileID: 0} + - target: {fileID: 4952453861214115371, guid: 9e2e93bf07726014bac5a458c32e697f, + type: 3} + propertyPath: m_LocalPosition.z + value: 3.2512481 + objectReference: {fileID: 0} + - target: {fileID: 4952453861214115371, guid: 9e2e93bf07726014bac5a458c32e697f, + type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 4952453861214115371, guid: 9e2e93bf07726014bac5a458c32e697f, + type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4952453861214115371, guid: 9e2e93bf07726014bac5a458c32e697f, + type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4952453861214115371, guid: 9e2e93bf07726014bac5a458c32e697f, + type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4952453861214115371, guid: 9e2e93bf07726014bac5a458c32e697f, + type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4952453861214115371, guid: 9e2e93bf07726014bac5a458c32e697f, + type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4952453861214115371, guid: 9e2e93bf07726014bac5a458c32e697f, + type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: 9e2e93bf07726014bac5a458c32e697f, type: 3} --- !u!1 &856668955 GameObject: m_ObjectHideFlags: 0 @@ -683,6 +751,74 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1001 &1279118200 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 2130934091406547798, guid: f480e7d630901ad48a69a5df6d2132f2, + type: 3} + propertyPath: m_Name + value: GameFlowManager + objectReference: {fileID: 0} + - target: {fileID: 8520498794796434433, guid: f480e7d630901ad48a69a5df6d2132f2, + type: 3} + propertyPath: m_LocalPosition.x + value: 829.4015 + objectReference: {fileID: 0} + - target: {fileID: 8520498794796434433, guid: f480e7d630901ad48a69a5df6d2132f2, + type: 3} + propertyPath: m_LocalPosition.y + value: 383.09033 + objectReference: {fileID: 0} + - target: {fileID: 8520498794796434433, guid: f480e7d630901ad48a69a5df6d2132f2, + type: 3} + propertyPath: m_LocalPosition.z + value: 3.2512481 + objectReference: {fileID: 0} + - target: {fileID: 8520498794796434433, guid: f480e7d630901ad48a69a5df6d2132f2, + type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 8520498794796434433, guid: f480e7d630901ad48a69a5df6d2132f2, + type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8520498794796434433, guid: f480e7d630901ad48a69a5df6d2132f2, + type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8520498794796434433, guid: f480e7d630901ad48a69a5df6d2132f2, + type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8520498794796434433, guid: f480e7d630901ad48a69a5df6d2132f2, + type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8520498794796434433, guid: f480e7d630901ad48a69a5df6d2132f2, + type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8520498794796434433, guid: f480e7d630901ad48a69a5df6d2132f2, + type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: f480e7d630901ad48a69a5df6d2132f2, type: 3} --- !u!1 &1304919964 GameObject: m_ObjectHideFlags: 0 @@ -788,6 +924,74 @@ MeshFilter: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1304919964} m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1001 &1532480746 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 5532734616494925005, guid: 781c629235eee4f4eb34f1e763aa7f67, + type: 3} + propertyPath: m_Name + value: TimePauseManager + objectReference: {fileID: 0} + - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, + type: 3} + propertyPath: m_LocalPosition.x + value: 0.29564962 + objectReference: {fileID: 0} + - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, + type: 3} + propertyPath: m_LocalPosition.y + value: 4.269477 + objectReference: {fileID: 0} + - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, + type: 3} + propertyPath: m_LocalPosition.z + value: -1.7842796 + objectReference: {fileID: 0} + - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, + type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, + type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, + type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, + type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, + type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, + type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6144181697203329678, guid: 781c629235eee4f4eb34f1e763aa7f67, + type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: 781c629235eee4f4eb34f1e763aa7f67, type: 3} --- !u!1 &1553269948 GameObject: m_ObjectHideFlags: 0 @@ -1190,6 +1394,9 @@ PrefabInstance: SceneRoots: m_ObjectHideFlags: 0 m_Roots: + - {fileID: 1532480746} + - {fileID: 1279118200} + - {fileID: 769057572} - {fileID: 410087041} - {fileID: 1274249804} - {fileID: 7020889523296792185} diff --git a/Assets/Scenes/UIScene.unity b/Assets/Scenes/UIScene.unity index efd1120..564ac8d 100644 --- a/Assets/Scenes/UIScene.unity +++ b/Assets/Scenes/UIScene.unity @@ -598,6 +598,99 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1200522801} m_CullTransparentMesh: 1 +--- !u!1 &1349586404 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1349586405} + - component: {fileID: 1349586408} + - component: {fileID: 1349586407} + - component: {fileID: 1349586409} + m_Layer: 5 + m_Name: CounDown + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1349586405 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1349586404} + 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: 1780593834} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 1} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 9.5458, y: -66} + m_SizeDelta: {x: 595.9615, y: 81.3619} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1349586407 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1349586404} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, 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_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 50 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 5 + m_MaxSize: 50 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: "\u5012\u8BA1\u65F6\uFF1A" +--- !u!222 &1349586408 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1349586404} + m_CullTransparentMesh: 1 +--- !u!114 &1349586409 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1349586404} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1aa400ea9061498897f3c03b0336cfda, type: 3} + m_Name: + m_EditorClassIdentifier: + countdownText: {fileID: 1349586407} --- !u!1 &1780593830 GameObject: m_ObjectHideFlags: 0 @@ -695,6 +788,7 @@ RectTransform: m_Children: - {fileID: 1200522802} - {fileID: 257151345} + - {fileID: 1349586405} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} diff --git a/Assets/Script/Core/Core.asmdef b/Assets/Script/Core/Core.asmdef index 22fbf72..354f4b3 100644 --- a/Assets/Script/Core/Core.asmdef +++ b/Assets/Script/Core/Core.asmdef @@ -2,7 +2,8 @@ "name": "Core", "rootNamespace": "", "references": [ - "GUID:75469ad4d38634e559750d17036d5f7c" + "GUID:75469ad4d38634e559750d17036d5f7c", + "GUID:f51ebe6a0ceec4240a699833d6309b23" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Assets/Script/Core/UniTimer.cs b/Assets/Script/Core/UniTimer.cs new file mode 100644 index 0000000..67e947c --- /dev/null +++ b/Assets/Script/Core/UniTimer.cs @@ -0,0 +1,108 @@ +using System; +using System.Threading; +using Cysharp.Threading.Tasks; +using UnityEngine; + +namespace Core +{ + /// + /// 通用计时器(正计时 / 倒计时均可) + /// 全程 UniTask,无 GC,支持暂停、继续、提前终止 + /// + public sealed class UniTimer + { + public float Duration { get; private set; } + public float Elapsed { get; private set; } + public float Remaining => Mathf.Max(0, Duration - Elapsed); + + public bool IsRunning { get; private set; } + public bool IsPaused { get; private set; } + + /// 每帧回调:参数为当前已走时间 + public event Action OnTick; + + /// 计时结束回调 + public event Action OnComplete; + + private CancellationTokenSource _cts; + + private UniTaskCompletionSource _taskSource; + + /*------------------------------------------------------*/ + /// + /// 开始计时 + /// + /// 时长(秒) + /// true=倒计时;false=正计时 + /// 可选:每帧刷新 + /// 可选:结束回调 + public UniTask StartAsync(float duration, + bool isCountDown = false, + Action onTick = null, + Action onComplete = null) + { + Stop(); // 先清理旧任务 + _taskSource = new UniTaskCompletionSource(); // 新建 + Duration = duration; + Elapsed = isCountDown ? duration : 0f; + OnTick = onTick; + OnComplete = onComplete; + IsRunning = true; + IsPaused = false; + _cts = new CancellationTokenSource(); + + return RunAsync(_cts.Token, isCountDown); + } + + /// 立即终止(不可恢复) + public void Stop() + { + if (!IsRunning) return; + _cts?.Cancel(); + _cts?.Dispose(); + _cts = null; + IsRunning = false; + _taskSource?.TrySetCanceled(); // 提前终止也通知 + IsPaused = false; + } + + /// 暂停 + public void Pause() => IsPaused = true; + + /// 继续 + public void Resume() => IsPaused = false; + + /*------------------------------------------------------*/ + private async UniTask RunAsync(System.Threading.CancellationToken token, bool countDown) + { + while (!token.IsCancellationRequested) + { + if (!IsPaused) + { + float dt = Time.deltaTime; + Elapsed += countDown ? -dt : dt; + + // 触发回调 + OnTick?.Invoke(Elapsed); + + // 结束条件 + if (countDown ? Elapsed <= 0f : Elapsed >= Duration) + { + Elapsed = countDown ? 0f : Duration; + OnTick?.Invoke(Elapsed); // 最后再给一次精确值 + break; + } + } + + await UniTask.Yield(PlayerLoopTiming.Update, token); + } + + IsRunning = false; + _taskSource?.TrySetResult(true); // 广播“结束” + if (!token.IsCancellationRequested) + OnComplete?.Invoke(); + } + + public UniTask WaitForFinishAsync() => _taskSource?.Task ?? UniTask.CompletedTask; + } +} \ No newline at end of file diff --git a/Assets/Script/Core/UniTimer.cs.meta b/Assets/Script/Core/UniTimer.cs.meta new file mode 100644 index 0000000..3104a28 --- /dev/null +++ b/Assets/Script/Core/UniTimer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7ddb70eec4a545f29d26f24f8370baae +timeCreated: 1760751050 \ No newline at end of file diff --git a/Assets/Script/Gameplay/Global/GameCountdownManager.cs b/Assets/Script/Gameplay/Global/GameCountdownManager.cs new file mode 100644 index 0000000..29dcd4d --- /dev/null +++ b/Assets/Script/Gameplay/Global/GameCountdownManager.cs @@ -0,0 +1,89 @@ +using System; +using Cysharp.Threading.Tasks; +using UnityEngine; +using UnityEngine.Events; +using Core; + +namespace Script.Gameplay.Global +{ + /// + /// 全局关卡倒计时管理器(UniTimer 版) + /// + public sealed class GameCountdownManager : MonoSingleton + { + + [Header("默认关卡时长(秒)")] [SerializeField] private float defaultDuration = 60f; + + [Header("是否受 Time.timeScale 影响")] [SerializeField] + private bool useUnscaledTime = false; + + [Header("事件:每秒刷新(剩余秒数)")] public UnityEvent OnTick; + + [Header("事件:倒计时结束")] public UnityEvent OnFinish; + + private UniTimer _timer = new UniTimer(); + + /*------------------------------------------------------*/ + protected override void Awake() + { + base.Awake(); + // 确保事件实例化,避免其他脚本订阅时报 NullReferenceException + OnTick ??= new UnityEvent(); + OnFinish ??= new UnityEvent(); + } + + /// + /// 启动关卡倒计时(默认时长) + /// + public UniTask StartLevelTimer() => StartLevelTimer(defaultDuration); + + /// + /// 启动关卡倒计时(指定时长) + /// + /// 秒 + public UniTask StartLevelTimer(float duration) + { + StopTimer(); // 先清掉旧计时器 + + // 用 unscaledDeltaTime 就不受 Time.timeScale 影响 + Time.timeScale = 1f; // 可根据需求保留或去掉 + return _timer.StartAsync( + duration, + isCountDown: true, + onTick: left => { OnTick?.Invoke(left); }, + onComplete: () => + { + OnFinish?.Invoke(); + // 这里可以统一处理“时间到”逻辑 + TimeOutHandle(); + }); + } + + /// 暂停 + public void Pause() => _timer.Pause(); + + /// 继续 + public void Resume() => _timer.Resume(); + + /// 立即结束并触发 OnFinish + public void StopTimer() => _timer.Stop(); + + /// 剩余时间(秒) + public float Remaining => _timer.Remaining; + + /// 是否正在跑 + public bool IsRunning => _timer.IsRunning; + + /*------------------------------------------------------*/ + // 统一处理“时间到” + private void TimeOutHandle() + { + Debug.Log("[GameCountdown] 关卡时间到!"); + // 可以在这里弹 UI、播放音效、加载结算场景等 + } + + /*------------------------------------------------------*/ + // 方便外部 await 等待结束 + public UniTask WaitForTimeOutAsync() => _timer.WaitForFinishAsync(); + } +} \ No newline at end of file diff --git a/Assets/Script/Gameplay/Global/GameCountdownManager.cs.meta b/Assets/Script/Gameplay/Global/GameCountdownManager.cs.meta new file mode 100644 index 0000000..a56cc16 --- /dev/null +++ b/Assets/Script/Gameplay/Global/GameCountdownManager.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: bdaad0392e5549f0ac761238b649cc70 +timeCreated: 1760751427 \ No newline at end of file diff --git a/Assets/Script/Gameplay/Global/GameFlowManager.cs b/Assets/Script/Gameplay/Global/GameFlowManager.cs new file mode 100644 index 0000000..cf8c79c --- /dev/null +++ b/Assets/Script/Gameplay/Global/GameFlowManager.cs @@ -0,0 +1,24 @@ +using System; +using Core; +using UnityEngine; + +namespace Script.Gameplay.Global +{ + public enum GameState + { + Boot, // 初始化 + MainMenu, // 主菜单 + Playing, // 游戏中 + Paused, // 暂停 + GameOver, // 游戏结束 + Victory // 胜利 + } + + public class GameFlowManager : MonoSingleton + { + private void Start() + { + GameCountdownManager.Instance.StartLevelTimer(); + } + } +} \ No newline at end of file diff --git a/Assets/Script/Gameplay/Global/GameFlowManager.cs.meta b/Assets/Script/Gameplay/Global/GameFlowManager.cs.meta new file mode 100644 index 0000000..06a52d9 --- /dev/null +++ b/Assets/Script/Gameplay/Global/GameFlowManager.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8ff98d4d16514d27a14dc271bbbd19e7 +timeCreated: 1760752445 \ No newline at end of file diff --git a/Assets/Script/Gameplay/UI/GameCountDownViewer.cs b/Assets/Script/Gameplay/UI/GameCountDownViewer.cs new file mode 100644 index 0000000..a75e72c --- /dev/null +++ b/Assets/Script/Gameplay/UI/GameCountDownViewer.cs @@ -0,0 +1,37 @@ +using System; +using UnityEngine; +using UnityEngine.UI; +using Script.Gameplay.Global; +namespace UI +{ + public class GameCountDownViewer : MonoBehaviour + { + public Text countdownText; + private GameCountdownManager _countdownManager; + + private void Start() + { + _countdownManager = GameCountdownManager.Instance; + if (_countdownManager != null) + { + _countdownManager.OnTick.AddListener(UpdateCountdown); + } + } + public void UpdateCountdown(float secondsLeft) + { + if (countdownText != null) + { + int seconds = Mathf.CeilToInt(secondsLeft); + countdownText.text = "倒计时: " + seconds.ToString(); + } + } + + private void OnDestroy() + { + if (_countdownManager != null) + { + _countdownManager.OnTick.RemoveListener(UpdateCountdown); + } + } + } +} \ No newline at end of file diff --git a/Assets/Script/Gameplay/UI/GameCountDownViewer.cs.meta b/Assets/Script/Gameplay/UI/GameCountDownViewer.cs.meta new file mode 100644 index 0000000..f525e22 --- /dev/null +++ b/Assets/Script/Gameplay/UI/GameCountDownViewer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1aa400ea9061498897f3c03b0336cfda +timeCreated: 1760751782 \ No newline at end of file