Attracting Power-ups in Unity
For today’s article, I’ll be going over how to implement attracting multiple power-ups nearby the player ship. To see the full code-base for reference and to follow along more closely, please visit my github repo: https://github.com/hlimbo/Space-Shooter-Tutorial
Adding Attract Behavior in Player Script
In the Player
script:
Breaking this script down:
- I use
FixedUpdate()
function overUpdate()
function because I’m using thePhysics2D.OverlapCircleAll()
function as Physics related calculations should be made inFixedUpdate()
based on Unity’s Documentation. Physics2D.OverlapCircleAll()
returns an array of Collider2D objects where I pass in the current location of the powerup, attract-radius, and layer mask. The layer mask is responsible for only filtering in game objects that belong to the power up layer mask which can be set in the Unity Editor:
- On every
FixedUpdate()
call, I make a call toPhysics2D.OverlapCircleAll()
to determine which new power-ups to add toattractedPowerups
list. One of the problems I ran into when implementing this solution was determining if my list of attracted power-ups are valid on the next physics step. - The way I resolved this issue was using a
HashSet
to hold a unique set ofPowerUp
components and checking in the list if the Power-up still exists in the set. If it does not exist in the set, I remove the stale power-up from the list and decrement the loop counter by 1. Note: Decrementing the loop counter by 1 when removing a power-up ensures we don’t skip over a power-up when checking for stale power-ups. Lists behind the scenes will shift valid entries to the left by 1 when deleting an entry in the middle of the list. - Lastly, I add all the new power-ups into the list and to make sure they are all unique copies, I use a
HashSet
and convert it back to a list afterwards.
Movement Code
- Here I use
isAttracted
flag to prevent default movement of the power-up when attracted to the Player ship.
Visualizing Attraction Radius in Unity Editor
I wrote a script named PlayerInspector.cs
which needs to be stored in the Editor directory in order for Unity to recognize it as a Custom Editor tool. Below is a script snippet where I use OnSceneGUI()
function to draw a circle that represents what Physics2D.OverlapCircleAll()
would look like:
The OnSceneGUI()
function will allow us to view the red circle drawn above when the Player game-object is selected in the Game Hierarchy view. The CustomEditor
attribute allows us to define what Component this Editor script is for. In my case, it is used only for game objects with the Player
component attached.
Thanks for reading :)