Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

NOOB (SERIES ONE) - Help With Health System

Discussion in 'Scripting' started by KirA-1996, May 8, 2014.

  1. KirA-1996

    KirA-1996

    Joined:
    Oct 27, 2012
    Posts:
    12
    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.
     
  2. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    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).
     
  3. KirA-1996

    KirA-1996

    Joined:
    Oct 27, 2012
    Posts:
    12
    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?
     
  4. KirA-1996

    KirA-1996

    Joined:
    Oct 27, 2012
    Posts:
    12
    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.
     
  5. KirA-1996

    KirA-1996

    Joined:
    Oct 27, 2012
    Posts:
    12
    I GET IT.

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

    How do I do that?
     
  6. KirA-1996

    KirA-1996

    Joined:
    Oct 27, 2012
    Posts:
    12
    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.
     
  7. Iron-Warrior

    Iron-Warrior

    Joined:
    Nov 3, 2009
    Posts:
    836
    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:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Enemy : MonoBehaviour
    5. {
    6.     public float Health = 10.0f;
    7.     // ... Other attributes of this class
    8.  
    9.     private float currentHealth;
    10.  
    11.     void Start()
    12.     {
    13.         currentHealth = Health;
    14.     }
    15.  
    16.     public void TakeDamage(float damage)
    17.     {
    18.         currentHealth -= damage;
    19.  
    20.         if (currentHealth < 0)
    21.         {
    22.             // Destroy the game object, or do something else
    23.             Destroy(gameObject);
    24.         }
    25.     }
    26. }
    This script would be applied to an Enemy object. So now we need a way to attack him.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Player : MonoBehaviour
    5. {
    6.     public float Damage = 10.0f;
    7.     // ... Other attributes of this class
    8.  
    9.     // This is temporary.  Assign a GameObject with an Enemy script attached to it
    10.     public GameObject EnemyToAttack;
    11.  
    12.     void Update()
    13.     {
    14.         if (Input.GetButtonDown("Fire1"))
    15.         {
    16.             EnemyToAttack.GetComponent<Enemy>().TakeDamage(Damage);
    17.         }
    18.     }
    19. }
    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
     
  8. KirA-1996

    KirA-1996

    Joined:
    Oct 27, 2012
    Posts:
    12
    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?
     
  9. Iron-Warrior

    Iron-Warrior

    Joined:
    Nov 3, 2009
    Posts:
    836
    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:

     
    Last edited: May 8, 2014
  10. KirA-1996

    KirA-1996

    Joined:
    Oct 27, 2012
    Posts:
    12
    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)
     
    Last edited: May 8, 2014
  11. KirA-1996

    KirA-1996

    Joined:
    Oct 27, 2012
    Posts:
    12
    And while I don't want to say too much, I understand I need to share as much of my "outline" as I can.
     
  12. Iron-Warrior

    Iron-Warrior

    Joined:
    Nov 3, 2009
    Posts:
    836
    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.
     
  13. KirA-1996

    KirA-1996

    Joined:
    Oct 27, 2012
    Posts:
    12
    So I need to find physics Tutorials on raycast?
     
  14. Iron-Warrior

    Iron-Warrior

    Joined:
    Nov 3, 2009
    Posts:
    836
    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.
     
  15. KirA-1996

    KirA-1996

    Joined:
    Oct 27, 2012
    Posts:
    12
    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.

    http://unity3d.com/learn/tutorials/modules/beginner/scripting

    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,
     
  16. novashot

    novashot

    Joined:
    Dec 12, 2009
    Posts:
    373
    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.

    Code (csharp):
    1.  
    2. //health.cs
    3.  
    4. public int health;
    5.  
    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


    Code (csharp):
    1.  
    2. //health.cs
    3.  
    4. public int health;
    5.  
    6. // we been hit.... but how bad
    7. public void Hit(int amount){
    8.      health-=amount;  // damage our health var by the amount we we hit by
    9. }
    10.  
    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

    Code (csharp):
    1.  
    2. //of course do make sure the hit object has a health component before you attempt calling functions or things get sad
    3. hitObject.GetComponent<health>().Hit(damage);
    4.  
    to make health more snazzy do things like regeneration and set max health and maybe even deal with death:

    Code (csharp):
    1.  
    2. //health.cs
    3.  
    4. public int maxHealth;
    5. public int health;
    6.  
    7. public bool canRegen; // can turn regen on or off
    8. public int regenAmount; // amount to heal per regen tick
    9. public float regenTime;  // time between regen ticks in seconds
    10. public float regenHitDelay; // how long after we are hit can we regen
    11.  
    12. void Start(){
    13.      health = maxHealth; // start with full health
    14.  
    15.      if(canRegen){
    16.           InvokeRepeating("Regen",regenTime, regenTime);
    17.      }
    18. }
    19.  
    20. // we been hit.... but how bad
    21. public void Hit(int amount){
    22.      if(IsInvoking("Regen")){
    23.          CancelInvoke("Regen"); // we've just been hit Cancel any active regen
    24.      }
    25.  
    26.      health-=amount;  // damage our health var by the amount we we hit by
    27.  
    28.      if(health<=0){
    29.           health = 0; // i don't like healthbars or text showing negatives...just me
    30.           Die(); // and now we die
    31.      }
    32.  
    33.      // If we can regen... resume it after the hit delay
    34.      if(canRegen){
    35.           InvokeRepeating("Regen",regenHitDelay, regenTime);
    36.      }
    37. }
    38.  
    39. //i make death a public function so things like insta-kill stuff just bypasses health and kills the target
    40. public void Die(){
    41.      //Do your deathly deeds here ... add kill/death counters...stats...whatever
    42.      // Destroy or Pool your GameObject (not just this component)
    43. }
    44.  
    45. void Regen(){
    46.      health+=regenAmount;
    47.  
    48.      if(health>=maxHealth){
    49.           health = maxHealth; // don't over do it
    50.  
    51.           if(IsInvoking("Regen")){
    52.                CancelInvoke("Regen"); // if we have full health we don't need to regen
    53.           }
    54.      }
    55. }
    56.  
    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.
     
    Last edited: May 9, 2014
  17. KirA-1996

    KirA-1996

    Joined:
    Oct 27, 2012
    Posts:
    12
    That, novashot, Is exactly what I wanted! thanks!
     
  18. DonPuno

    DonPuno

    Joined:
    Dec 22, 2020
    Posts:
    57
    Many many thanks!