NOOB (SERIES ONE) - Help With Health System

Hey guys, assume I’m a noob, (which means don’t get pissed if I don’t know something that seems obvious about unity.)

I am making a game with my brother and have to grey box the whole thing. Basically I do all the technical heavy lifting and he does story and art. This is all kind of irrelevant anyway. On to the reason I’m here.

Here is my objective for today. I am trying to create a script (preferably Unity script or c#) that I can apply to players and NPC’s that will give them a health system (Health values)(Hopefully with one of those neat adjustable slider components to create varying health’s) that will say “this guy has x health” and when he has “no health” he “dies.”

Now, this probably is a weird idea for more experienced users, but what I was thinking was, If I can accomplish this, Then I can create two more scripts for subtracting health. They would be similar except: one would be for melee, and one would be for guns (ranged.)

If this is a bad idea I am open to alternative ideas.

My end result is I want varying healths, and melee and ranged attack options. But like I said, I was just going to start with the health script.

Thank you for reading, and thank you in advance for any help.

how would they be different exactly? they both take a value of health away from the target… beyond that??

usually a “health script” has a method “ApplyDamage(number)” which takes health away… the melee/ranged/whatever is better handled by the thing doing the damage (it already knows what it is: melee, ranged or whatever).

So basically I should let a sword tell the script its melee and a gun tell it its ranged? This is good because I can then also have variable damage dependent on weapon.

Do you know how I would go about doing this?

Here is what I want to do.

-declare health variable
-declare base damage variable
-use update function for checking for “Fire1” input

I don’t really know what I’m doing, so if any of this is wrong let me know.

I GET IT.

I apply a basic distance limit, and let different weapons determine additional range.

How do I do that?

I realize if.get is wrong and apply is wrong but I don’t know how to tell unity correctly what I want. any help is greatly appreciated.

Hi KirA, so far I think you’re on a good track. Just a few side notes here and I’ll address your question.

First off, the whole if (get.input(“Fire1”)) is not correct syntax (as you pointed out) but writing code like this is actually a really useful technique called pseudocode. Basically, it’s a way of describing algorithms in a language-independent manner, and is super useful to get your point across without wasting time looking at syntax.

Second, for code use the [ CODE ] tags, instead of quote.

Anyways.

An easy way to divide up scripts is to make each one represent an action or an object. You probably don’t want to create a script to “Take Damage.” Instead, you want to create an Enemy script that has a function that lets him take damage. Since you said C# or UnityScript and I love C# I’m going to hijack the language in this thread:

using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour
{
    public float Health = 10.0f;
    // ... Other attributes of this class

    private float currentHealth;

    void Start()
    {
        currentHealth = Health;
    }

    public void TakeDamage(float damage)
    {
        currentHealth -= damage;

        if (currentHealth < 0)
        {
            // Destroy the game object, or do something else
            Destroy(gameObject);
        }
    }
}

This script would be applied to an Enemy object. So now we need a way to attack him.

using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour
{
    public float Damage = 10.0f;
    // ... Other attributes of this class

    // This is temporary.  Assign a GameObject with an Enemy script attached to it
    public GameObject EnemyToAttack;

    void Update()
    {
        if (Input.GetButtonDown("Fire1"))
        {
            EnemyToAttack.GetComponent<Enemy>().TakeDamage(Damage);
        }
    }
}

And then each time you click, he loses 10 health.

I’m not able to compile this code so I haven’t tested it but it should do what you want.

Erik

Ok, so

I copied and compiled the code.
and it works, but

In my test I have three unique game objects that represent enemies. I figured out how to assign the scripts to each (including the gameobject variable which was an awesome touch) and I can kill all the enemies. Only problem: It kills all enemies at once. how do I fix?

second question: I can assign both of these scripts to all “living” entities in my project? like Players and enemies?

For Q2: You could. However, obviously the player is probably going to have different behavior than the enemies. This could be a problem since when he takes damage he might react differently from the enemies, and vice versa. The way around this is through Inheritance. Inheritance basically allows you to extend a current class and add to it’s features. You’ll notice that Enemy and Player both inherit from MonoBehaviour, which allows you to use some of it’s methods and properties. So in your case, you could create a class named “Living”, that has the Health member and the TakeDamage method, and then extend it to add new methods (maybe when the player takes damage he bounces backwards, or the enemy is stunned, etc).

To answer #1, I think I’ll need context on how this game works. Is it like a shooter? An RTS? Right now the enemies are just abstractions…how are they “actually” being attacked?

EDIT: Here’s an example of inheritance I saw in another thread, explains it fairly well:

For Context It is a shooter, but I really also want melee abilities (comparable to at least minecraft.)

It is a wave-survival arcade fps.

To be specific I have like 3 - 5 different kinds of badguys who I want to all be compatible with being hit via melee (cutting punching whatever) AND hit via ranged (bullets, arrows, lasers and stuff)

And while I don’t want to say too much, I understand I need to share as much of my “outline” as I can.

Okay, so then to answer this:

You need to first decide how you are going to detect when an enemy was “hit” or not. I’d start with just a gun since melee can be done a couple different ways, whereas shooting bullets can be represeted as a Physics.Raycast function. If you’re not really familiar with Unity’s physics I’d recommend looking into some tutorials. Most of the physics functions with return the game object or collider that was contacted. From here, you’d retrieve the attached Enemy script (just like I did with GetComponent above) and apply damage as per before.

So I need to find physics Tutorials on raycast?

How far are you in your learning? Do you have your character moving around?

I’d just search for a basic FPS tutorial and learn what you can from that.

Honestly I did the roll a boll learn class and watched some vids from brackeys.

Other than that I am 100% inexperienced In this situation.

I have currently found the unity tutorials for scripting. So I am going through all of those a few times to hopefully get some sort of a grasp on it.

I will search for more tutorials once I have gone through this 2 or 3 times. Anything You think would be super helpful I will check out too,

Look at it this way… Health is just a number. You want all living things to have “health” in your game. so your basic script is this.

//health.cs

public int health;

you take that and drop that script on anything… add a number in the inspector and that thing has that amount of health.
health is great and grand… but now you need a way to take away health if you want things to die.
some pointers on health:

  • health should be its own system (only deals with health)
  • health doesn’t care what weapons you have or your weapon / magic / whatever systems (health just has a way for those systems to effect health)

modify health

//health.cs

public int health;

// we been hit.... but how bad
public void Hit(int amount){
     health-=amount;  // damage our health var by the amount we we hit by
}

now health can be damaged…by anything… it just calls the Hit function and sends it an amount

how ever you detect a hit… collision/trigger(melee/physical projectiles) or raycast hit (again melee/projectiles) they do the same

//of course do make sure the hit object has a health component before you attempt calling functions or things get sad
hitObject.GetComponent<health>().Hit(damage);

to make health more snazzy do things like regeneration and set max health and maybe even deal with death:

//health.cs

public int maxHealth;
public int health;

public bool canRegen; // can turn regen on or off
public int regenAmount; // amount to heal per regen tick
public float regenTime;  // time between regen ticks in seconds
public float regenHitDelay; // how long after we are hit can we regen

void Start(){
     health = maxHealth; // start with full health

     if(canRegen){
          InvokeRepeating("Regen",regenTime, regenTime);
     }
}

// we been hit.... but how bad
public void Hit(int amount){
     if(IsInvoking("Regen")){
         CancelInvoke("Regen"); // we've just been hit Cancel any active regen
     }

     health-=amount;  // damage our health var by the amount we we hit by

     if(health<=0){
          health = 0; // i don't like healthbars or text showing negatives...just me
          Die(); // and now we die
     }

     // If we can regen... resume it after the hit delay
     if(canRegen){
          InvokeRepeating("Regen",regenHitDelay, regenTime);
     }
}

//i make death a public function so things like insta-kill stuff just bypasses health and kills the target
public void Die(){
     //Do your deathly deeds here ... add kill/death counters...stats...whatever
     // Destroy or Pool your GameObject (not just this component)
}

void Regen(){
     health+=regenAmount;

     if(health>=maxHealth){
          health = maxHealth; // don't over do it

          if(IsInvoking("Regen")){
               CancelInvoke("Regen"); // if we have full health we don't need to regen
          }
     }
}

There is a basic Health Script. I’m using int as my health to keep things neat… floats work as well its just preference. Again… health is a simple thing and is not or should not be weapon specific. Hope this helps.

4 Likes

That, novashot, Is exactly what I wanted! thanks!

Many many thanks!