Search Unity

What's wrong with this health bar script?

Discussion in 'Scripting' started by ecloev, Oct 4, 2015.

  1. ecloev

    ecloev

    Joined:
    Oct 1, 2015
    Posts:
    101
    Hello,
    Why does my healthbar full and doesn't work?
    Is it something wrong with my script?

    Thanks :)
    Error:
    Code (csharp):
    1.  
    2. transform.localScale assign attempt for 'Bar' is not valid. Input localScale is { NaN, 1.000000, 1.000000 }.
    3. UnityEngine.Transform:set_localScale(Vector3)
    4. EnemyLogic:setHealthbar(Single) (at Assets/Scripts/EnemyLogic.cs:28)
    5. EnemyLogic:ApplyDamage(Int32) (at Assets/Scripts/EnemyLogic.cs:15)
    6. UnityEngine.Component:SendMessage(String, Object, SendMessageOptions)
    7. MeleeSystem:Update() (at Assets/Scripts/MeleeSystem.cs:16)
    8.  
    Script::
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class EnemyLogic : MonoBehaviour {
    6.    
    7.     public float max_Health = 100f;
    8.     public float cur_health = 0f;
    9.     public GameObject Bar;
    10.    
    11.  
    12.     public void ApplyDamage (int Damage){
    13.         max_Health -= Damage;
    14.         cur_health = max_Health;
    15.         float calc_Health = cur_health / max_Health;
    16.         setHealthbar (calc_Health);
    17.         if (max_Health <= 0) {
    18.             Dead();
    19.  
    20.         }
    21.     }
    22.    
    23.     private void Dead(){
    24.         Destroy (this.gameObject);
    25.     }
    26.    
    27.     public void setHealthbar(float enemyHealth) {
    28.         //enemyHealth is 0-1, calculated based on health and max health and current health :P
    29.         Bar.transform.localScale = new Vector3(Mathf.Clamp(enemyHealth,0f ,1f), Bar.transform.localScale.y, Bar.transform.localScale.z);
    30.     }
    31. }
    32.  
    33.  
     
  2. Zaladur

    Zaladur

    Joined:
    Oct 20, 2012
    Posts:
    391
    The logic of ApplyDamage seems a bit funny to me. Why lower max health when you take damage? You should be lowering current health, and keeping max where it is, so you can get the proper percentage to fill your hp bar.

    Right now it looks like these lines are the culprit:
    Code (csharp):
    1.  
    2. cur_health = max_Health;
    3. float calc_Health = cur_health / max_Health;
    4.  
    You are always going to have calc_result return 1, making your health bar stay full. The exception is if max_Health drops to 0 from your ApplyDamage method, in which case you will divide by zero. When you pass try to set the local scale with that result, you get the error you are seeing.

    NaN means 'Not a Number', which can result from the result of an operation being undefined (like when you divide by zero).
     
  3. ecloev

    ecloev

    Joined:
    Oct 1, 2015
    Posts:
    101
    Yes, that seems about right, so what can i do to have this work correctly?
     
  4. Zaladur

    Zaladur

    Joined:
    Oct 20, 2012
    Posts:
    391
    Operating on currentHealth instead of Max should solve this bug, assuming the rest of your scripts are working.

    Code (csharp):
    1. cur_health -= Damage;
    2. float calc_Health = cur_health / max_Health;
    3. setHealthbar (calc_Health);
     
  5. ecloev

    ecloev

    Joined:
    Oct 1, 2015
    Posts:
    101
    So what should my script look like? What should i change?
     
  6. ecloev

    ecloev

    Joined:
    Oct 1, 2015
    Posts:
    101
    Bump
     
  7. Grimkeep

    Grimkeep

    Joined:
    Aug 27, 2015
    Posts:
    13
    This should work
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class EnemyLogic : MonoBehaviour {
    4.  
    5.     public float max_Health = 100f;
    6.     public float cur_health = 100f;
    7.     public GameObject Bar;
    8.  
    9.     public void ApplyDamage (int Damage){
    10.         cur_health -= Damage;
    11.         float calc_Health = cur_health / max_Health;
    12.         setHealthbar (calc_Health);
    13.         if (max_Health <= 0) {
    14.             Dead();
    15.         }
    16.     }
    17.  
    18.     private void Dead(){
    19.         Destroy (this.gameObject);
    20.     }
    21.  
    22.     public void setHealthbar(float enemyHealth) {
    23.         //enemyHealth is 0-1, calculated based on health and max health and current health :P
    24.         Bar.transform.localScale = new Vector3(Mathf.Clamp(enemyHealth,0f ,1f), Bar.transform.localScale.y, Bar.transform.localScale.z);
    25.     }
    26. }
     
    Last edited: Oct 5, 2015
  8. ecloev

    ecloev

    Joined:
    Oct 1, 2015
    Posts:
    101
    Well now my unity wont die. Healthbar works and goes down but the units health doesn't do anything when it gets to 0, it just keeps going down into negatives?
     
  9. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    6,916
    You're checking to see if max health is <= 0. Should be checking cur health.
     
  10. ecloev

    ecloev

    Joined:
    Oct 1, 2015
    Posts:
    101
    Thanks :D