Stop losing health when shield is up.

hi,

I made is shooter and when i press Ctrl i will cover myelf with a shield, but when i get close to the enemy they still hit me with there bullets and so i keep losing health.

I sort of want to absorb the dmg they do, what is the best way to do that? with destroy object??

atm i have this:

private GameObject shield;


void Start () {
	
	
	shield = GameObject.FindGameObjectWithTag("Shield"); 
	
	shield.GetComponent<MeshRenderer>().enabled = false;
	shield.GetComponent<MeshCollider>().enabled = false;

}

void Update () {
	
	if (Input.GetKey(KeyCode.LeftControl)) {
	
		shield.GetComponent<MeshRenderer>().enabled = true;
		shield.GetComponent<MeshCollider>().enabled = true;
					
		
	}else{
	
		shield.GetComponent<MeshRenderer>().enabled = false;
		shield.GetComponent<MeshCollider>().enabled = false;
	}
}

}

You didn’t show/tell how you take damage from your enemies. You could use a bool variable to indicate whether your shield is activated or not.

One thing to note is, it’s not efficient performance-wise to call GetComponent many times, like inside Update - Do this instead:

private GameObject shield;
private bool isShieldActive;

void start()
{
   shield = GameObject.FindWithTag(Tags.shield);
}

void Update()
{
   isShieldActive = Input.GetKey(KeyCode.LeftControl)); // this is valid because GetKey returns a bool
   shield.SetActive(isShieldActive);
}

And then somewhere in your code when your enemy hits/attacks you:

if (!isShieldActive)
{
   // deal damage
}

else don’t do anything… :slight_smile:

You can do it without a bool if you want, just:

shield.SetActive(Input.GetKey(KeyCode.LeftControl));

and then:

if (!shield.active)
{
  // deal damage
}

I would use a bool.

About the Tags that I used, it’s a class that I always like to use to store all my tags - it’s always better to keep things in one place and not scattered around. Because what if you changed your tag? - you would have to go and change it in numerous places.
A Tags sample would be:

Tags.cs

public class Tags
{
   public const string shield = "Shield"; // you can use static instead of const
   public const string player = "Player";
}

And then you can access your tags in a static manner (cuz you’re using const), like so:

if (collider.tag == Tags.player)
{
   // do something
}

EDIT: So here’s your enemy damage script that you commented:

void OnTriggerEnter (Collider other) 
{ 
	if(other.gameObject.tag == "Enemy_Bullet") 
	{ 
		Debug.Log("Hit"); 
		curHealth -= 3; 
		if(curHealth < 0) 
			Application.LoadLevel("gameover"); 
	}
}

Couple of notes:

  1. As I told you, use the Tags class
    idea to organize your tags better.
  2. The way you decreased your player’s
    health isn’t optimal. Again, we’d
    fall in to the same problem: what if
    you decided later on to change the
    damage amount? you would have to
    search, find, replace and update
    them all! - So it’s better to store
    the amount of damage in a variable.
    Where to store that variable? that
    depends on your game complexity and design, you
    could make it so that each enemy
    deals different damage - That way
    you would have a parent Enemy
    class and then derive from it, so
    you have Zombie, Mercenary,
    Goon, etc. Or, if you’re dealing
    with weapons and such, you could
    store the damage in your Bullet
    class, so each bullet does a
    different amount of damage (9mm,
    ShotgunShell, Rocket, etc) - I
    HIGHLY recommend you to learn about
    OOP (Object oriented programming) -
    There’s a lot of resources out
    there, for example.
    Another thing about taking damage, is that you should encapsulate the ‘taking damage’ code into a method, so you call TakeDamage(enemy.damage) - The benefit of this, is that what if you needed to do other things beside reducing the health? like play a ‘taking hit’ animation, or instantiating blood stains, etc.
    Finally, as per your original problem, you don’t need to destroy the bullet, you don’t even need to use bullets and instantiate them - just use raycast shooting. But since you’re using it this way, you could Recycle the bullet, instead of destroying it. More about object recycling (VERY USEFUL)

But if you wanna keep it simple and just destroy it, I don’t see any problem doing that:

if(other.gameObject.tag == "Enemy_Bullet") 
{
  Debug.Log("Hit");
  if (isShieldActive) // remember, use the shield idea I told you about
  {
     Destroy(other.gameObject);
     return;
  }
  curHealth -= 3;
  if(curHealth < 0)
  Application.LoadLevel("gameover");
}

What problems did you get doing that? - Did you debug? If not, you should. You can solve most of your problems and figure out what has gone wrong doing so. If you’re on Monodevelop, or VS.