I mainly come from a programming background so a lot of the time I prefer to visualize my effects through code instead of Unity’s built animation tools. Especially for simple things like the Danger Zone displayed here.
So now, how does it work? Just like always we must first breakdown what we want our code to do step by step. In this particular case it would look like this:
- The further away from the player the ring is, the dimmer it gets. Inversely, the closer the player is to the ring, the brighter it gets
- If the player enters the ring, then the ring turns red
- When the player exits the ring, then the ring turns white
Let’s start with Step 1. Arguably, the hardest step of the process. This takes an understanding of Colours in Unity and some clever usage of division. The trick here is to affect the Alpha channel of the SpriteRenderer’s colour to make it dimmer or brighter depending on the distance between the edge of the ring and the player.
Colours in Unity are simply Vector4 data types with the (red, green, blue, alpha) values in that order. However, when instantiating a new colour via code each channel is normalized to a factor of 1. That means that White, which is normally (255,255,255,255) in the inspector is actually (1,1,1,1). With this in mind we now know that we can adjust our Alpha using a scale of 0–1.
Alpha is what determines the transparency of a colour. With 0 being transparent and 1 being opaque
So now, how do we get the Alpha to be less than 1 when the player is far away and greater than or equal to 1 as the player gets closer?
Simple. We use Division! Remember that the greater divisor is, then the smaller the result is. We can use this to our advantage. Our formula would like this
minimumDistance / distanceBetweenSelfAndPlayer
Now how do we translate that into Unity C# code? Like this!
As long as we have a reference to the player then getting the distance is easy enough thanks to the Vector3.Distance() function. But why does the minimumDistance look so complicated? Allow me to elaborate.
I didn’t name it very well, but sc stands for sphere collider since I want to search for the player using a ring. Why am I multiplying the radius by the localScale.x though? This is done so I can quickly adjust the size of the ring in the inspector by changing the scale and since it’s a circle the x and y scale will always be the same. This way I can adjust the size of the collider and the sprite at the same time without worrying about offsetting the code manually each time. The last value 1.25f is a constant I chose because I wanted to ring to reach maximum Alpha before actually touching the ring so that the player has a bit of an early warning. So the minimumDistance in the formula is actually the radius + 25%. Which is purely a Quality of life design decision and not necessary for the formula.
Slap that into your update function and you’re done!
Step 2 and 3 are very straightfoward thanks to the OnTriggerEnter() and OnTriggerExit() events.
With the explanation of colours from earlier in mind. What do you think the colour red would be? If you said “(1,0,0,1) then you would be correct! But I’m lazy so I just put Color.red instead XD
And step 3? Exact same thing except that it’s in the OnTriggerExit() event instead.
That’s it for the danger zone! This technique is pretty situational, but I want the main take away to be the minimumDistance/totalDistance forumla. This technique can be quite useful in many distance based code, whether it be for effects, gameplay or otherwise.
Just remember, the greater the divisor the smaller the result!
Hope that helps! ^_^b