- Home /
Health not counting down?
My health is not counting down in this script:
#pragma strict
var tex1 : Texture;
var tex2 : Texture;
var tex3 : Texture;
var tex4 : Texture;
var tex5 : Texture;
var health : float = 100.0;
private var maxHealth : float = 100.0;
private var enterCollider : boolean = false;
//Damage Collider
function OnTriggerEnter (Col : Collider)
{
if(Col.gameObject.tag == "Enemy")
{
enterCollider = true;
Debug.Log("Is inside collider");
}
}
function OnTriggerExit (Col : Collider)
{
if(Col.gameObject.tag == "Enemy")
{
enterCollider = false;
}
}
function Update ()
{
//Health countdown whilst in the damage collider
if(health > 0 && enterCollider == true)
{
health -= Time.deltaTime * 20;
}
if(health >= 0)
{
yield (WaitForSeconds (1));
Application.LoadLevel("Deade");
}
//Normal health regeneration
if(health >= 0 && enterCollider == false)
{
health += Time.deltaTime * 5;
}
//When health reaches 100, set to maxHealth
if(health > maxHealth)
{
health = maxHealth;
}
}
function OnGUI ()
{
if (health <= 70)
{
GUI.DrawTexture(Rect(0,0, Screen.width, Screen.height), tex1);
}
if (health <= 45)
{
GUI.DrawTexture(Rect(0,0, Screen.width, Screen.height), tex2);
}
if (health <= 25)
{
GUI.DrawTexture(Rect(0,0, Screen.width, Screen.height), tex3);
}
if (health <= 10)
{
GUI.DrawTexture(Rect(0,0, Screen.width, Screen.height), tex4);
}
if(health <= 0)
{
GUI.DrawTexture(Rect(0,0, Screen.width, Screen.height), tex5);
}
}
are OnTriggerExit/Enter, uh... triggering? If not check if your tags are set correctly and if you have rigidbodies attached.
you have
if (health >= 0)
{
yield (WaitForSeconds (1));
Application.LoadLevel("Deade");
}
I'm fairly sure that should be
if(health <= 0)
if(health >= 0) { yield (WaitForSeconds (1)); Application.LoadLevel("Deade"); }
seems weird to me... Your game will keep reloading this scene as long as ur health is higher than 0... Is that the desired behaviour? and also u can't yield in Update function... you would need to start a coroutine from it which would yield in it
Answer by TKS_Keeper · May 27, 2014 at 08:55 PM
You have a few problems here. I'm supplying some cleaned up code with some (potential) fixes here.
Your key issues were:
Misuse of yield within a noncoroutine.
Not using
else if
orelse
logical blocks
Coroutines are tricky but powerful tools. They require explicitly being started through the MonoBehaviour.StartCoroutine method. See for details on this. http://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html
They next issue was that because many of the logical blocks could activate together there was a lot of unexpected behavior. This was especially bad in the OnGui
method.
I'd suggest becoming familiar with using the debugger, and stepping through your code if you have problems like this. As has been pointed out by others, there were conditionals which were probably not evaluating as intended in several places and without the 'else if' and 'else' usage your code was executing a lot of unnecessary and potentially disruptive code. (Rule of thumb, if one thing should happen and not the others, then 'else' and 'else if' are your friends)
# pragma strict
var tex1 : Texture;
var tex2 : Texture;
var tex3 : Texture;
var tex4 : Texture;
var tex5 : Texture;
var health : float = 100.0;
private var dead : bool = false;
private var maxHealth : float = 100.0;
private var enterCollider : boolean = false;
var damagePerSecondOnContact : float = 20;
var healthRegeneratedPerSecond : float = 5;
//Damage Collider
function OnTriggerEnter(Col : Collider) {
if (Col.gameObject.tag == "Enemy") {
enterCollider = true;
Debug.Log("Is inside collider");
}
}
function OnTriggerExit(Col : Collider) {
if (Col.gameObject.tag == "Enemy") {
enterCollider = false;
}
}
function Update() {
if(dead){
health = 0;
return;
}
//check for health exceeding maxHealth and correct if needed
if (health > maxHealth) {
health = maxHealth;
}
if (health > 0) {
//We are alive! Check if we should heal or take damage
if(enterCollider == true){
//take damage
health -= Time.deltaTime * damagePerSecondOnContact;
Debug.Log("Was damaged to " + health);
}
else{
//heal (a heal delay might be good, we may be regenerating faster than collisions can cause damage)
health += Time.deltaTime * healthRegeneratedPerSecond;
Debug.Log("Was healed to " + health);
}
}
else if (health <= 0) {
StartCoroutine(OnHealthZero()); //THIS WAS WHAT WAS MISSING
}
}
function OnGUI() {
if (health <= 0 || dead) {
GUI.DrawTexture(Rect(0, 0, Screen.width, Screen.height), tex5);
}
else if (health <= 70) {
GUI.DrawTexture(Rect(0, 0, Screen.width, Screen.height), tex1);
}
else if (health <= 45) {
GUI.DrawTexture(Rect(0, 0, Screen.width, Screen.height), tex2);
}
else if (health <= 25) {
GUI.DrawTexture(Rect(0, 0, Screen.width, Screen.height), tex3);
}
else if (health <= 10) {
GUI.DrawTexture(Rect(0, 0, Screen.width, Screen.height), tex4);
}
}
/**
* Coroutine function which runs the death sequence.
* @see http://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html
*/
function OnHealthZero(){
//we indicate that the player died IMMEDIATELY so as to stop bad updates
Debug.Log("Is dead now");
dead = true;
yield(WaitForSeconds(1));
Application.LoadLevel("Deade");
}