- Home /
How To Make Health Decrease
I am very new to Unity Script and am in the middle of learning it. One thing I want to do is create a variable(e.g. health) which automatically decreases after a few seconds. I understand Time.deltaTime means every second. This is the script I have made:
//Health Textures
var health9 : Texture2D;
var health8 : Texture2D;
var health7 : Texture2D;
var health6 : Texture2D;
var health5 : Texture2D;
var health4 : Texture2D;
var health3 : Texture2D;
var health2 : Texture2D;
var health1 : Texture2D;
//Intigers
static var Player_Health = 9;
//Textures
var HealthGUI : GUITexture;
switch (Player_Health)
{
case 9:
HealthGUI.texture = health9;
break;
case 8:
HealthGUI.texture = health8;
break;
case 7:
HealthGUI.texture = health7;
break;
case 6:
HealthGUI.texture = health6;
break;
case 5:
HealthGUI.texture = health5;
break;
case 4:
HealthGUI.texture = health4;
break;
case 3:
HealthGUI.texture = health3;
break;
case 2:
HealthGUI.texture = health2;
break;
case 1:
HealthGUI.texture = health1;
//Don't forget to add a death script here!
break;
}
function Update()
{
Player_Health -= Time.deltaTime;
}
I am not sure why the last function doesn't work. It may be something to do with thee function that I am not aware of(I am a noob) or something wrong with the switch thing. Please tell me how to do this(all I want is Player_Health to decrease every second-I can mess with other things later) Thanks for helping and reading!
Answer by robertbu · May 31, 2013 at 05:48 PM
Time.deltaTime is the fraction of a second that has elapsed since the last frame. It is not "every second." You declare your Player_Health as:
static var Player_Health = 9;
which makes it an integer. So I would expect it to go to 0 almost immediately (9 frames). What you want is to make it a float:
static var Player_Health = 9.0;
Then in your switch statement you would round it to an integer:
switch (Mathf.RoundToInt(Player_Health)) {
Note that you switch statement is not inside Update (or any function), so it will only be executed once. I think you can to call it every frame, or use Invoke() to call it at a regular interval. Putting it all together, you get something like:
#pragma strict
//Health Textures
var health9 : Texture2D;
var health8 : Texture2D;
var health7 : Texture2D;
var health6 : Texture2D;
var health5 : Texture2D;
var health4 : Texture2D;
var health3 : Texture2D;
var health2 : Texture2D;
var health1 : Texture2D;
//Intigers
static var player_Health = 9.0;
var speed = 0.5;
//Textures
var HealthGUI : GUITexture;
function Update()
{
player_Health -= Time.deltaTime * speed;
if (player_Health < 0.0)
player_Health = 0.0;
SetHealth();
}
function SetHealth() {
switch (Mathf.RoundToInt(player_Health))
{
case 9:
HealthGUI.texture = health9;
break;
case 8:
HealthGUI.texture = health8;
break;
case 7:
HealthGUI.texture = health7;
break;
case 6:
HealthGUI.texture = health6;
break;
case 5:
HealthGUI.texture = health5;
break;
case 4:
HealthGUI.texture = health4;
break;
case 3:
HealthGUI.texture = health3;
break;
case 2:
HealthGUI.texture = health2;
break;
case 1:
HealthGUI.texture = health1;
//Don't forget to add a death script here!
break;
}
}
Answer by Jamora · Jun 01, 2013 at 08:24 AM
I would use a coroutine here. Coroutines are sort of like a new thread (more like timesharing) that can stop execution and resume at the same point next frame.
forgive my JS, I usually use C#...
#pragma strict
var Player_Health = 9;
function StartDecreasingHealth(){
StartCoroutine("SetHealth");
}
function StopDecreasingHealth(){
StopAllCoroutines();
}
function SetHealth() {
while(true)
{
switch (player_Health)
{
case 9:
HealthGUI.texture = health9;
break;
case 8:
HealthGUI.texture = health8;
break;
case 7:
HealthGUI.texture = health7;
break;
case 6:
HealthGUI.texture = health6;
break;
case 5:
HealthGUI.texture = health5;
break;
case 4:
HealthGUI.texture = health4;
break;
case 3:
HealthGUI.texture = health3;
break;
case 2:
HealthGUI.texture = health2;
break;
case 1:
HealthGUI.texture = health1;
//Don't forget to add a death script here!
//You can also stop the coroutine here, since we're dead (dying?)
StopAllCoroutines();
break;
}
//decrease health for next tick
Player_Health -= 1;
/**
* set the waiting time in seconds here. The script will continue execution from here in 1 second,
* i.e. go back to the beginning of the while loop
**/
yield WaitForSeconds(1);
}
}
Now, whenever you call StartDecreasingHealth() the health drops by oen every second. StopDecreasingHealth() stops the decrese.
I would also use an array or list for the health images. Makes it easier on the eyes.
Answer by raybarrera · May 31, 2013 at 05:49 PM
Time.deltaTime doesn't actually mean "every second", it means time since the last frame.
Your approach is probably not working because health is an int, but you are decreasing it by a tiny float, which is probably just rounding back up to the nearest whole value.
What you'll actually want to do is create a "tick" that subtracts 1 every second, rather than subtract the Time.deltaTime. Like so:
var tickInterval : float = 1;
var counter : float = 0;
function Update(){
if(counter < tickInterval){
counter += Time.deltaTime;
}else{
Player_Health -= 1;
counter = 0;
}
}
Answer by aldonaletto · May 31, 2013 at 05:49 PM
You should declare Player_Health as a float - the way you did, Player_Health is assumed to be an integer by the JS compiler:
static var Player_Health: float = 9;
or, alternatively:
static var Player_Health = 9.0; // assigning a float constant defines the variable as float
I prefer the first alternative, since the variable type is explicitly declared and will not be changed if we later modify the initialization constant.
Though this would work, his switches would not, because the chances of the health actually equalling a whole number would be small.
Your answer
Follow this Question
Related Questions
Spinning Pointer that reacts when health drops 0 Answers
Player Health Damage 2 Answers
Calling a variable from one script to another 1 Answer
Decrease life from another script 1 Answer
Life/Health Bar 0 Answers