CustomAssets
Askowl Custom Assets
HealthBarTranscript.cs
1 //- We are going to create a code-free health resource for your game. First let's create a test scene. [[Folder Examples/Editor/Example. Context Create/Scene. Name Health Double-click]]
2 //- Next create a custom asset to store character health. [[Folder Examples/Editor/Example. Context Create/Custom Assets/Mutable/Float. Name Health.]]
3 //- For convenience we will start with full health [[Health Value: 1]]
4 //- Now for the visual. We will start by creating a canvas [[Create/UI/Canvas, context/Create Empty Child/named Bounds]]
5 //- ... and an empty game object called HealthBar [[Create/Create Empty Child/named Health]]
6 //- Let's create an image for the background and make it red [[Set X/Y Anchors to Min 0, Max 1, Change X pivot to 0]]
7 //- Duplicate for the foreground, but make it green.
8 //- The foreground is the only active component. We are going to reduce the scale so that the background shows through. Since transforms don't expose their data, we use a connector. [[Drag connector into Inspector]]
9 //- And we need a float driver to change the scale when our health custom asset changes [[drag Float-Driver into the inspector]]
10 //- This is where we hook them up [[drop health asset into driver and set component to ScaleX]]
11 //- We created the health scene for two reasons - so that we can tweak our health bar before adding it to our project and so we can add manual and automatic testing. We need to add a component to drive the health bar. Fortunately the Unity UI has a slider that works a treat. [[Bounds//context//UI//Slider]]
12 //- It is as simple as pie to hook in our custom asset [[On Value Change/+/Health custom asset/Float.Value]]
13 //- Let's run it up and see if I have made any mistakes
14 
15 //- To finish up, we will write a quick Unity test that can be automated if you wish. It will be run in the Unity Test Runner and drives our visual test slider directly.
16 
17 #if !ExcludeAskowlTests
18 using System.Collections;
19 using UnityEditor;
20 using UnityEngine;
21 using UnityEngine.Assertions;
22 using UnityEngine.TestTools;
23 using UnityEngine.UI;
24 
25 // ReSharper disable MissingXmlDoc
26 
27 namespace Askowl.Transcripts {
28  public class HealthBarTranscript : PlayModeTests {
29  private static string scenePath = "Health";
30 
31  //- PlayModeTests provides a support function to make sure the scene is in the Build Settings so it can be run
32  #if UNITY_EDITOR
33  [InitializeOnLoadMethod] private static void AddSceneToBuildSettings() => AddSceneToBuildSettings(scenePath);
34  #endif
35 
36  //- We will only need a single method to test the integrity of the health function.
37  [UnityTest] public IEnumerator HeathBarTestsWithEnumeratorPasses() {
38  yield return LoadScene(scenePath);
39  //- We will need a reference to the slider for control and the foreground to check the results
40  var slider = Component<Slider>("Testing Slider");
41  var foreground = Component<RectTransform>("Foreground");
42  //- Set the slider to match the health starting value
43  slider.value = foreground.localScale.x;
44 
45  //- local function to set and check a health value. Note the wait. It could be one frame, but I have made it longer so we can see the test happening.
46  IEnumerator setAndCheck(float health) {
47  slider.value = health;
48  yield return new WaitForSeconds(0.1f);
49  var scale = foreground.localScale.x;
50  Assert.AreApproximatelyEqual(health, scale, 0.01f);
51  }
52 
53  //- Check bounds
54  yield return setAndCheck(0);
55  yield return setAndCheck(1);
56  //- Ramp up and make sure all matches
57  for (float health = 0; health <= 1; health += 0.05f) yield return setAndCheck(health);
58  //- Now let's do some random ones in case change of direction can be a problem.
59  for (int i = 0; i < 20; i++) yield return setAndCheck(Random.Range(0f, 1f));
60  }
61  }
62 }
63 #endif
64 //- I guess you will want to see the test running...