Invincible Script Won't Work Correctly?

Hello, I have had some of this script made for me on the Unity answers, but it doesn’t work correctly. When I grab the powerup and turn invincible, it stays invincible forever. It doesn’t stop when it’s supposed to stop(I have a certain time set).The person and I could not figure out what’s wrong. So I decided to take things to the forums, since this is always the best place to go it seems, and I always get the help I need. Here’s my scripts:

Player Script:

public class ControllerScript : MonoBehaviour
{
	public float maxSpeed = 10f;
	//bool facingRight = true;
	public float coeffSpeedUp = 1100.5f;
	public float coeffSpeedUpTime = 1.5f;
	public float invincibleTime = 1.0f;
	[HideInInspector]
	public bool isInvincible = false;
	public Renderer invincibleIndicator;

	Animator anim;

	bool grounded = false;
	public Transform groundCheck;
	float groundRadius = 0.2f;
	public LayerMask whatIsGround;
	public float jumpForce = 700f;

	//public void OnCollisionEnter2D (Collision2D col);

	public void SetInvincible()
	{
				isInvincible = true;
		        invincibleIndicator.enabled = true;

				CancelInvoke ("SetDamageable"); // in case the method has already been invoked
				Invoke ("SetDamageable", invincibleTime);
		}

	void SetDamageable()
	{
		isInvincible = true;
		invincibleIndicator.enabled = false;
		}

	// Use this for initialization
	void Start () 
	{
		anim = GetComponent<Animator>();

		if ( !invincibleIndicator )
		{
			invincibleIndicator = transform.Find("InvincibleIndicator").renderer;
		}
		
		invincibleIndicator.enabled = false;

	}
	
	// Update is called once per frame
	void FixedUpdate () 
	{

				transform.Translate (5f * Time.deltaTime, 0f, 0f);

				grounded = Physics2D.OverlapCircle (groundCheck.position, groundRadius, whatIsGround);
				anim.SetBool ("Ground", grounded);

				anim.SetFloat ("vSpeed", rigidbody2D.velocity.y);

				if (!grounded)
						return;
						
		        //float move = Input.GetAxis ("Horizontal");

				//anim.SetFloat ("Speed", Mathf.Abs(move));

				//rigidbody2D.velocity = new Vector2 (move * maxSpeed, rigidbody2D.velocity.y);

	}

	void Update()
	{

		if (grounded  Input.GetKeyDown (KeyCode.Space)) 
		{
			anim.SetBool("Ground", false);
			rigidbody2D.AddForce(new Vector2(0, jumpForce));

		}
	}

	public void SpeedUp()
	{
		// Speed up the player
		coeffSpeedUp = 1.5f;
		
		CancelInvoke ("EndSpeedUp"); // in case the method has already been invoked
		Invoke ("EndSpeedUp", coeffSpeedUpTime);
	}
	
	void EndSpeedUp()
	{
		coeffSpeedUp = 1.0f; // back to normal
	}

	public IEnumerator StopSpeedUp() {

		Debug.Log( "StopSpeedUp()" );
		yield return new WaitForSeconds(1110.5f); // the number corresponds to the number of seconds the speed up will be applied
		coeffSpeedUp = 1110.5f; // back to normal
		Debug.Log( "back to normal" );
	}
}

Collision Script:

public class Collision : MonoBehaviour {

ControllerScript player;
	
	void Start()
	{
		player = GetComponent<ControllerScript>();
	}
	
	void OnCollisionEnter2D (Collision2D col)
	{
		// If the colliding gameobject is an Enemy...
		if(col.gameObject.tag == "Dangerous")
		{
			// check if player is NOT invincible
			if ( !player.isInvincible ) // this is the same as writing if(player.isInvincible == false)
			{
				// Find all of the colliders on the gameobject and set them all to be triggers.
				Collider2D[] cols = GetComponents<Collider2D>();
				foreach(Collider2D c in cols)
				{
					c.isTrigger = true;
				}
				// ... disable user Player Control script
				GetComponent<ControllerScript>().enabled = false;
			}
			// else the player IS invincible, destroy all obstacles in the way
			else
			{
				// destroy the Dangerous object
				Destroy (col.gameObject); // This is to destroy the obstacles
			}
		}
	}
}

Powerup Script:

public class PowerupScript : MonoBehaviour {


	void OnTriggerEnter2D(Collider2D other)
	{
				if (other.tag == "Player") {
						ControllerScript playerScript = other.gameObject.GetComponent<ControllerScript> (); // not sure about the syntax here...
						if (playerScript) {

								// call function on playerScript to set player to invincible
								playerScript.SetInvincible (); 
				                // We speed up the player and then tell to stop after a few seconds
				                playerScript.SpeedUp();

								// We speed up the player and then tell to stop after a few seconds
								//playerScript.coeffSpeedUp = 1110.5f;
								//StartCoroutine (playerScript.StopSpeedUp ());


						}
						Destroy (gameObject);
				}
		}
	
	}

Your “SetDamageable” function does the same thing as your “SetInvincible” function, instead of reversing the effect.

Also, are you sure you can Invoke a private function? That seems like it shouldn’t work.

So what should I do with the SetDamageable function? Remove it or set it to something else? As for your question, I’m pretty sure I can do that. If you think it’s better to change it, please tell me so I won’t have anymore problems.

You should change it so that it sets “isInvincible = false;” instead of “isInvincible = true;” like you have now.

Well, if the invincibleIndicator was being turned off correctly, then that’s working. If it wasn’t, try changing it to public. I don’t really know the answer to this one; I prefer coroutines and direct calls.

I changed the isInvincible, it didn’t affect anything. I still stay invincible forever, Just a note, when I get rid of all the invincibleIndicators, it allows me to collide with obstacles and die after about 4 seconds after getting the powerup. So I stay invincible for 4 seconds and then it turns off. I don’t know why this is, but maybe that can help us figure out what’s wrong.

I’m thinking of just dropping this little powerup of mine and updating it later on(since my skills lack). That is, if we can’t figure this out.

When I was new to scripting (and to a certain extent still) I often encountered situations like this, whereby my programming skill at the time wasn’t up to the job of implementing what I wanted. In the event that I couldn’t eventually figure it out I either modified or omitted the feature I was trying to program.

Then what usually happens is that a few months down the line something similar crops up and all of a sudden it’s obvious how it’s done, because of the programming knowledge you’ve gained along the way.

I’ve also lost count of the times I’ve looked at old code (that at the time of was immensely proud of) and wondered what on earth possessed me to approach it in such a convoluted and inefficient way.

Anyway I guess my point is don’t get too hung up about a particular problem you can’t solve, if it isn’t game breaking, move or adapt and at some point you’ll have learnt enough to implement it. And if it is game breaking, make a different game :mrgreen:

Got it, thanks for the advice. :slight_smile: