As the previous recipe illustrates, displaying images for integers with one-to-one correspondence is straightforward. However, sometimes there may be a small number of images to help highlight the "zone" of a numeric variable. Examples might include health points—with green (very healthy) and red (little health remaining) displays. Whether values are represented as floats (for example, 0.0 – 1.0) or ranges within larger numbers (for example, 0 – 50), a general solution is to identify the sub-range (zone) of the numeric value and display the appropriate corresponding image.
To display images corresponding to floats and ranges, please follow these steps:
// file: HealthBar.cs using UnityEngine; using System.Collections; public class HealthBar : MonoBehaviour { const int MAX_HEALTH = 100; public Texture2D bar00; public Texture2D bar10; public Texture2D bar20; public Texture2D bar30; public Texture2D bar40; public Texture2D bar50; public Texture2D bar60; public Texture2D bar70; public Texture2D bar80; public Texture2D bar90; public Texture2D bar100; private int healthPoints = MAX_HEALTH; private void OnGUI() { GUILayout.Label("health = " + healthPoints); float normalisedHealth = (float)healthPoints / MAX_HEALTH; GUILayout.Label( HealthBarImage(normalisedHealth) ); bool decButtonClicked = GUILayout.Button("decrease power"); bool incButtonClicked = GUILayout.Button("increase power"); if( decButtonClicked ) healthPoints -= 5; if( incButtonClicked ) healthPoints += 5; } private Texture2D HealthBarImage(float health) { if( health > 0.9 ){ return bar100; } else if( health > 0.8 ){ return bar90; } else if( health > 0.7 ){ return bar80; } else if( health > 0.6 ){ return bar70; } else if( health > 0.5 ){ return bar60; } else if( health > 0.4 ){ return bar50; } else if( health > 0.3 ){ return bar40; } else if( health > 0.2 ){ return bar30; } else if( health > 0.1 ){ return bar20; } else if( health > 0 ){ return bar10; } else{ return bar00; } } }
The private healthPoints
integer variable stores the game parameter to be graphically represented. The MAX_HEALTH
constant defines the value of healthPoints
, which indicates full health. The 11 public image variables store different versions of the health bar image to correspond to different health ranges. For example, bar00
corresponds to zero health remaining, so it appears as an image with warning red coloring.
The core function in this recipe is a method being called that returns a Texture
image object corresponding to the current value of healthPoints
. A normalized value is created (which will always range between 0.0 and 1.0) by dividing healthPoints
by MAX_HEALTH
. This normalized float is passed to the HealthBarImage()
method, which returns an image; the image is displayed via a Label()
method call.
The HealthBarImage()
method uses a sequence of if
statements to decide which image to return. The provided health value is tested in a sequence of decreasing boundary values—0.9
tested first, then 0.8
, and so on. Ranges are implied by these values, so if the normalized health value is from 0.9
to 1.0
, the image in the bar100
variable will be displayed.
By normalizing values into the range 0.0 – 1.0, methods can be re-used in many different circumstances. So whether the health points for one game are from 0 – 50, or 0 – 10, or 0 – 500, the same code can be used, by always normalizing values by dividing them by their maximum value to get the 0.0 – 1.0 range.
If ranges corresponding to images are always of the same size, then an even more general purpose method could be created that takes as input a normalized value, and an array of images, and determines the ranges depending on the size of the array.
Here are some details you don't want to miss:
While having lots of public Texture2D
variables is straightforward, cleaner code can be achieved by a single public array of Texture2D
objects (in the Inspector view, you'll need to set the size of the array to 11
for this example):
// public array public Texture2D[] barImageArray;
The if
statements inside the HealthBarImage()
method now return values from this array, for example:
if( health > 0.9 ){ return barImageArray[10]; }
3.137.217.95