This part adds logic for the PC and keep track of things such as health, dying. I also add functionality for invisibility (that have already partly added in Guard class). I also add HUD using the new GUI system to show health and energy (that is used to maintain invisibility).
Previous parts:
Lets start with setting up HUD. We need Canvas (GameObject -> UI -> Canvas), couple Images (GameObject -> UI – Image) and Sliders (GameObject -> UI -> Slider). I add canvas under GameManager. I first created background for Invisibility bar and Slider for displaying the energy left. You can drag then object where you want them to be, After that was ready, I copied objects (and modified the parts to make it fit to another corner and have correct texts.)

(Unity UI tutorial is a good starting point to understand how the UI system works.)
As I want to health and invisibility bars to be at the bottom corners, I need to anchor them to those corners.

Slider object needs some fine-tuning also.



Copy the Energy/Invisibility bar and fine tune it to health bar.
Now we have HUD ready to be used. I need to pass pointers to the PC object to sliders so that they actually shows the values they are intended to so. So I add functionality to GameAgents.cs
GameAgents.cs
public class GameAgents : MonoBehaviour {
public Slider energyBar;
public Slider healthBar;
and then the end of Awake():
PlayerLogic pc = player.GetComponent(); pc.energyBar = energyBar; pc.healthBar = healthBar;
Drag-and-drop sliders from the HUD to energyBar and healthBar. And next, it is time to revise PlayerLogic and add functionality there.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class PlayerLogic : MonoBehaviour, CharacterInterface {
// Sliders for displaying energy and health
public Slider energyBar;
public Slider healthBar;
// how much energy maintaining invisibility costs
public float invisibilityCostInterval = 1.0f;
public int invisibilityCost = 5;
// Delay before start screen is loaded after dying
public float startScreenDelay = 2.0f;
public int startEnergy = 0;
public int startHealth = 100;
public const int MAX_ENERGY = 100;
public const int MAX_HEALTH = 100;
// definitions for saving and loading dats
public const string HEALTH_KEY = "h";
public const string ENERGY_KEY = "e";
public const string CURRENT_LEVEL_KEY = "c";
public const string LAST_DOOR_KEY = "d";
private int health;
private int energy;
private bool invisible;
// effects for later use. Grayscale effect is used when
// the PC dyes and Glow and AudioLowPassFilter are use
// when PC is invisible. Camera should have these components
// attached.
private GrayscaleEffect grayscaleEffect;
private GlowEffect glowEffect;
private AudioLowPassFilter audioLowpassFilter;
void Awake () {
invisible = false;
glowEffect = GetComponentInChildren();
if (!glowEffect) {
Debug.LogError("PlayerLogic.Awake(): Camera does not have GlowEffect component");
}
else {
glowEffect.enabled = false;
}
grayscaleEffect = GetComponentInChildren();
if (!grayscaleEffect) {
Debug.LogError("PlayerLogic.Awake(): Camera does not have GrayscaleEffect component");
}
else {
grayscaleEffect.enabled = false;
}
audioLowpassFilter = GetComponentInChildren();
if (!audioLowpassFilter) {
Debug.LogError("PlayerLogic.Awake(): Camera does not have AudioLowpassFilter component");
}
else {
audioLowpassFilter.enabled = false;
}
ReadSave();
}
void Update () {
// display in HUD the current values of energy and health
energyBar.value = energy;
healthBar.value = health;
if (health <= 0) {
// if dead do nothing...
return;
}
// turning invisible with Fire1 or "o"
if (Input.GetButton("Fire1") || Input.GetKey("o")) {
// invisibility
if (!IsInvoking()) {
// Invisibility started. Enabling effects
// and start tick reducing energy
glowEffect.enabled = true;
audioLowpassFilter.enabled = true;
InvokeRepeating("MaintaingInvisibility", 0.0f, invisibilityCostInterval);
}
} else {
// not invisible
if (IsInvoking()) {
// but the PC was invisible in the last frame
// disabling the effects
glowEffect.enabled = false;
audioLowpassFilter.enabled = false;
CancelInvoke();
// and setting internal state to visible
invisible = false;
}
}
}
public static void DeleteSave() {
// Data is store in PlayerPrefs. Deleting the data
PlayerPrefs.DeleteKey(CURRENT_LEVEL_KEY);
PlayerPrefs.DeleteKey(ENERGY_KEY);
PlayerPrefs.DeleteKey(HEALTH_KEY);
PlayerPrefs.DeleteKey(LAST_DOOR_KEY);
}
public void ReadSave () {
// reading the saved data
int e = PlayerPrefs.GetInt(ENERGY_KEY);
int h = PlayerPrefs.GetInt(HEALTH_KEY);
// if health is zero, the PC just died and
// and we go back to max
if (h > 0) {
energy = e;
health = h;
}
else {
energy = startEnergy;
health = startHealth;
}
}
bool CharacterInterface.IsInvisible () {
return invisible;
}
void CharacterInterface.ReceiveDamage (int amount) {
if (amount < 0) {
Debug.LogError("PlayerLogic.RecieveDamage() called with negative damage. Ignoring");
return;
}
health -= amount;
if (health <= 0) {
health = 0;
grayscaleEffect.enabled = true;
Invoke("StartScreen", startScreenDelay);
}
}
void CharacterInterface.PowerUp (int _energy, int _health) {
if (_energy < 0 || _health < 0) {
return;
} energy += _energy;
if (energy > MAX_ENERGY) {
energy = MAX_ENERGY;
}
health += _health;
if (health > MAX_HEALTH) {
health = MAX_HEALTH;
}
}
bool CharacterInterface.CanUseHealth() {
// return if the PC needs health from Powerup. If not
// the power-up won't active
if ( health < MAX_HEALTH) {
return true;
}
else {
return false;
}
}
bool CharacterInterface.CanUseEnergy() {
if ( energy < MAX_ENERGY) {
return true;
}
else {
return false;
}
}
void CharacterInterface.Save(string levelName, string door) {
Debug.Log ("PlayerLogic.Save(" + levelName + ")");
PlayerPrefs.SetInt(ENERGY_KEY, energy);
PlayerPrefs.SetInt(HEALTH_KEY, health);
PlayerPrefs.SetString(CURRENT_LEVEL_KEY, levelName);
PlayerPrefs.SetString(LAST_DOOR_KEY, door);
}
public void Save () {
Debug.Log ("PlayerLogic.Save() called.");
((CharacterInterface)this).Save (Application.loadedLevelName, "");
}
void Start() {
Transform startPosition = null;
string door = PlayerPrefs.GetString(LAST_DOOR_KEY);
if (door != "") {
GameObject doorObj = GameObject.Find(door);
if (doorObj) {
startPosition = doorObj.transform.Find("spawn");
if(startPosition == null) {
Debug.LogError ("PlayerLogic.Start(): " + doorObj.name + " has now spawn point");
}
}
}
if(startPosition == null) {
GameObject ps = GameObject.FindWithTag("PlayerStartPoint");
if (startPosition) {
startPosition = ps.transform;
}
else {
Debug.LogError("PlayerLogic.Start(): level has not StartPosition waypoint");
}
}
Debug.Log("PlayerLogic.OnStart(): spawning the PC at " + startPosition.name );
transform.rotation = startPosition.transform.rotation;
transform.position = startPosition.position;
CancelInvoke();
invisible = false;
glowEffect.enabled = false;
audioLowpassFilter.enabled = false;
}
private void MaintaingInvisibility () {
// ticks while invisibility is maintained
// reduce energy and quits if energy runs out
energy = energy - invisibilityCost;
invisible = true;
if (energy < 0) {
energy = 0;
invisible = false;
glowEffect.enabled = false;
audioLowpassFilter.enabled = false;
CancelInvoke();
}
}
private void StartScreen () {
Application.LoadLevel(0);
}
}
