2D Enemy Wave Patterns for Unity 3D
2D Enemy Wave Patterns gives you the ability to easily create your own, custom wave and formation patterns for enemies, objects or other entities in your Unity games. It also includes a Wave Manager that allows you to chain waves that you create together and have them spawn one after the other. There are seven main wave components to choose from, each having a large selection of properties to tweak and change with the built-in, custom editor Wave Manager editor. Tweaking the controls when creating your own waves gives you thousands of possibilities.
Waves are created using a custom inspector/editor, and added to an optional Wave Manager object for spawning in-game using the custom editor controls. When spawned, each object/entity in the wave is assigned a movement component that is automatically assigned the movement and positioning properties that you specified using the editor. Movement is handled automatically by the movement component and uses translation to move the wave entities (not physics). Of course the objects are still perfectly capable of interacting with the Unity 2D physics engine if you require this separately.
As mentioned above, there are 7 x types of Wave Generator components.
Common features across all Wave Generator components
There is a common IWaveGenerator interface that is shared by all Wave Generator components. This ensures that all Wave Generator components implement a common set of properties and actions, which gives the flexibility to use common properties and methods on all wave generator components, no matter what type they are. Here are the common interface features that all wave generator components have:
- GenerateWave() - this method is used to run code that generates objects in each wave.
- PullFromPool() - this method is used if an optional object pool is chosen to use to spawn objects instead of normal instantiation. This method is hooked up to your own custom implemented object pools, and works as long as your custom object pool method chosen in the inspector returns the GameObject type.
- CustomPoolRef - this is a reference to a MonoBehaviour script instance which represents your own custom (and optional) object pool.
- CustomPoolGetMethodName - this is a string reference to the name of the custom object pool method that would be used to return GameObjects from your pool (again, optional).
- WaveGenerationStarted event - this event fires when wave generation of objects begins.
- WaveGenerationFinished event - this event fires when wave generation of objects ends.
- IsGeneratingWave boolean - true when generating objects, false when not.
- GenerationComplete boolean - true when wave generation is complete, false when not.
- WaveName string - holds the name of the wave.
- AutoDestruct boolean - when true, the value of the AutoDestructTimer is used as a delayed destroy timer for any object spawned in the wave. This is currently only supported for objects spawned by standard instantiation. If you use your own custom object pool to spawn objects, then you need to handle disable/re-enabling of objects from your pool yourself.
- AutoDestructTimer float - this is the amount of time newly spawned objects will wait to auto-destroy if the AutoDestruct flag was set.
All waves also have a speed and direction property. This allows you to move objects in waves left, right, up, down, or any angle by using a combination. E.g. to move objects from right to left, the direction should be set to (-1, 0). Left to right would be (1, 0).
This direction is used in conjunction with the speed property to determine how fast the movement in the direction is.
Some other features that most wave components have is the ability to assign rotation (and rotation direction/speed) to each member object of the wave, as well as spawn delay time in-between individual objects. Many of the wave components also allow you to specify a ‘separation factor’ which increases the distance between objects in a wave that might otherwise normally be too close.
Wave Generator Components
The following sections discusses the important properties of each and give some example screenshots of how a typical configuration could look like in each case.
This is the simplest of wave generator components. It spawns objects in a straight line with some customisable properties like spawn rate and optional rotation. You can use a delay value to specify the interval between individually spawned objects of the wave.
The triangle wave spawns objects all at once. The spawn delay value is ignored. The triangle is created with the point / pinnacle on the left, and the base on the right. The number of objects you set for the wave will determine how big the triangle is.
You can also use the object distance factor property to sepecify how far apart objects forming the triangle are spawned from each other.
The circle wave spawns objects in a full circle. The size of this circle is determined by how many objects you set up to spawn in the wave, as well as the circle spawn distance property value you set. Objects are spawned all in one go with the circle wave. The spawn delay property is ignored.
The sine wave generates objects in a sine curve movement pattern. Objects are spawned using the spawn delay value, and follow a sine curve movement pattern. You control this pattern using the amplitude and omega properties.
The segment wave also uses a sine-like curve movement pattern, but has some custom components that are attached to each object that spawns in the wave. These components ‘attach’ each object in the wave to the object that spawned in front of it. The wave also has a ‘head’ object that spawns first (with the next object being attached to that, and so on…). With this pattern, you can achieve worm or snake-like pattern movement. Destroying one object in the center of the segment will cut-off movement of all the rest that were attached behind the one which was destroyed.
Standard Rotating Wave
This wave spawns lines of objects, but parents them to a central empty GameObject which is given a rotation value that you set. This causes the entire line of objects that get spawned to rotate in tandem. You can create star-like patterns by spawning multiple copies of this type of wave on top of each other (using a 0 delay), and by setting each wave to have a different rotational value.
Spiral Disc Wave
The spiral disc wave arguably has the most number of customisations and options to change it’s appearance. By adjusting the number of objects to spawn, delay, speed, direction, separation factor, and radian angle properties, you are able to achieve many variations and interesting patterns.
The main idea is the use of spirals and circle properties - hence the radian angle property slider in the editor.
How to set up a WaveManger in your Scene
Start by creating an empty GameObject. Give it a name like WaveManager.
Add the WaveManager.cs script to your new GameObject using the Inspector window.
The first thing you’ll want to do is select a Prefab for the type of item / enemy / object that this ‘wave’ in your game will consist of. Chose that using the Wave object prefab field.
Give the wave a name to help identify it, and select the WaveType from the drop down.
You can hover over the other options for a tooltip that explains all the other options and settings that you can use for your wave.
Once finished configuring your wave, click Create wave in the Inspector. The wave is added to the Configured waves list view.
When the game starts, the first wave in the list is the first wave to spawn. The rest will follow based on the settings you set up for each wave.
Take a look at the demo scene included in the package for some more ideas of how to configure wave patterns.
If you are unsure how something works or wish to report an issue, please get in touch by using the contact form.