Swarm Survivor, a top-down shooter using DOTS
Yesterday, I published this game. "Swarm Survivor" is a temporary name, since this is still a prototype, maybe even just a tech demo.
My goal making this game was to challenge myself and use Unity's Data Oriented Technology Stack to create engaging gameplay. I had been doing some tests and playing around with DOTS for a while before this, but I hadn't "made a game". I am very happy with how it turned out.
However, don't expect a riveting story, a complex skills system, or a bunch of different enemies and weapons. What you see in the gif is what you get 😅
Now, I will go through the development process. I documented it on my Twitter (@_emmaPrats), but I think it's pertinent to organize it and put it in this devlog:
First, I created an empty Unity project. I chose the version 2021.3.4 with the intention of upgrading versions as they are released, since this is a prototype in active development, and don't need the most stable version with long time support.
I chose the Universal Rendering Pipeline because I was not looking for high-fidelity realistic graphics (I never am).
And I chose to use the version 0.51.0 of the Entities package. This was the most up to date version at the time (it still is at the time of writing), but has fewer features than some of the older version. Since I wanted to use "the latest stuff" and wasn't planning on using animations anyway, it was a perfectly good choice.
So, the first step was to set up a basic environment, create the player and the bullet prefabs, and code the player's movement and shooting behaviour:
At this point, there are no collisions between the bullets and the environment yet.
Then, I created the enemy prefabs and implemented an "enemy spawner" that spawns enemies at random positions (at a minimum distance from the player) at a regular interval.
I also implemented collision detection between the bullets and the enemies, which was very interesting. In "regular Unity", you have access to the OnCollisionEnter() and OnTriggerEnter() methods in the MonoBehaviour class, which will be called by Unity's runtime automatically. However, with ECS, you must implement an IContactsJob and manually set it as a callback to the StepPhysicsWorld system.
At this point, I had a bunch of enemies appearing (but they're static), a player that can move and shoot, and enemies die when they are shot.
Next, I added a time counter and a kills counter. I made the ui using UI Toolkit. Since the UI is controlled by a "regular Unity" MonoBehaviour, and the enemies are "detected to be dead" in a system, I used a message bus.
Oh, and now the bullets bounce off walls!
Next, I added a "restart" button to be able to restart the level. It's not exciting, so I didn't make a specific gif for it.
And then it was finally time to make the enemies move. They should move toward the player.
My first thought was to implement a basic seek behaviour. However, I thought that there might be a time when I would want to create different environments, maybe add walls, or obstacles... So A* it is!
I treated the environment as a grid, assigned which cells are "walkable" and which are not, and implemented the A* pathfinding algorithm. I made it into a bust-compiled parallel job, so that thousands of units can run it without the game crashing or grinding to a halt.
It is important to note that the pathfinding algorithm only runs whenever the player's position changes (as in "which cell in the grid the player is on"), there is no need to run it every frame.
At this point, the enemy is not yet a physics body, and it is simply following the path between points without any smoothing.
So the next step was to make the enemy a physics body, and constrain its degrees of freedom so that it only rotates in the Y axis and it only moves in the horizontal plane:
And then I implemented the seek behaviour for the enemies to follow their path.
(I temporarily deactivated the killing of enemies from bullet hits to check that collisions looked good.)
Since the enemies seem to "get stuck" easily, I also added a separation behaviour (enemies will try to keep a safe distance between each other) to a distance just slightly larger than the cube side length.
And I got rid of the tiles and obstacles, because I wasn't convinced they were that good.
Finally, I implemented player-enemy collision detection, made the player have hitpoints, and now the player takes 1 damage from contact with an enemy (and the enemy is destroyed). I also added a game over screen for when the player reaches 0 HP.
And this is it! This is the "game". It has been an interesting experiment, and I look forward to trying out more DOTS features, and/or polishing the prototype. In general, DOTS is a bit more convoluted than "regular Unity", but it gives you much greater control, and the performance is definitely there.
Files
Get Swarm Survivor
Swarm Survivor
A top-down shooter prototype.
Status | Prototype |
Author | Emma Prats |
Genre | Action |
Tags | Bullet Hell, Prototype, Top-Down, Top down shooter |
Languages | English |
Leave a comment
Log in with itch.io to leave a comment.