Upgrade Unity UI : Dynamic HUD Color Changes
Creating UI features can seem insignificant but with each feature that is added to increase the User Interface clarity and responsiveness, each time the User will experience a more immersive and engaging experience in a Unity game. By dynamically updating the HUD (Heads Up Display) based on gameplay elements, like shield durability, developers can provide Players with intuitive feedback. In this story, Unity’s scripting tools will be used, specifically focusing on Color.Lerp, to create dynamic UI elements that react in real-time to in-game events.
In my previous story, Upgrading Game Mechanics in Unity: Shield Durability, applying color properties and the Color constructor was used to improve visual feedback and the User experience. Why stop there? To continue to expand on an understanding of Color as a means to provide the User with visible feedback, why not also apply color to UI Manager, specifically Heads Up Display color changes, to reflect the durability of the shield state on the Player’s lives image?
To develop the UIManager (Script) so that the UpdateLives method changes the color of each image to reflect the loss of each shield, the _livesImg
color property will be updated based on the current number of collisions stored in the variable _shieldsRemaining
. This process is referred to as normalizing values.
I open the UIManager (Script). Go to the Scripts folder within the Assets. At the top of the class a Sprite[] array named liveSprites stores the sprite images (png) that needs to change color. _liveSprites is assigned to _livesImg, and this Image data type has the color property that will be accessed and changed.
Setting Up Script communication
To enable the UIManager (Script) to change the color of the lives image (i.e., _livesImg
), script communication between the two scripts is only part of the answer. To communicate with the UI Manager from the Player (Script), a new custom method UpdateShieldColor()
will be created in the UIManager and called from the Player (Script) Damage() method when the shield state changes.
Develop the logic to handle the new behavior. This method will update the _livesImg
sprites using the color property based on the _shieldsRemaining
collisions. In the curly braces draft the pseudocode as // define and set the Color and change color
, // access the Color property of the lives image sprite
Color.Lerp
After sometime researching, I came across one of many methods used to change colors in Unity game development.
Google search: “transition between two colors Unity”. The search returns the Unity Scripting API: Color.Lerp.
The Description states that Color.Lerp, “Linearly interpolates between colors a
and b
by t
.” What does interpolate mean exactly? a
, b
and t
represent what exactly?
The term “interpolate” means to alter something through the insertion of one thing into the other; “inter-” meaning between and “polate” implies two end of a spectrum or poles like north and south pole. In the context of colors between two points on a linear scale, one color is “inserted” into the other to create a transition from one color to another. Colors a
and b
implies the colors are on opposite ends of the scale, and t
… t
?
t
represents a specific point(s) between the color a
and color b
. 0
returns color a
, 1
returns color b
and any floating decimal between a
and b
returns a variation of the colors hue.
Looking at both the Declaration syntax and the script example, it’s clear Lerp() has 3 parameters, the first is a
“starting” color property, the second is b
“ending” color property, then the t
value that interpolates between the 2 floating point values.
The script example shows a variable that Color.Lerp()
method is assigned to. The parameters in the Lerp()
method have a starting and ending color and a t
value. Below the method, the variable using Lerp()
is assigned to a component’s color property.
In theory the _livesImg
color property could be assigned to a variable and then that variable could set the color using the Lerp()
method.
The t
value will change as a result of the _shieldsRemaining
variable being divided by the 3f
, the total number of shields, after each collision and be accessed by setting the UpdateShieldColor()
method to the variable colorValue
in the Player (Script). This allows the shift in color value to correspond identically between the _shield
sprite and the _livesImg
sprite through the process of normalizing values, but that’s another story to be shared later.
Player Script Communication
Next, to complete the process of communication between scripts, the Player script’s Damage()
method needs developed to communicate with the UIManager (Script) whenever the shield state changes.
In the Damage()
method, when the shield is active, the reference data type UIManager (i.e., _uiManager
) is called, its method, UpdateShieldColor()
identified, and the variable that stores the normalized value , float colorValue
, will update the UIManager what the current normalized value is.
When the _shieldsRemaining
is less than or equal to 0
, the _livesImg.color
property will be reset to its original Color.white
.
In the UIManager (Script) To reset the _livesImg
to its original color, create a custom method ResetLivesColor()
and access the color property of _livesImg
then set it Color property to white.
Back in the Player’s (script), within the Damage() method, where the if statement checks shieldsRemaining is less than or equal to 0, the shields will be deactivated. This is where the ResetLivesColor() method needs to be called. Use the named variable uiManager to access the reference to the UIManager (Script) and notify the UI it is time to reset the lives image to the original color.
Test the Feature
Go back to the Unity editor. Press play. Collect a Shield Power Up. Deliberately collide with incoming Enemies. Each time the Player collides, not only does the Shield color change, now the images of available lives in the top left corner use color to indicate the state of the shield and when the shield has no more collisions remaining the color is reset to communicate a state of vulnerability to the User.
Using dynamic HUD elements by leveraging Unity’s powerful scripting tools like Color.Lerp(), any game developer can create a more satisfying Player experience for the User. As I continue exploring creative possibilities and experimenting with techniques to further refine my game development skills, join me, please follow/subscribe or clap and comment. Look below for more resources that I found on my journey.