diff --git a/.idea/.idea.idle-survivors/.idea/codeStyles/codeStyleConfig.xml b/.idea/.idea.idle-survivors/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..a55e7a1
--- /dev/null
+++ b/.idea/.idea.idle-survivors/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Assets/EventChannels.meta b/Assets/EventChannels.meta
new file mode 100644
index 0000000..7e6f2bd
--- /dev/null
+++ b/Assets/EventChannels.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 243302c56bf8926489fe86e5626dd4d3
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/EventChannels/EndSpawnWave.asset b/Assets/EventChannels/EndSpawnWave.asset
new file mode 100644
index 0000000..e640b20
--- /dev/null
+++ b/Assets/EventChannels/EndSpawnWave.asset
@@ -0,0 +1,14 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 908e283bf3a54c859a0771fd8aed7bce, type: 3}
+ m_Name: EndSpawnWave
+ m_EditorClassIdentifier:
diff --git a/Assets/EventChannels/EndSpawnWave.asset.meta b/Assets/EventChannels/EndSpawnWave.asset.meta
new file mode 100644
index 0000000..1d1be12
--- /dev/null
+++ b/Assets/EventChannels/EndSpawnWave.asset.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b8a8049e92364834ebac76909a03324b
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 11400000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/EventChannels/StartSpawnWave.asset b/Assets/EventChannels/StartSpawnWave.asset
new file mode 100644
index 0000000..d64f46a
--- /dev/null
+++ b/Assets/EventChannels/StartSpawnWave.asset
@@ -0,0 +1,14 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 908e283bf3a54c859a0771fd8aed7bce, type: 3}
+ m_Name: StartSpawnWave
+ m_EditorClassIdentifier:
diff --git a/Assets/EventChannels/StartSpawnWave.asset.meta b/Assets/EventChannels/StartSpawnWave.asset.meta
new file mode 100644
index 0000000..3574443
--- /dev/null
+++ b/Assets/EventChannels/StartSpawnWave.asset.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3f9039af54fd5d240b144e1ab3bbeb72
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 11400000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Runtime Sets.meta b/Assets/Runtime Sets.meta
new file mode 100644
index 0000000..59dfce9
--- /dev/null
+++ b/Assets/Runtime Sets.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 57024de5f8ad4f74ba5d83bb062a7612
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Runtime Sets/ActiveEnemyRuntimeSet.asset b/Assets/Runtime Sets/ActiveEnemyRuntimeSet.asset
new file mode 100644
index 0000000..604da9b
--- /dev/null
+++ b/Assets/Runtime Sets/ActiveEnemyRuntimeSet.asset
@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 5f1e329a7f6343f88553db21ffb55693, type: 3}
+ m_Name: ActiveEnemyRuntimeSet
+ m_EditorClassIdentifier:
+ Items: []
diff --git a/Assets/Runtime Sets/ActiveEnemyRuntimeSet.asset.meta b/Assets/Runtime Sets/ActiveEnemyRuntimeSet.asset.meta
new file mode 100644
index 0000000..e47d681
--- /dev/null
+++ b/Assets/Runtime Sets/ActiveEnemyRuntimeSet.asset.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 7c32c32e039cdda409e8a56d2e320f2d
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 11400000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scenes/test.unity b/Assets/Scenes/test.unity
index dd08e1d..7ab66de 100644
--- a/Assets/Scenes/test.unity
+++ b/Assets/Scenes/test.unity
@@ -497,6 +497,73 @@ MonoBehaviour:
cameraController: {fileID: 1176001025}
rotationSensitivity: 100
zoomSensitivity: 0.05
+--- !u!1 &880655848
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 880655850}
+ - component: {fileID: 880655849}
+ - component: {fileID: 880655851}
+ m_Layer: 0
+ m_Name: LevelDirector
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &880655849
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 880655848}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: bb718e52728142e4a8db081fd6a36a70, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ startNewSpawnWaveEventChannel: {fileID: 11400000, guid: 3f9039af54fd5d240b144e1ab3bbeb72, type: 2}
+ endSpawnWaveEventChannel: {fileID: 11400000, guid: b8a8049e92364834ebac76909a03324b, type: 2}
+ enemyRuntimeSet: {fileID: 11400000, guid: 7c32c32e039cdda409e8a56d2e320f2d, type: 2}
+ spawnCenter: {fileID: 19609788}
+ minimumSpawnRadius: 10
+ timeBetweenClearedWaves: 0
+ timeBeforeFirstWave: 0
+--- !u!4 &880655850
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 880655848}
+ 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: 0}
+ m_RootOrder: 6
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &880655851
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 880655848}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a91533ae182d470c88ce779956713e02, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ waveSpawner: {fileID: 880655849}
+ spawnWaves:
+ - {fileID: 11400000, guid: e7512725c2f0b3148bd090141c5eed5d, type: 2}
--- !u!1 &1038072789
GameObject:
m_ObjectHideFlags: 0
@@ -685,3 +752,64 @@ Transform:
m_Father: {fileID: 1176001024}
m_RootOrder: -1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1001 &5742654212719732323
+PrefabInstance:
+ m_ObjectHideFlags: 0
+ serializedVersion: 2
+ m_Modification:
+ serializedVersion: 3
+ m_TransformParent: {fileID: 0}
+ m_Modifications:
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_RootOrder
+ value: 5
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalPosition.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalPosition.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalPosition.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalRotation.w
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalRotation.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalRotation.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalRotation.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 6229410894397123332, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_Name
+ value: TestEnemy
+ objectReference: {fileID: 0}
+ m_RemovedComponents: []
+ m_RemovedGameObjects: []
+ m_AddedGameObjects: []
+ m_AddedComponents: []
+ m_SourcePrefab: {fileID: 100100000, guid: 200dea255585b154f8222e550c23b55e, type: 3}
diff --git a/Assets/Scriptables/Waves.meta b/Assets/Scriptables/Waves.meta
new file mode 100644
index 0000000..4b4da7b
--- /dev/null
+++ b/Assets/Scriptables/Waves.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 409432f90c2931d49a55a87ded944aa9
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scriptables/Waves/SpawnPack_Test.asset b/Assets/Scriptables/Waves/SpawnPack_Test.asset
new file mode 100644
index 0000000..f951c46
--- /dev/null
+++ b/Assets/Scriptables/Waves/SpawnPack_Test.asset
@@ -0,0 +1,19 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 52673fed940f4a67b5a08641a55feff6, type: 3}
+ m_Name: SpawnPack_Test
+ m_EditorClassIdentifier:
+ possibleEnemies:
+ - {fileID: 7321161463868935016, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ - {fileID: 1158114420728610952, guid: 9dff131d77697b242ae2e2b68aa7e1db, type: 3}
+ minCount: 5
+ maxCount: 10
diff --git a/Assets/Scriptables/Waves/SpawnPack_Test.asset.meta b/Assets/Scriptables/Waves/SpawnPack_Test.asset.meta
new file mode 100644
index 0000000..53e636c
--- /dev/null
+++ b/Assets/Scriptables/Waves/SpawnPack_Test.asset.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 970a884aa40996749b022ebb2765d769
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 11400000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scriptables/Waves/SpawnWave_Test.asset b/Assets/Scriptables/Waves/SpawnWave_Test.asset
new file mode 100644
index 0000000..f527390
--- /dev/null
+++ b/Assets/Scriptables/Waves/SpawnWave_Test.asset
@@ -0,0 +1,33 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 17a69c35e3e64b6d9f655533478f9772, type: 3}
+ m_Name: SpawnWave_Test
+ m_EditorClassIdentifier:
+ packs:
+ - {fileID: 11400000, guid: 970a884aa40996749b022ebb2765d769, type: 2}
+ - {fileID: 11400000, guid: 970a884aa40996749b022ebb2765d769, type: 2}
+ - {fileID: 11400000, guid: 970a884aa40996749b022ebb2765d769, type: 2}
+ - {fileID: 11400000, guid: 970a884aa40996749b022ebb2765d769, type: 2}
+ - {fileID: 11400000, guid: 970a884aa40996749b022ebb2765d769, type: 2}
+ - {fileID: 11400000, guid: 970a884aa40996749b022ebb2765d769, type: 2}
+ - {fileID: 11400000, guid: 970a884aa40996749b022ebb2765d769, type: 2}
+ - {fileID: 11400000, guid: 970a884aa40996749b022ebb2765d769, type: 2}
+ - {fileID: 11400000, guid: 970a884aa40996749b022ebb2765d769, type: 2}
+ - {fileID: 11400000, guid: 970a884aa40996749b022ebb2765d769, type: 2}
+ - {fileID: 11400000, guid: 970a884aa40996749b022ebb2765d769, type: 2}
+ - {fileID: 11400000, guid: 970a884aa40996749b022ebb2765d769, type: 2}
+ distribution: 2
+ radius: 25
+ packRadius: 7.5
+ timeBetweenSpawns: 0.01
+ timeBetweenPacks: 0
+ timeToComplete: 0
diff --git a/Assets/Scriptables/Waves/SpawnWave_Test.asset.meta b/Assets/Scriptables/Waves/SpawnWave_Test.asset.meta
new file mode 100644
index 0000000..7329763
--- /dev/null
+++ b/Assets/Scriptables/Waves/SpawnWave_Test.asset.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: e7512725c2f0b3148bd090141c5eed5d
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 11400000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Enemy.cs b/Assets/Scripts/Enemy.cs
new file mode 100644
index 0000000..f3c5bb1
--- /dev/null
+++ b/Assets/Scripts/Enemy.cs
@@ -0,0 +1,11 @@
+using UnityEngine;
+
+namespace DefaultNamespace
+{
+ // TODO (Michael): Empty behavior until we decide more on how enemies should be structured. Mainly being used for
+ // other systems to have something to reference.
+ public class Enemy : MonoBehaviour
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Enemy.cs.meta b/Assets/Scripts/Enemy.cs.meta
new file mode 100644
index 0000000..56e0666
--- /dev/null
+++ b/Assets/Scripts/Enemy.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 0ce366659158473783c8d53d2f3fc5f5
+timeCreated: 1690856221
\ No newline at end of file
diff --git a/Assets/Scripts/EnemyRuntimeSetSO.cs b/Assets/Scripts/EnemyRuntimeSetSO.cs
new file mode 100644
index 0000000..6ac0946
--- /dev/null
+++ b/Assets/Scripts/EnemyRuntimeSetSO.cs
@@ -0,0 +1,11 @@
+using UnityEngine;
+
+namespace DefaultNamespace
+{
+ [CreateAssetMenu(menuName = "Enemy Runtime Set", fileName =
+ "EnemyRuntimeSet")]
+ public class EnemyRuntimeSetSO : RuntimeSetSO
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/EnemyRuntimeSetSO.cs.meta b/Assets/Scripts/EnemyRuntimeSetSO.cs.meta
new file mode 100644
index 0000000..6f23eba
--- /dev/null
+++ b/Assets/Scripts/EnemyRuntimeSetSO.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 5f1e329a7f6343f88553db21ffb55693
+timeCreated: 1690858329
\ No newline at end of file
diff --git a/Assets/Scripts/Events.meta b/Assets/Scripts/Events.meta
new file mode 100644
index 0000000..bce3236
--- /dev/null
+++ b/Assets/Scripts/Events.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 5741392326404cb387003f002d90acee
+timeCreated: 1690857552
\ No newline at end of file
diff --git a/Assets/Scripts/Events/SpawnWaveSOEventChannelSO.cs b/Assets/Scripts/Events/SpawnWaveSOEventChannelSO.cs
new file mode 100644
index 0000000..f633948
--- /dev/null
+++ b/Assets/Scripts/Events/SpawnWaveSOEventChannelSO.cs
@@ -0,0 +1,17 @@
+using UnityEngine;
+using UnityEngine.Events;
+using Wave;
+
+namespace Events
+{
+ [CreateAssetMenu(menuName = "Events/Spawn Wave SO Event Channel")]
+ public class SpawnWaveSOEventChannelSO : ScriptableObject
+ {
+ public event UnityAction OnEventRaised;
+
+ public void RaiseEvent(SpawnWaveSO spawnWave)
+ {
+ OnEventRaised?.Invoke(spawnWave);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Events/SpawnWaveSOEventChannelSO.cs.meta b/Assets/Scripts/Events/SpawnWaveSOEventChannelSO.cs.meta
new file mode 100644
index 0000000..c2cf029
--- /dev/null
+++ b/Assets/Scripts/Events/SpawnWaveSOEventChannelSO.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 908e283bf3a54c859a0771fd8aed7bce
+timeCreated: 1690857571
\ No newline at end of file
diff --git a/Assets/Scripts/Level.meta b/Assets/Scripts/Level.meta
new file mode 100644
index 0000000..827c059
--- /dev/null
+++ b/Assets/Scripts/Level.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: eb1638a1c58a4878adf9166dddc40738
+timeCreated: 1690927890
\ No newline at end of file
diff --git a/Assets/Scripts/Level/LevelDirector.cs b/Assets/Scripts/Level/LevelDirector.cs
new file mode 100644
index 0000000..d044cd6
--- /dev/null
+++ b/Assets/Scripts/Level/LevelDirector.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using Wave;
+
+namespace Level
+{
+ public class LevelDirector : MonoBehaviour
+ {
+ [SerializeField] private WaveSpawner waveSpawner;
+ [SerializeField] private List spawnWaves;
+
+ private void Start()
+ {
+ waveSpawner.Begin(spawnWaves);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Level/LevelDirector.cs.meta b/Assets/Scripts/Level/LevelDirector.cs.meta
new file mode 100644
index 0000000..a991625
--- /dev/null
+++ b/Assets/Scripts/Level/LevelDirector.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: a91533ae182d470c88ce779956713e02
+timeCreated: 1690927896
\ No newline at end of file
diff --git a/Assets/Scripts/RuntimeSetSO.cs b/Assets/Scripts/RuntimeSetSO.cs
new file mode 100644
index 0000000..1686dfb
--- /dev/null
+++ b/Assets/Scripts/RuntimeSetSO.cs
@@ -0,0 +1,26 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public abstract class RuntimeSetSO : ScriptableObject
+{
+ [HideInInspector] [SerializeField] private List items = new();
+
+ public IReadOnlyCollection Items => items;
+ public bool IsEmpty => items.Count == 0;
+
+ public void Add(T thing)
+ {
+ if (!items.Contains(thing))
+ {
+ items.Add(thing);
+ }
+ }
+
+ public void Remove(T thing)
+ {
+ if (items.Contains(thing))
+ {
+ items.Remove(thing);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/RuntimeSetSO.cs.meta b/Assets/Scripts/RuntimeSetSO.cs.meta
new file mode 100644
index 0000000..b4b80d6
--- /dev/null
+++ b/Assets/Scripts/RuntimeSetSO.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 942f0916a83b433891dd4c6a9bbb50fd
+timeCreated: 1690858304
\ No newline at end of file
diff --git a/Assets/Scripts/Wave.meta b/Assets/Scripts/Wave.meta
new file mode 100644
index 0000000..b5b3dd7
--- /dev/null
+++ b/Assets/Scripts/Wave.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 6515ffdab88e4d23b8f09dace4a2157a
+timeCreated: 1690921607
\ No newline at end of file
diff --git a/Assets/Scripts/Wave/SpawnDistribution.cs b/Assets/Scripts/Wave/SpawnDistribution.cs
new file mode 100644
index 0000000..caa2f8d
--- /dev/null
+++ b/Assets/Scripts/Wave/SpawnDistribution.cs
@@ -0,0 +1,9 @@
+namespace Wave
+{
+ public enum SpawnDistribution
+ {
+ Uniform,
+ Random,
+ DiskRandom
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Wave/SpawnDistribution.cs.meta b/Assets/Scripts/Wave/SpawnDistribution.cs.meta
new file mode 100644
index 0000000..00c20c9
--- /dev/null
+++ b/Assets/Scripts/Wave/SpawnDistribution.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 2a4df8269a27463eaf87da9ae1283dcb
+timeCreated: 1690925288
\ No newline at end of file
diff --git a/Assets/Scripts/Wave/SpawnPackSO.cs b/Assets/Scripts/Wave/SpawnPackSO.cs
new file mode 100644
index 0000000..b4e3075
--- /dev/null
+++ b/Assets/Scripts/Wave/SpawnPackSO.cs
@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+using DefaultNamespace;
+using UnityEngine;
+using UnityEngine.Assertions;
+
+namespace Wave
+{
+ [CreateAssetMenu(fileName = "SpawnPack", menuName = "Spawn/Pack", order = 0)]
+ public class SpawnPackSO : ScriptableObject
+ {
+ [SerializeField] private List possibleEnemies;
+ [SerializeField] [Min(0)] private int minCount;
+ [SerializeField] [Min(0)] private int maxCount;
+
+ public IReadOnlyCollection EnemiesToSpawn()
+ {
+ Assert.IsTrue(possibleEnemies.Count > 0);
+
+ var count = Random.Range(minCount, maxCount);
+ var enemiesToSpawn = new List();
+
+ for (var i = 0; i < count; i++)
+ {
+ var enemyIndex = Random.Range(0, possibleEnemies.Count);
+ enemiesToSpawn.Add(possibleEnemies[enemyIndex]);
+ }
+
+ return enemiesToSpawn;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Wave/SpawnPackSO.cs.meta b/Assets/Scripts/Wave/SpawnPackSO.cs.meta
new file mode 100644
index 0000000..e5e7ab1
--- /dev/null
+++ b/Assets/Scripts/Wave/SpawnPackSO.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 52673fed940f4a67b5a08641a55feff6
+timeCreated: 1690938542
\ No newline at end of file
diff --git a/Assets/Scripts/Wave/SpawnWaveSO.cs b/Assets/Scripts/Wave/SpawnWaveSO.cs
new file mode 100644
index 0000000..c7c3956
--- /dev/null
+++ b/Assets/Scripts/Wave/SpawnWaveSO.cs
@@ -0,0 +1,27 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Serialization;
+
+namespace Wave
+{
+ [CreateAssetMenu(fileName = "SpawnWave", menuName = "Spawn Wave", order = 0)]
+ public class SpawnWaveSO : ScriptableObject
+ {
+ [SerializeField] private List packs;
+ [SerializeField] private SpawnDistribution distribution;
+ [SerializeField] [Min(10)] private float radius;
+ [SerializeField] [Min(0)] private float packRadius;
+ [SerializeField] [Min(0)] private float timeBetweenSpawns;
+ [SerializeField] [Min(0)] private float timeBetweenPacks;
+ [SerializeField] [Min(0)] private float timeToComplete;
+
+
+ public IReadOnlyCollection Packs => packs;
+ public SpawnDistribution Distribution => distribution;
+ public float Radius => radius;
+ public float PackRadius => packRadius;
+ public float TimeBetweenSpawns => timeBetweenSpawns;
+ public float TimeBetweenPacks => timeBetweenPacks;
+ public float TimeToComplete => timeToComplete;
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Wave/SpawnWaveSO.cs.meta b/Assets/Scripts/Wave/SpawnWaveSO.cs.meta
new file mode 100644
index 0000000..831dd48
--- /dev/null
+++ b/Assets/Scripts/Wave/SpawnWaveSO.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 17a69c35e3e64b6d9f655533478f9772
+timeCreated: 1690856578
\ No newline at end of file
diff --git a/Assets/Scripts/Wave/WaveSpawner.cs b/Assets/Scripts/Wave/WaveSpawner.cs
new file mode 100644
index 0000000..74c4f4c
--- /dev/null
+++ b/Assets/Scripts/Wave/WaveSpawner.cs
@@ -0,0 +1,129 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using DefaultNamespace;
+using Events;
+using UnityEngine;
+using UnityEngine.Assertions;
+using Random = UnityEngine.Random;
+
+namespace Wave
+{
+ public class WaveSpawner : MonoBehaviour
+ {
+ [SerializeField] private SpawnWaveSOEventChannelSO startNewSpawnWaveEventChannel;
+ [SerializeField] private SpawnWaveSOEventChannelSO endSpawnWaveEventChannel;
+
+ [SerializeField] private EnemyRuntimeSetSO enemyRuntimeSet;
+ [SerializeField] private Transform spawnCenter;
+ [SerializeField] private float minimumSpawnRadius;
+ [SerializeField] [Min(0)] private float timeBetweenClearedWaves;
+ [SerializeField] [Min(0)] private float timeBeforeFirstWave;
+
+ private float _timeSinceLastSpawnWaveStarted;
+ private Coroutine _handleSpawnWaves;
+
+ private bool HasWaveBeenCleared => enemyRuntimeSet.IsEmpty;
+
+ public void Begin(IEnumerable spawnWaves)
+ {
+ Assert.IsNull(_handleSpawnWaves);
+ _handleSpawnWaves = StartCoroutine(CO_HandleSpawnWaves(spawnWaves));
+ }
+
+ public void End()
+ {
+ StopCoroutine(_handleSpawnWaves);
+ }
+
+ private IEnumerator CO_HandleSpawnWaves(IEnumerable spawnWaves)
+ {
+ yield return new WaitForSeconds(timeBeforeFirstWave);
+
+ foreach (var spawnWave in spawnWaves)
+ {
+ startNewSpawnWaveEventChannel.RaiseEvent(spawnWave);
+ yield return SpawnWave(spawnWave);
+ _timeSinceLastSpawnWaveStarted = 0.0f;
+
+ yield return new WaitUntil(() =>
+ _timeSinceLastSpawnWaveStarted >= spawnWave.TimeToComplete
+ || HasWaveBeenCleared);
+
+ endSpawnWaveEventChannel.RaiseEvent(spawnWave);
+ yield return new WaitForSeconds(timeBetweenClearedWaves);
+ }
+ }
+
+ private IEnumerator SpawnWave(SpawnWaveSO spawnWave)
+ {
+ var enemyPacksToSpawn = spawnWave.Packs.Select(pack => pack.EnemiesToSpawn()).ToList().AsReadOnly();
+ var totalPacksToSpawn = enemyPacksToSpawn.Count;
+
+
+ var numberPacksSpawned = 0;
+ foreach (var enemyPackToSpawn in enemyPacksToSpawn)
+ {
+ numberPacksSpawned++;
+ var waveCompletionPercentage = (float) numberPacksSpawned / (float) totalPacksToSpawn;
+
+ // TODO (Michael): Both the pack and enemy position samplers need to be a bit smarter. I think in most scenarios the pack circle just needs to not overlap with other pack circles.
+ // The enemy spawns probably need something like a poission disk sampler so that monsters dont overlap. The enemy spawn radius at the pack's position should also probably scale with the size of the pack.
+ var enemyPackSpawnCenter = CalculatePackSpawnPosition(waveCompletionPercentage, spawnWave);
+
+ foreach (var enemy in enemyPackToSpawn)
+ {
+
+ var spawnLocation = CalculateEnemySpawnPosition(enemyPackSpawnCenter, spawnWave.PackRadius);
+ var spawnedEnemy = Instantiate(enemy, spawnLocation, Quaternion.identity);
+ enemyRuntimeSet.Add(spawnedEnemy);
+
+ if (spawnWave.TimeBetweenSpawns > 0.0f)
+ {
+ yield return new WaitForSeconds(spawnWave.TimeBetweenSpawns);
+ }
+ }
+
+ if (spawnWave.TimeBetweenPacks > 0.0f)
+ {
+ yield return new WaitForSeconds(spawnWave.TimeBetweenPacks);
+ }
+ }
+ }
+
+ private Vector3 CalculatePackSpawnPosition(float waveCompletionPercentage, SpawnWaveSO spawnWave)
+ {
+ var angle = waveCompletionPercentage * 2 * MathF.PI;
+ var unitCirclePosition = Random.insideUnitCircle;
+ var swizzledUnitCirclePosition = new Vector3(unitCirclePosition.x, 0, unitCirclePosition.y);
+
+ var spawnOffset = spawnWave.Distribution switch
+ {
+ SpawnDistribution.Uniform => new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * spawnWave.Radius,
+ SpawnDistribution.Random => swizzledUnitCirclePosition.normalized * spawnWave.Radius,
+ SpawnDistribution.DiskRandom => swizzledUnitCirclePosition * spawnWave.Radius,
+ _ => throw new ArgumentOutOfRangeException(nameof(spawnWave.Distribution), spawnWave.Distribution, null)
+ };
+
+ spawnOffset += spawnOffset.normalized * (minimumSpawnRadius + spawnWave.PackRadius);
+
+ return spawnCenter.position + spawnOffset;
+ }
+
+ private Vector3 CalculateEnemySpawnPosition(Vector3 center, float radius)
+ {
+ var unitCirclePosition = Random.insideUnitCircle;
+ var swizzledUnitCirclePosition = new Vector3(unitCirclePosition.x, 0, unitCirclePosition.y);
+
+ var spawnOffset = swizzledUnitCirclePosition * radius;
+
+ return center + spawnOffset;
+ }
+
+ private void Update()
+ {
+ _timeSinceLastSpawnWaveStarted += Time.deltaTime;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Wave/WaveSpawner.cs.meta b/Assets/Scripts/Wave/WaveSpawner.cs.meta
new file mode 100644
index 0000000..fe2d11d
--- /dev/null
+++ b/Assets/Scripts/Wave/WaveSpawner.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: bb718e52728142e4a8db081fd6a36a70
+timeCreated: 1690856916
\ No newline at end of file
diff --git a/Assets/TestEnemy Variant.prefab b/Assets/TestEnemy Variant.prefab
new file mode 100644
index 0000000..234554c
--- /dev/null
+++ b/Assets/TestEnemy Variant.prefab
@@ -0,0 +1,179 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &8302155952709515973
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 7488072351778741751}
+ - component: {fileID: 3366913879355185749}
+ - component: {fileID: 1785543729989221829}
+ - component: {fileID: 1100616685365383236}
+ m_Layer: 0
+ m_Name: Capsule
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &7488072351778741751
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8302155952709515973}
+ 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: 4279102732078913915}
+ m_RootOrder: -1
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!33 &3366913879355185749
+MeshFilter:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8302155952709515973}
+ m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!23 &1785543729989221829
+MeshRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8302155952709515973}
+ m_Enabled: 1
+ m_CastShadows: 1
+ m_ReceiveShadows: 1
+ m_DynamicOccludee: 1
+ m_StaticShadowCaster: 0
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RayTracingMode: 2
+ m_RayTraceProcedural: 0
+ m_RenderingLayerMask: 1
+ m_RendererPriority: 0
+ m_Materials:
+ - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ m_StaticBatchRoot: {fileID: 0}
+ m_ProbeAnchor: {fileID: 0}
+ m_LightProbeVolumeOverride: {fileID: 0}
+ m_ScaleInLightmap: 1
+ m_ReceiveGI: 1
+ m_PreserveUVs: 0
+ m_IgnoreNormalsForChartDetection: 0
+ m_ImportantGI: 0
+ m_StitchLightmapSeams: 1
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+ m_AdditionalVertexStreams: {fileID: 0}
+--- !u!136 &1100616685365383236
+CapsuleCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8302155952709515973}
+ m_Material: {fileID: 0}
+ m_IncludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ExcludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_LayerOverridePriority: 0
+ m_IsTrigger: 0
+ m_ProvidesContacts: 0
+ m_Enabled: 1
+ serializedVersion: 2
+ m_Radius: 0.5
+ m_Height: 2
+ m_Direction: 1
+ m_Center: {x: 0, y: 0, z: 0}
+--- !u!1001 &8470021174966258656
+PrefabInstance:
+ m_ObjectHideFlags: 0
+ serializedVersion: 2
+ m_Modification:
+ serializedVersion: 3
+ m_TransformParent: {fileID: 0}
+ m_Modifications:
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_RootOrder
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalPosition.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalPosition.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalPosition.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalRotation.w
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalRotation.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalRotation.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalRotation.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 6229410894397123332, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ propertyPath: m_Name
+ value: TestEnemy Variant
+ objectReference: {fileID: 0}
+ m_RemovedComponents: []
+ m_RemovedGameObjects:
+ - {fileID: 6791948486170648146, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ m_AddedGameObjects:
+ - targetCorrespondingSourceObject: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ insertIndex: -1
+ addedObject: {fileID: 7488072351778741751}
+ m_AddedComponents: []
+ m_SourcePrefab: {fileID: 100100000, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+--- !u!4 &4279102732078913915 stripped
+Transform:
+ m_CorrespondingSourceObject: {fileID: 5686324643192967835, guid: 200dea255585b154f8222e550c23b55e, type: 3}
+ m_PrefabInstance: {fileID: 8470021174966258656}
+ m_PrefabAsset: {fileID: 0}
diff --git a/Assets/TestEnemy Variant.prefab.meta b/Assets/TestEnemy Variant.prefab.meta
new file mode 100644
index 0000000..0eef45c
--- /dev/null
+++ b/Assets/TestEnemy Variant.prefab.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 9dff131d77697b242ae2e2b68aa7e1db
+PrefabImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/TestEnemy.prefab b/Assets/TestEnemy.prefab
new file mode 100644
index 0000000..8a953c1
--- /dev/null
+++ b/Assets/TestEnemy.prefab
@@ -0,0 +1,152 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &6229410894397123332
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 5686324643192967835}
+ - component: {fileID: 7321161463868935016}
+ m_Layer: 0
+ m_Name: TestEnemy
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &5686324643192967835
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6229410894397123332}
+ 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: 572175646573100614}
+ m_Father: {fileID: 0}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &7321161463868935016
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6229410894397123332}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 0ce366659158473783c8d53d2f3fc5f5, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+--- !u!1 &6791948486170648146
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 572175646573100614}
+ - component: {fileID: 2871351465463266601}
+ - component: {fileID: 4344212730668217775}
+ - component: {fileID: 9190027053535473730}
+ m_Layer: 0
+ m_Name: Model
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &572175646573100614
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6791948486170648146}
+ 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: 5686324643192967835}
+ m_RootOrder: -1
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!33 &2871351465463266601
+MeshFilter:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6791948486170648146}
+ m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!23 &4344212730668217775
+MeshRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6791948486170648146}
+ m_Enabled: 1
+ m_CastShadows: 1
+ m_ReceiveShadows: 1
+ m_DynamicOccludee: 1
+ m_StaticShadowCaster: 0
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RayTracingMode: 2
+ m_RayTraceProcedural: 0
+ m_RenderingLayerMask: 1
+ m_RendererPriority: 0
+ m_Materials:
+ - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ m_StaticBatchRoot: {fileID: 0}
+ m_ProbeAnchor: {fileID: 0}
+ m_LightProbeVolumeOverride: {fileID: 0}
+ m_ScaleInLightmap: 1
+ m_ReceiveGI: 1
+ m_PreserveUVs: 0
+ m_IgnoreNormalsForChartDetection: 0
+ m_ImportantGI: 0
+ m_StitchLightmapSeams: 1
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+ m_AdditionalVertexStreams: {fileID: 0}
+--- !u!135 &9190027053535473730
+SphereCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6791948486170648146}
+ m_Material: {fileID: 0}
+ m_IncludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ExcludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_LayerOverridePriority: 0
+ m_IsTrigger: 0
+ m_ProvidesContacts: 0
+ m_Enabled: 1
+ serializedVersion: 3
+ m_Radius: 0.5
+ m_Center: {x: 0, y: 0, z: 0}
diff --git a/Assets/TestEnemy.prefab.meta b/Assets/TestEnemy.prefab.meta
new file mode 100644
index 0000000..384c8a8
--- /dev/null
+++ b/Assets/TestEnemy.prefab.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 200dea255585b154f8222e550c23b55e
+PrefabImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant: