Why Does Running This Script Crash My Computer?

Im trying to make a simple script that sets a player health and lowers it when they walk into spikes. I previously asked a similar question and one of the mods gave me the wrong answer and then rejected the question.

	public float health = 100f;
	public AudioClip Hurt;
	AudioSource Audio;
	void Start(){
		Audio = GetComponent<AudioSource> ();
	}

	void OnTriggerStay(Collider other){
		while(health > 0f){
			if (other.gameObject.tag == ("Spike")) {
				Invoke("Damage",2);
			}
		}
	}
	void Damage(){
		health -= 10f;
		Audio.clip = Hurt;
	}

it works fine if i don’t use invoke except it takes away all my health instantly. When i changed it to invoke or use a co-routine it crashed my computer.

I want to make it do 10 damage every second. If there is another way around this can you please tell me or if im doing something wrong can you give me a way to fix it.

Thanks

Mods can you not reject this unless you are actually going to give me an answer that works.

A while loop continues running the code within it while the passed in condition is true. In thise case, the condition is that health is > 0. So you enter this code and will never get out of it. Invoke and CoRoutines are not separate threads. They run cooperatively within your main thread. So even though you are calling Invoke, you stay in the while loop forever in your thread, and you never give the main thread a chance to run the Invoked code.

The simple solution is to say “if (health > 0)” instead. You may also want to add a flag indicating that you are removing the health, like so:

bool removingHealth;

void OnTriggerStay(Collider other){
     if(health > 0f && !removingHealth){
         if (other.gameObject.tag == ("Spike")) {
             removingHealth = true;
             Invoke("Damage",2);
         }
     }
 }
 void Damage(){
     health -= 10f;
     Audio.clip = Hurt;
     removingHealth = false;
 }

Hello new user :slight_smile:

So what your script is doing is Calling Damage Continuously after 2 sec (hope you get me what i am trying to say)

If you want to damage 10 every second then you can do like this

bool damageNow = true;

 void OnTriggerStay(Collider other){
      while(health > 0f){
             if (other.gameObject.tag == ("Spike") && damageNow) {
                 Damage();
                 damageNow = false;
                 Invoke("PutDamageTrue",1f);
             }
         }
     }
     void Damage(){
         health -= 10f;
         Audio.clip = Hurt;
     }

void PutDamageTrue ()
{
 damageNow = true;
}

Hope you get your answer :slight_smile:
If not, please explain a little more what you exactly want.