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