Invulnerability C#++, Unity2D

Okay so I have tried a few different ways to make this temporary invulnerability work, keep failing.

I’m still fairly new to coding, so I don’t fully understand alot of the “leet speak” people usein forums/reddits/etc.

using System.Collections;
using UnityEngine;


namespace SAE
{

    public class LightSpeedArmorAbility : Health
    {
        public bool invincibleAbility;
        public bool timeoutActive;
        public float CooldownTime; // A cooldown time
        public float cooldownUntilNextPress; // The determined value of where the time limit needs to reach.

        /// <summary>
        /// Start was called in the script I was using inheritance from, so use awake instead.
        /// </summary>
        public void Awake()
        {
            cooldownUntilNextPress = 60; // Sets cooldownuntilNextPress to 60 seconds.  
            invincibleAbility = false; //Set to false
        }


        /*private void OnTriggerEnter(Collider other)
        {
            if (other.gameObject.tag == "Enemy")
            {
                hp += float.MaxValue;
                invincibleAbility = true; // makes this whole function unusable since invincible is no longer false
            }
           
        }*/

        private void Update()
        {
            CooldownTime += Time.deltaTime; // CoolDownTime adds up
            if (CooldownTime >= cooldownUntilNextPress) // once greater than 60 seconds you can use input
            {
                if (Input.GetKeyDown(KeyCode.DownArrow))
                {
                    hp += float.MaxValue;
                    invincibleAbility = true; // makes this whole function unusable since invincible is no longer false
                    StartCoroutine(BeginTimeout());
                }

            }
        }

        IEnumerator BeginTimeout()
        {
            timeoutActive = true;
            yield return (8f);
            CooldownTime = 0;
            invincibleAbility = false;
            timeoutActive = false;
        }
    }
}
using UnityEngine;

namespace SAE
{
    /// <summary>
    /// A Starting point for a Health script, intended to be expanded to meet indivdual games needs, either via
    /// direct modification or inheritence.
    /// </summary>
    public class Health : MonoBehaviour
    {
        [SerializeField] public int pointValue;
        protected ScoreTracker scoreTracker;
        [SerializeField] protected float hp;
        [SerializeField] protected float maxHp;
        [SerializeField] protected bool isAlive = true;
        [SerializeField] protected bool isVuln = true;
        public bool canHealOnKill = false;
        public int healthOnKill;
        [SerializeField] protected AudioEffectSO deathAudioEffect;
        [SerializeField] protected GameObject deathEffectPrefab;
        [SerializeField] protected HealthBar playerHealthBar;
        [SerializeField] protected LightSpeedArmorAbility lightSpeed; // Was trying somthing, so ignore this.

        public virtual void Start()
        {
            hp = maxHp;

            // Check to see if the gameobject is the player, if so assign the healthbar to be controlled by this script. (also set the max health of the bar!)
            if (tag.Contains("Player") && playerHealthBar == null)
            {
                playerHealthBar = GameObject.FindGameObjectWithTag("HealthBar").GetComponent<HealthBar>();
                playerHealthBar.SetMaxHealth((int) maxHp);
                Debug.Log("Max Health Set!");
            }

            lightSpeed.Awake(); // Was trying somthing, so ignore this.
            scoreTracker = GameObject.FindGameObjectWithTag("ScoreSystem").GetComponent<ScoreTracker>();
        }

        public virtual void ReceiveDamage(float dmg)
        {
            if (!isAlive && !isVuln)
            {
                return;
            }

            hp -= dmg;
            OnDamage();
            OnHealthChange();

            if (hp <= 0)
            {
                isAlive = false;
                Death();
            }
        }

        public virtual void AddHP(float amt)
        {
            hp += amt;
            hp = Mathf.Clamp(hp, 0, maxHp);
            OnHealthChange();
        }

        protected virtual void Death()
        {
            OnHealthChange();
            OnDeath();
            Destroy(gameObject);
            DoDeathEffects();
        }

        protected virtual void DoDeathEffects()
        {
            if (deathEffectPrefab != null)
            {
                Instantiate(deathEffectPrefab, transform.position, deathEffectPrefab.transform.rotation * transform.rotation);
            }

            if (deathAudioEffect != null)
            {
                deathAudioEffect.Play2D();
            }
        }

        // this is a good starting point, but eventually you might want to pass more context
        protected virtual void OnDamage()
        {
        }

        // To be called whenever the health changes, useful for updating relevant values
        protected virtual void OnHealthChange()
        {
            // Call SetHealth on the UI healthbar and set it to current health
            if (playerHealthBar != null)
            {
                playerHealthBar.SetHealth((int)hp);
                Debug.Log("Healthbar Updated");
            }
        }

        public virtual void OnDeath()
        {
            if (GameObject.FindGameObjectWithTag("Player").GetComponent<Health>().canHealOnKill == true)
            GameObject.FindGameObjectWithTag("Player").GetComponent<Health>().AddHP(GameObject.FindGameObjectWithTag("Player").GetComponent<Health>().healthOnKill);
            scoreTracker.addScore(pointValue);
            scoreTracker.increaseCombo();
        }
    }
}

Basically what I am trying to do, is when I hit the down arrow; I want # amount of seconds where I can’t take damage, its a certain special ability assigned to the “body” type.

I have managed to make a Decoy drop and a instant 180 for these special abilities of other body types and I am trying to make this last ability standalone in its own script.

(I did comment out the on trigger, but I have tried and failed on using the on trigger function)

So any advice, tips or insight on how to get this invulnerability script to work, would be greatly appreciated.

Thank you in advance for even taking the time to read this.

I’ve read multiple forums, post, etc. But nothing has helped so far.

Its a 2D platformer.

What is actually happening with it right now?

You have this line:

invincibleAbility = true; // makes this whole function unusable since invincible is no longer false

But the comment is misleading since the function will continue to run even when this value is set to true, you have nothing that says otherwise.

Given that, you could spam press the DownArrow and get unlimited invincibility.

Right now, I still take damage, but the inspector updates to say if “is active” or not… but it doesn’t stop any health being lost du to enemy attacks.

That line is from a code a tried I tried to follow along with, so I was hoping if that code was successful I would get answer/translation to that. But it didn’t work, so I am left with that riddle of what the original author of said script was trying to make apparent.

Also
"

  • if (CooldownTime >= cooldownUntilNextPress) // once greater than 60 seconds you can use input
  • {
  • if (Input.GetKeyDown(KeyCode.DownArrow))
  • {(etc.)
    "

Actually makes it’s so you can only press down key every 60 seconds, which even with the script not causing invulnerability, the down key does nothing until the timer is reached.
It works the same in my decoy script and Flip facing script… So you have a cool-down on being able to use down arrow… and yeah the Invulnerability scripts I managed to find DON’T seem to work.

All I am trying to achieve is a script that causes the player to not take damage for 5-8 seconds after Down Key is successfully activated.
I’m open to completely different ways to tackle this… I only added scripts as a reference as to the code used in an attempt.

I am trying to also achieve said invulnerability in a script separate from health(hence using inheritance to try and get around using the health script directly).

As stated in my OP, I am still in the very early stages of learning scripting/unity - So I am not 100% on how to go about many things… and more annoyingly… most post/tutorials use either a very similar structure to the code I showed above, or their not implemented well.

Even like a bubble ‘SHIELD’ would work for me, if anyone has some insight on how to implement that, would be greatly appreciated.

The way you have it right now the cooldown only resets after 8 seconds judging by your IEnumerator here:

        IEnumerator BeginTimeout()
        {
            timeoutActive = true;
            yield return (8f); // <<< here you are waiting 8 seconds
            CooldownTime = 0; // <<< THEN you reset the cooldown
            invincibleAbility = false;
            timeoutActive = false;
        }

So you have an ~8 second time span where you can just spam the DownArrow. Unless I’m missing something there.

But despite this, your issue is that you never set isVuln to false in your Health script :slight_smile:

1 Like

That 8 seconds was how long the shield last for(according to the comments/posts anyway), not cool downs between button spam. (Edit: Nevermind, in my frustraton, I must of cut and pasted it in the wrong area, that’s a big “MY BAD” on my part)

That is probably why I am getting overridden in the other script, thanks… though one my earlier attempts was to set isVuln but that was through the script that inherits from health script.

I’ll try through a function in Health script but call it in the other script, thank you for pointing that out, greatly appreciated.

Also explain why others were wearing by the script I copied/tried to create an alt version for after failed attempts)