Code not executing to full extent. Maybe problem with yield?

After taking damage, the player is invulnerable and cannot shoot for a few seconds. The avatar blinks (renderer on and off) to reflect that state. This typically works fine.

However, when the player shoots at an enemy, gets hit, and the shot connects after receiving damage, the renderer and shooting are permanently set to the off position. The on/off code does not execute, and the player is never able to shoot again. As you can imagine, this is fairly game breaking. Any ideas? I’ve been struggling with this for the past 2 months or so.

Code for taking damage (decrease means health decrease)

static function Decrease(){
	var hs:GameObject=GameObject.Find("HealthSmall"); //health indicator
	var pShooting = FindObjectOfType(typeof(PlayerShootingJS)); //Shooting script
	
			
	if (playerInvulnerable == 0){	//Invulnerable = 0 means that the player is not invulnerable

		if (PlayerHealth < 10){ //Player knockback on damage
			if (m.transform.localScale.x > 0){
				m.transform.position.x = m.transform.position.x - 3;
		
			}else if(m.transform.localScale.x < 0){
				m.transform.position.x = m.transform.position.x + 3;
	
			}else{
				m.transform.position.x = m.transform.position.x - 3;
			}
			PlayerHealth--; //Reduce player health
		}
	
		hs.renderer.enabled = false; //reduce health indicator
		
		
	//Player invulnerable after taking damage. Blink player image.
	//Currently not working. Glitches when player kills enemy while invulnerable. Freezes renderer in off state and maintains permanent invulnerability.
			
		playerInvulnerable = 1; //Sets player to invulnerable
		pShooting.enabled = false; //Disables player's ability to shoot
		m.renderer.enabled = false; //blink code starts here
		yield WaitForSeconds (0.1);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.2);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.2);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.2);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.2);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.2);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.2);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.2);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.2);
		m.renderer.enabled = true; //Player is now fully visible, no more blinking
		playerInvulnerable = 0; //Removes invulnerability
		pShooting.enabled = true; //Player can shoot
		
		
	}
}

Code for enemy taking damage

var Health = 10; //EnemyHealth

function OnTriggerEnter (other: Collider) {
	if (other.tag=="Brainwave"){ //Brainwave is the projectile
		var bw:GameObject=GameObject.Find("playerProjectile");
		
		Health--; //Reduce health of enemy
		Destroy (GameObject.FindWithTag("Brainwave")); //Destroys projectile
		PlayerHealth.score = PlayerHealth.score + 125; //Increases score
	}
	if (other.tag=="Player"){
		PlayerHealth.Decrease(); //Calls function that does damage to player and makes him invulnerable

	}
}

function Update(){
	if (Health <=0){ //If enemy health is zero or less, destroy enemy
		Destroy(gameObject);
	}
}

Code for projectile shooting

var projectile : Rigidbody;
var speed = 10; //projectile speed
private var allowfire : boolean = true; //whether or not the player can shoot. Adds a cooldown between shots

function Update () {
	if ( Input.GetButton ("Fire1")(allowfire)) { //Press fire button, call Fire function
		Fire();
	}
}


function Fire(){
	var m:GameObject=GameObject.Find("MainChar"); //sets m to MainChar; Reference
	
			
	allowfire=false;	//Shooting cooldown
	var projectileStartPosition = m.transform.position; //Sets projectile start position
	projectileStartPosition.y += .4;

	clone = Instantiate(projectile, projectileStartPosition, m.transform.rotation); //creates new projectile

	
	if (m.transform.localScale.x > 0){ //Sets velocity and direction
		clone.velocity = new Vector3(speed,0,0);
		
	}else if(m.transform.localScale.x < 0){
		clone.velocity = new Vector3(-speed,0,0);
	
	}else{
		clone.velocity = new Vector3(speed,0,0);
	}
	
	Destroy (clone.gameObject, 0.3); //Removes the projectile from the scene
	yield WaitForSeconds(0.3); //Reduces firing speed
	allowfire=true; //Shooting enabled again

	
	
}

How many times do you want your character to blink?

A full on off cycle, about 11 times. I’m just saying that based on the code I have up there, though. I never really thought about it in terms of how many times. I just wanted to use it as feedback, On and off quickly at first, but then as the total invulnerability time reached its end, I wanted it to slow down, to signal the end to the player. That’s why my “waitforseconds” increases towards the end.

Something like this should work (I can’t always get WaitForSeconds to work, so I use Time.time):

static function Decrease(){

    var hs:GameObject=GameObject.Find("HealthSmall"); //health indicator

    var pShooting = FindObjectOfType(typeof(PlayerShootingJS)); //Shooting script

    

            

    if (playerInvulnerable == 0){   //Invulnerable = 0 means that the player is not invulnerable

 

        if (PlayerHealth < 10){ //Player knockback on damage

            if (m.transform.localScale.x > 0){

                m.transform.position.x = m.transform.position.x - 3;

        

            }else if(m.transform.localScale.x < 0){

                m.transform.position.x = m.transform.position.x + 3;

    

            }else{

                m.transform.position.x = m.transform.position.x - 3;

            }

            PlayerHealth--; //Reduce player health

        }

    

        hs.renderer.enabled = false; //reduce health indicator

        

        

    //Player invulnerable after taking damage. Blink player image.

    //Currently not working. Glitches when player kills enemy while invulnerable. Freezes renderer in off state and maintains permanent invulnerability.

            

        playerInvulnerable = 1; //Sets player to invulnerable

        pShooting.enabled = false; //Disables player's ability to shoot

        var timeAmount = 0;
        var waitTime1 = 0.1;
        var waitTime2 = 0.2;
        var timesBlinked1 = 0;
        var timesBlinked2 = 0;
        
        while(playerInvulnerable == 1)
        {
                pShooting.enabled= false;
                if(Time.time > timeAmount)
                {
                          if(timesBlinked1 % 14 !== 0)
                         {
                         timesBlinked1 += 1;
                         m.renderer.enabled = !m.renderer.enabled;
                         timeAmount += waitTime1;
                         }
                         else if(timesBlinked2 % 8 !== 0)
                        {
                         timesBlinked2 += 1;
                         m.renderer.enabled = !m.renderer.enabled;
                         timeAmount += waitTime2; 
                         }
                         else
                         {
                         timesBlinked1 = 0;
                         timesBlinked2 = 0;
                         m.renderer.enabled = true;
                         pShooting.enabled = true;
                         playerInvulnerable = 0;
                         }
               }
        }
    }

}

I really hope this works :smile: If not, tell me and I will attempt to fix it.

Thanks JSierra! It’s actually throwing an error on lines 68 and 74 "is not’ can’t be used with a value type (‘int’)

I went to see if I could fix it, but the code is a little unfamiliar to me. Is this C#? This is within a UnityScript script.

On the two lines in question, the “!== 0” should read “!= 0”. Also, the code is UnityScript.

Thanks jgodfrey. The code doesn’t throw an error after that, but neither the invulnerability nor the blinking work anymore. I’m fiddling with it now to see if I can figure it out, but help is appreciated.

EDIT:
I don’t really understand this line:

if(Time.time > timeAmount){

Time.time is simply the time elapsed since the level has started, right? If so, isn’t this just an infinitely increasing number? What is its utility here?

Anybody know what the problem is with the code I posted? I’d really like to know why it’s not working, more than just being given the answer, though I do appreciate the help.

EDIT 2: I used Time.time to set a variable at the beginning of injury (initialHurtTime). I then check it on update. If Time.time - initialHurtTime > 3 (in other words, if more than three seconds have elapsed since the time the player was hurt), I enable the renderer, shooting, and collider. This is an ok patch. It’s no longer game breaking, but it’s still not a pretty, as the player still completely disappears for three seconds when the glitch happens. I’m still searching for a definitive answer to this.

Update: I just tried to attach this code to a projectile shot from one of my enemies, and it has the same effect as the other code. I’ve been trying to draw parallels. The only common trait seems to be a projectile that is colliding with the player.

function OnTriggerEnter (other: Collider) {
	if (other.tag=="Player"){
		PlayerHealth.Decrease(); //Calls function that does damage to player and makes him invulnerable

	}
}

Also, this decrease function works without a hitch in one other instance where I directly call it, without any collision.

Holy crap - I think it’s fixed! lol.

I was writing a different (much simpler) script, and realized that yield waitforseconds was causing it to fail. When I moved it to its own function, everything magically worked. Note: It did NOT work as a static function. I tried the same thing here and it worked.

So, essentially, in my decrease function, I set a variable to 1. When update sees that variable at 1, it calls the new invulnerability function. The variable is set back to 0 at the end of the invulnerability function, and the cycle repeats the next time the player is hurt.

Does anybody have any idea why this works?

static function Decrease(){
	var hs:GameObject=GameObject.Find("HealthSmall"); //health indicator
	pShooting = FindObjectOfType(typeof(PlayerShootingJS)); //Shooting script
	
	
			
	if (playerInvulnerable == 0){	//Invulnerable = 0 means that the player is not invulnerable

		if (PlayerHealth < 10){ //Player knockback on damage
			if (m.transform.localScale.x > 0){
				m.transform.position.x = m.transform.position.x - 3;
		
			}else if(m.transform.localScale.x < 0){
				m.transform.position.x = m.transform.position.x + 3;
	
			}else{
				m.transform.position.x = m.transform.position.x - 3;
			}
			PlayerHealth--; //Reduce player health
		}
	
		hs.renderer.enabled = false; //reduce health indicator
			

		playerInvulnerable = 1; //Update will run Invulnerable(); when this is set to 1
		
		
		

	}
}
function Update(){
	if (playerInvulnerable == 1){
		Invulnerable();
	}
}
function Invulnerable(){
		initialHurtTime = Time.time;
		playerInvulnerable = 1; //Sets player to invulnerable
		pShooting.enabled = false; //Disables player's ability to shoot
		m.renderer.enabled = false; //blink code starts here
		yield WaitForSeconds (0.1);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.1);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.2);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.2);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.2);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.2);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.2);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.2);
		m.renderer.enabled = true;
		yield WaitForSeconds (0.2);
		m.renderer.enabled = false;
		yield WaitForSeconds (0.2);
		m.renderer.enabled = true; //Player is now fully visible, no more blinking
		playerInvulnerable = 0; //Removes invulnerability
		pShooting.enabled = true; //Player can shoot
}