Level 1 according to waves
This commit is contained in:
parent
d096c20cf5
commit
204d25f657
@ -45650,24 +45650,6 @@ Transform:
|
||||
type: 3}
|
||||
m_PrefabInstance: {fileID: 268364652}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &269148361 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 385312391933029727, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
m_PrefabInstance: {fileID: 447491950}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 9de313fb3f367d04bbd130657183cdc8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!4 &269148367 stripped
|
||||
Transform:
|
||||
m_CorrespondingSourceObject: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
m_PrefabInstance: {fileID: 447491950}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!1 &270497163
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -69347,99 +69329,6 @@ MeshFilter:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 446839706}
|
||||
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!1001 &447491950
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 481936153}
|
||||
m_Modifications:
|
||||
- target: {fileID: 3951388154437428790, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: enableRegen
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4006626876238256025, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Enemy (1)
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4006626876238256025, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_IsActive
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalScale.x
|
||||
value: 0.05879492
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalScale.y
|
||||
value: 0.43239498
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalScale.z
|
||||
value: 0.06264454
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: -0.103
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0.16271059
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: -0.274
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: a205c5f30032031428dae83c4a2f2af8, type: 3}
|
||||
--- !u!1001 &447901445
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -74744,12 +74633,9 @@ Transform:
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 17.00827, y: 2.3127, z: 15.96308}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 1806068479}
|
||||
- {fileID: 269148367}
|
||||
- {fileID: 2008455231}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1078692958}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &483243085
|
||||
@ -168780,8 +168666,9 @@ GameObject:
|
||||
m_Component:
|
||||
- component: {fileID: 1078692958}
|
||||
- component: {fileID: 1078692957}
|
||||
- component: {fileID: 1078692959}
|
||||
m_Layer: 0
|
||||
m_Name: GameObject
|
||||
m_Name: Level 1
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
@ -168799,11 +168686,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 42850bd66917c2648a04c287cd0fa78f, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
enemiesParent: {fileID: 481936153}
|
||||
enemies:
|
||||
- {fileID: 1806068473}
|
||||
- {fileID: 269148361}
|
||||
- {fileID: 2008455225}
|
||||
spawner: {fileID: 1078692959}
|
||||
checkInterval: 0.25
|
||||
--- !u!4 &1078692958
|
||||
Transform:
|
||||
@ -168821,6 +168704,30 @@ Transform:
|
||||
- {fileID: 481936153}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &1078692959
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1078692956}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 9274e1d861dffcc4f828e772e0d685d2, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
waves:
|
||||
- enemyPrefab: {fileID: 4006626876238256025, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
count: 2
|
||||
spawnRate: 5
|
||||
- enemyPrefab: {fileID: 4006626876238256025, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
count: 3
|
||||
spawnRate: 2
|
||||
spawnPoint: {fileID: 481936153}
|
||||
containerParent: {fileID: 481936153}
|
||||
timeBetweenWaves: 10
|
||||
--- !u!1001 &1080331081
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -301654,24 +301561,6 @@ Transform:
|
||||
type: 3}
|
||||
m_PrefabInstance: {fileID: 1805929970}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &1806068473 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 385312391933029727, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
m_PrefabInstance: {fileID: 1527259665985799113}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 9de313fb3f367d04bbd130657183cdc8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!4 &1806068479 stripped
|
||||
Transform:
|
||||
m_CorrespondingSourceObject: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
m_PrefabInstance: {fileID: 1527259665985799113}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!1001 &1806685759
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -314028,94 +313917,6 @@ Transform:
|
||||
type: 3}
|
||||
m_PrefabInstance: {fileID: 1886256379}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!1001 &1886577979
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 481936153}
|
||||
m_Modifications:
|
||||
- target: {fileID: 4006626876238256025, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Enemy (2)
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4006626876238256025, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_IsActive
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalScale.x
|
||||
value: 0.05879492
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalScale.y
|
||||
value: 0.43239498
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalScale.z
|
||||
value: 0.06264454
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: -0.049
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0.16271059
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0.118
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: a205c5f30032031428dae83c4a2f2af8, type: 3}
|
||||
--- !u!1001 &1887138831
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -331623,24 +331424,6 @@ Transform:
|
||||
type: 3}
|
||||
m_PrefabInstance: {fileID: 2008147940}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &2008455225 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 385312391933029727, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
m_PrefabInstance: {fileID: 1886577979}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 9de313fb3f367d04bbd130657183cdc8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!4 &2008455231 stripped
|
||||
Transform:
|
||||
m_CorrespondingSourceObject: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
m_PrefabInstance: {fileID: 1886577979}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!1001 &2008475454
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -355462,99 +355245,6 @@ Transform:
|
||||
type: 3}
|
||||
m_PrefabInstance: {fileID: 2145953391}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!1001 &1527259665985799113
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 481936153}
|
||||
m_Modifications:
|
||||
- target: {fileID: 3951388154437428790, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: enableRegen
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4006626876238256025, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Enemy
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4006626876238256025, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_IsActive
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalScale.x
|
||||
value: 0.05879492
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalScale.y
|
||||
value: 0.43239498
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalScale.z
|
||||
value: 0.06264454
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0.224
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0.16271059
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: -0.136
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7154477416992791333, guid: a205c5f30032031428dae83c4a2f2af8,
|
||||
type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: a205c5f30032031428dae83c4a2f2af8, type: 3}
|
||||
--- !u!4 &1827334621118886615
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -1,61 +1,69 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class Level1 : Level
|
||||
{
|
||||
[Header("Enemy Setup")]
|
||||
[Tooltip("Optional: parent whose children have EnemyBase components")]
|
||||
public Transform enemiesParent;
|
||||
|
||||
[Tooltip("Or manually assign enemies here")]
|
||||
public List<EnemyBase> enemies = new List<EnemyBase>();
|
||||
|
||||
[Header("Monitoring")]
|
||||
[Tooltip("How often to check alive enemies")]
|
||||
public float checkInterval = 0.25f;
|
||||
[Header("Wave Flow")]
|
||||
public WaveSpawner spawner; // Assign in Inspector
|
||||
[Min(0.05f)] public float checkInterval = 0.25f;
|
||||
|
||||
private bool _running;
|
||||
private Coroutine _monitorCo;
|
||||
|
||||
// Optional: simple counters for UI hooks
|
||||
private int _currentWaveIdx = -1;
|
||||
private int _totalWaves = 0;
|
||||
private int _currentAlive = 0;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (spawner != null)
|
||||
{
|
||||
spawner.OnWaveStarted += HandleWaveStarted;
|
||||
spawner.OnWaveCompleted += HandleWaveCompleted;
|
||||
spawner.OnAllWavesCompleted += HandleAllWavesCompleted;
|
||||
spawner.OnAliveCountChanged += HandleAliveChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (spawner != null)
|
||||
{
|
||||
spawner.OnWaveStarted -= HandleWaveStarted;
|
||||
spawner.OnWaveCompleted -= HandleWaveCompleted;
|
||||
spawner.OnAllWavesCompleted -= HandleAllWavesCompleted;
|
||||
spawner.OnAliveCountChanged -= HandleAliveChanged;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnLevelStart()
|
||||
{
|
||||
base.OnLevelStart();
|
||||
|
||||
// Collect enemies if using a parent
|
||||
if (enemiesParent != null)
|
||||
if (spawner == null)
|
||||
{
|
||||
enemies.Clear();
|
||||
foreach (Transform child in enemiesParent)
|
||||
{
|
||||
var eb = child.GetComponent<EnemyBase>();
|
||||
if (eb != null) enemies.Add(eb);
|
||||
}
|
||||
}
|
||||
|
||||
// Turn enemies on & let their own Start() find the player
|
||||
foreach (var e in enemies)
|
||||
{
|
||||
if (e == null) continue;
|
||||
e.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
// Edge case: no enemies -> complete immediately
|
||||
if (CountAlive() == 0)
|
||||
{
|
||||
CompleteLevel();
|
||||
Debug.LogError("[Level1] No WaveSpawner assigned.");
|
||||
CompleteLevelImmediate();
|
||||
return;
|
||||
}
|
||||
|
||||
_totalWaves = spawner.TotalWaves;
|
||||
_running = true;
|
||||
_monitorCo = StartCoroutine(MonitorEnemies());
|
||||
Debug.Log("Level1: Started, monitoring enemies...");
|
||||
|
||||
// Kick off waves
|
||||
spawner.StartSpawning();
|
||||
|
||||
// As an extra safeguard, monitor completion state
|
||||
_monitorCo = StartCoroutine(MonitorForCompletion());
|
||||
Debug.Log("[Level1] Level started, waves spawning…");
|
||||
}
|
||||
|
||||
public override void OnLevelEnd()
|
||||
{
|
||||
base.OnLevelEnd();
|
||||
_running = false;
|
||||
|
||||
if (_monitorCo != null)
|
||||
{
|
||||
StopCoroutine(_monitorCo);
|
||||
@ -63,46 +71,55 @@ public class Level1 : Level
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator MonitorEnemies()
|
||||
private IEnumerator MonitorForCompletion()
|
||||
{
|
||||
var wait = new WaitForSeconds(checkInterval);
|
||||
while (_running)
|
||||
{
|
||||
if (CountAlive() == 0)
|
||||
// Complete when spawner reports all waves completed AND no alive remain
|
||||
if (spawner.AllWavesCompleted && spawner.CurrentAlive == 0)
|
||||
{
|
||||
CompleteLevel();
|
||||
CompleteLevelImmediate();
|
||||
yield break;
|
||||
}
|
||||
yield return wait;
|
||||
}
|
||||
}
|
||||
|
||||
private int CountAlive()
|
||||
private void CompleteLevelImmediate()
|
||||
{
|
||||
int alive = 0;
|
||||
for (int i = 0; i < enemies.Count; i++)
|
||||
{
|
||||
var e = enemies[i];
|
||||
if (e != null && e.gameObject.activeInHierarchy && !e.IsDead())
|
||||
alive++;
|
||||
}
|
||||
return alive;
|
||||
}
|
||||
|
||||
private void CompleteLevel()
|
||||
{
|
||||
Debug.Log("Level1: All enemies defeated. Completing level.");
|
||||
_running = false;
|
||||
Debug.Log("[Level1] All waves cleared. Level complete!");
|
||||
|
||||
// Tell GameplayManager if available
|
||||
if (GameplayManager.Instance != null)
|
||||
{
|
||||
GameplayManager.Instance.CompleteCurrentLevel();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback: just disable this level object
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
// ===== Event handlers (useful for UI/logs/hook-ins) =====
|
||||
private void HandleWaveStarted(int waveIdx, WaveSpawner.Wave wave)
|
||||
{
|
||||
_currentWaveIdx = waveIdx;
|
||||
Debug.Log($"[Level1] Wave {waveIdx + 1}/{_totalWaves} started. Count={wave.count}, Rate={wave.spawnRate:F2}/s");
|
||||
// TODO: Update UI: “Wave X/Y starting”
|
||||
}
|
||||
|
||||
private void HandleWaveCompleted(int waveIdx)
|
||||
{
|
||||
Debug.Log($"[Level1] Wave {waveIdx + 1}/{_totalWaves} completed.");
|
||||
// TODO: UI “Wave complete”
|
||||
}
|
||||
|
||||
private void HandleAllWavesCompleted()
|
||||
{
|
||||
Debug.Log("[Level1] All waves spawned. Waiting for last enemies to die…");
|
||||
// Completion is finalized in MonitorForCompletion once alive == 0
|
||||
}
|
||||
|
||||
private void HandleAliveChanged(int currentAlive)
|
||||
{
|
||||
_currentAlive = currentAlive;
|
||||
// TODO: UI “Enemies Left: currentAlive”
|
||||
}
|
||||
}
|
||||
|
@ -1,69 +1,192 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class WaveSpawner : MonoBehaviour
|
||||
{
|
||||
[System.Serializable]
|
||||
[Serializable]
|
||||
public class Wave
|
||||
{
|
||||
public GameObject enemyPrefab; // Enemy prefab to spawn
|
||||
public int count = 5; // Number of enemies in this wave
|
||||
public float spawnRate = 1f; // Enemies per second (1 = 1/sec)
|
||||
public GameObject enemyPrefab;
|
||||
[Min(1)] public int count = 5;
|
||||
[Tooltip("Enemies per second. 1 = spawn every 1s, 5 = every 0.2s")]
|
||||
[Min(0.0001f)] public float spawnRate = 1f;
|
||||
}
|
||||
|
||||
[Header("Setup")]
|
||||
public Wave[] waves;
|
||||
public Transform spawnPoint;
|
||||
[Tooltip("Optional parent to keep the hierarchy tidy")]
|
||||
[Tooltip("Optional parent to keep hierarchy clean")]
|
||||
public Transform containerParent;
|
||||
public float timeBetweenWaves = 5f;
|
||||
public bool autoStart = false;
|
||||
[Min(0f)] public float timeBetweenWaves = 3f;
|
||||
|
||||
public int CurrentWaveIndex { get; private set; } = -1; // 0-based, -1 = none yet
|
||||
public bool IsSpawning { get; private set; }
|
||||
public bool AllWavesDone { get; private set; }
|
||||
public bool AllWavesCompleted { get; private set; }
|
||||
public int CurrentAlive => _alive.Count;
|
||||
|
||||
public readonly List<EnemyBase> spawned = new List<EnemyBase>();
|
||||
// EVENTS (subscribe from Level1 or any other listener)
|
||||
public event Action<int, Wave> OnWaveStarted; // args: waveIndex, waveDef
|
||||
public event Action<int> OnWaveCompleted; // args: waveIndex
|
||||
public event Action OnAllWavesCompleted;
|
||||
public event Action<GameObject> OnEnemySpawned; // args: instance
|
||||
public event Action<int> OnAliveCountChanged; // args: currentAlive
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (autoStart) StartSpawning();
|
||||
}
|
||||
// Internals
|
||||
private readonly List<GameObject> _alive = new List<GameObject>();
|
||||
private Coroutine _routine;
|
||||
|
||||
public int TotalWaves => waves != null ? waves.Length : 0;
|
||||
|
||||
public void StartSpawning()
|
||||
{
|
||||
if (IsSpawning || AllWavesDone) return;
|
||||
StartCoroutine(SpawnRoutine());
|
||||
if (IsSpawning || AllWavesCompleted) return;
|
||||
if (spawnPoint == null || waves == null || waves.Length == 0)
|
||||
{
|
||||
Debug.LogWarning("[WaveSpawner] Missing spawnPoint or waves.");
|
||||
return;
|
||||
}
|
||||
_routine = StartCoroutine(SpawnRoutine());
|
||||
}
|
||||
|
||||
IEnumerator SpawnRoutine()
|
||||
public void StopSpawning()
|
||||
{
|
||||
if (_routine != null)
|
||||
{
|
||||
StopCoroutine(_routine);
|
||||
_routine = null;
|
||||
}
|
||||
IsSpawning = false;
|
||||
}
|
||||
|
||||
private IEnumerator SpawnRoutine()
|
||||
{
|
||||
IsSpawning = true;
|
||||
AllWavesDone = false;
|
||||
AllWavesCompleted = false;
|
||||
|
||||
for (int w = 0; w < waves.Length; w++)
|
||||
{
|
||||
CurrentWaveIndex = w;
|
||||
var wave = waves[w];
|
||||
OnWaveStarted?.Invoke(w, wave);
|
||||
|
||||
// spawn phase
|
||||
for (int i = 0; i < wave.count; i++)
|
||||
{
|
||||
SpawnEnemy(wave.enemyPrefab);
|
||||
yield return new WaitForSeconds(1f / Mathf.Max(0.0001f, wave.spawnRate));
|
||||
SpawnEnemyOnce(wave.enemyPrefab);
|
||||
yield return new WaitForSeconds(1f / wave.spawnRate);
|
||||
}
|
||||
|
||||
if (w < waves.Length - 1)
|
||||
// wait until wave cleared (no alive remaining from all spawns so far)
|
||||
yield return StartCoroutine(WaitUntilCleared());
|
||||
|
||||
OnWaveCompleted?.Invoke(w);
|
||||
|
||||
if (w < waves.Length - 1 && timeBetweenWaves > 0f)
|
||||
yield return new WaitForSeconds(timeBetweenWaves);
|
||||
}
|
||||
|
||||
IsSpawning = false;
|
||||
AllWavesDone = true;
|
||||
AllWavesCompleted = true;
|
||||
OnAllWavesCompleted?.Invoke();
|
||||
}
|
||||
|
||||
void SpawnEnemy(GameObject enemyPrefab)
|
||||
private IEnumerator WaitUntilCleared()
|
||||
{
|
||||
if (enemyPrefab == null || spawnPoint == null) return;
|
||||
var wait = new WaitForSeconds(0.25f);
|
||||
while (true)
|
||||
{
|
||||
CompactAliveList();
|
||||
if (_alive.Count == 0) break;
|
||||
yield return wait;
|
||||
}
|
||||
}
|
||||
|
||||
var go = Instantiate(enemyPrefab, spawnPoint.position, spawnPoint.rotation, containerParent);
|
||||
private void SpawnEnemyOnce(GameObject prefab)
|
||||
{
|
||||
if (prefab == null) return;
|
||||
var go = Instantiate(prefab, spawnPoint.position, spawnPoint.rotation, containerParent);
|
||||
|
||||
// Attach relay so we detect destruction/disable cleanly
|
||||
var relay = go.AddComponent<_EnemyLifeRelay>();
|
||||
relay.Init(this);
|
||||
|
||||
_alive.Add(go);
|
||||
OnEnemySpawned?.Invoke(go);
|
||||
OnAliveCountChanged?.Invoke(_alive.Count);
|
||||
}
|
||||
|
||||
private void CompactAliveList()
|
||||
{
|
||||
for (int i = _alive.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var go = _alive[i];
|
||||
if (go == null)
|
||||
{
|
||||
_alive.RemoveAt(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Consider not-alive when:
|
||||
// 1) Destroyed (handled by null above), OR
|
||||
// 2) Inactive in hierarchy, OR
|
||||
// 3) Has EnemyBase and IsDead() is true.
|
||||
bool alive = go.activeInHierarchy;
|
||||
if (alive)
|
||||
{
|
||||
var eb = go.GetComponent<EnemyBase>();
|
||||
if (eb != null) spawned.Add(eb);
|
||||
if (eb != null && eb.IsDead()) alive = false;
|
||||
}
|
||||
|
||||
if (!alive)
|
||||
{
|
||||
_alive.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Called by relay on death/destroy/disable
|
||||
private void NotifyGone(GameObject go)
|
||||
{
|
||||
if (go == null) return;
|
||||
int idx = _alive.IndexOf(go);
|
||||
if (idx >= 0)
|
||||
{
|
||||
_alive.RemoveAt(idx);
|
||||
OnAliveCountChanged?.Invoke(_alive.Count);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper component placed on each spawned enemy
|
||||
private class _EnemyLifeRelay : MonoBehaviour
|
||||
{
|
||||
private WaveSpawner _owner;
|
||||
private EnemyBase _enemyBase;
|
||||
private bool _notified;
|
||||
|
||||
public void Init(WaveSpawner owner)
|
||||
{
|
||||
_owner = owner;
|
||||
_enemyBase = GetComponent<EnemyBase>();
|
||||
// If your EnemyBase has an OnDeath event, you can hook it here:
|
||||
// _enemyBase.OnDeath += HandleGone;
|
||||
}
|
||||
|
||||
private void OnDisable() => HandleGone();
|
||||
private void OnDestroy() => HandleGone();
|
||||
|
||||
private void HandleGone()
|
||||
{
|
||||
if (_notified || _owner == null) return;
|
||||
|
||||
// If EnemyBase exists and isn't actually dead yet (e.g., pooled), skip.
|
||||
// We'll rely on spawner's periodic compaction in that case.
|
||||
if (_enemyBase != null && !_enemyBase.IsDead() && gameObject.activeInHierarchy)
|
||||
return;
|
||||
|
||||
_owner.NotifyGone(gameObject);
|
||||
_notified = true;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user