Platformer Game CollectiblesMay 22, 2016 7 min read
Some notes on implementing a collectible in a platformer game.
[This article assumes basic knowledge of Unity]
Cute-Platformer-Game was a project I was working on back in 2016 with a team online.
The project was cancelled after my team disappeared, never to be seen again. I continued working on it a bit but ultimately, the scope was far too large for our level of experience. Looking back, it was a bit naive to think a bunch of beginners were going to create the next Mario Odyssey.
A common tale in game dev.
The Drops along with a well, my first model made in Blender.
Drops were the game’s main collectible currency. They were inspired by the Japanese candy, konpeito, while the name came from a British sweet which also has a similar look.
So basically they were the star bits from Mario Galaxy.
Souvenirs from a Japan trip. I just think konpeitos are neat.
Here it is in action:
Below are some notes I had written at the time, back when I was developing it.
The GameObject Setup
Typical Unity workflow would dictate that you make a prefab out of a GameObject with all its components attached. This had a couple problems:
- When the Drop was removed from the game when it’s picked up by the player, the audio and particle effects would also immediately be removed.
- I needed 2 different trigger sphere colliders. A hitbox for when it touches the player, and a second bigger sphere for when the player gets near it to make it start floating towards them.
The first problem was easy to solve. I created a global object pool system that can spawn objects, in this case the audio/particle effects, on request.
Once they were done, the object pool would then store them to be reused later. This was an important optimization during the Unity 5 days, (though I hear garbage collection is less of a problem in Unity 2022).
The second problem took a bit of experimentation.
If Unity wouldn’t let me use 2 separate trigger colliders, what if I used 1 trigger sphere collider and 1 solid (not-trigger) cube collider? Unfortunately, there was a noticeable delay between the solid collider touching the player’s body and the code being activated so this was a no go.
If Unity wouldn’t let me use 2 separate trigger colliders on 1 GameObject, what if I had 2 GameObjects instead? In fact, I had a group of 3 GameObjects. This was before I made the above Object Pool so I had 2 for the colliders and 1 for the audio/particle effects.
I dropped this approach since it required the team to set up all the objects and scripts in a specific way which was prone to user error.
It also made it a pain to reference scripts from another object because I needed to get the components from all the children and sort through them etc.
So back to 1 GameObject. What if I didn’t need 2 triggers?
A sphere check is actually a very simple thing to code, I don’t need to rely on Unity’s Physics engine at all. I can just check the distance between the Drop and the Player.
For debugging I can visualize this manual sphere using Editor gizmos.
Visuals and Movement
They all slowly spin and bob (at slightly different speeds to each other) to add a bit of life into the levels. We didn’t have any artists so we figured the levels might feel barren without these little bits of movement.
On spawn, I cycle through the available colors instead of randomizing them because it looks nicer when the colours are evenly distributed.
There are no lights on the Drop. The glow is made using a Halo Component and an emissive material.
I was planning on experimenting with actual lights if we ever made a night level. It would possibly impact performance though we were using deferred lighting which should allow for this.
There’s a particle trail as it flies towards the player to emphasize its motion. When it hits the player there is a shattering-glass-like particle effect to make it feel more satisfying to collect.
The speed the Drops fly at the player is fast enough to easily catch up but the air resistance is high enough for the Drop to “skid” and curve through the air creating lovely swirly patterns with the trails.
Instead of just floating into the player when they get close, the drop will first hop straight up (as if it’s been activated), freeze for a second, before shooting at the player. This makes it feel more lively and satisfying.
I make sure the Drops have line of sight to the Player first, so they don’t get activated through walls.
Populating the levels
Turns out that having 100 colliding objects in close proximity will tank the frame rate.
For easier level creation, I first thought to make the Drops physics objects.
Instead of needing to carefully place all the Drops at the right height in the levels, I thought it would be quicker if they had gravity and could automatically fall to the ground when they spawn.
Still, this involved a lot of copy/paste so I scrapped it.
Here’s what I came up with instead.
These evenly spawn GameObjects along their path.
These were going to be used for the hand-added Drops in the levels. To guide the Player in the right direction or to catch their attention in certain areas.
This ended up being much easier to implement than I thought. Though I did use a script I found online for calculating the bezier curves.
The 2nd spawner type spews GameObjects out like a fountain.
These were used for dynamically spawned Drops, like when an enemy is defeated or when the Player breaks open a crate.
This involved figuring out how to math random points on a sphere within a given angle/cone to get the spawning directions, but in hindsight maybe just a random.x + random.z would’ve been good enough.
“Should be easy. Find some satisfying foley, drop in the file and I’m done, right?”
2 problems. First, kinda annoying. Second, getting a bunch of Drops at once either causes the sounds to stack/resonate/SCREECH or it breaks Unity and no sound is played at all.
A few techniques I had used to improve this:
Use a different sound effect.
I tried out a few more foley-type effects but they all sounded obnoxious when repeated so frequently.
Then I tried something abstract/gamey and found a few which sounded decent but didn’t quite fit.
I eventually settled on an inoffensive sparkly effect in the end.
Randomize the pitch, volume and length of the sound clip.
This helped reduced the ear-piercing a lot since they were no longer resonating with each other when the player picked up a large group at once. Plus it added a little variation.
Cull sound clips that played too close to each other and add a delay between each Drop spawn.
This had the unintended side effect of making it look like the drops were streaming out the spawn point like a fountain which I totally love.
Increase the pitch after consecutive pick ups.
I tried this with the hand-placed Drops. This is the same technique used in the Mario games. As you pick up coins quickly the pitch rises like a nice musical combo.
Though the intended effect didn’t quite work out as well here as you pick up a lot of Drops at once compared to the other games that use this technique.
I did leave it in but only subtly. I feel this technique is better reserved for more difficult challenges to audibly reward the player.
In-progress video with an exaggerated increasing pitch effect before I settled on the sparkly audio
While it’s a shame the project never got anywhere I am still pretty satisfied with how these turned out. I’d love to get a chance to reuse them in a future project if the oppotunity ever arises.
The heartmato was going to be the health collectible in the game.
The 2nd model I had ever made in Blender.