Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Getting reference to the healt in the enemyScript?

Discussion in 'Scripting' started by Argonxx, Jul 23, 2017.

  1. Argonxx

    Argonxx

    Joined:
    Apr 16, 2017
    Posts:
    37
    Hi! I found a lot of examples, but none of them is simple and clear.

    I want only to destroy the enemy game object when his health will be 0 - in another script.

    In my little game enemies get active or passive in the hierarchy, but I don't destroy that objects. But now I need to do that and I would like to destroy the object when his health == 0.

    How to do that?

    I have the enemy and enemyScript. Now I am doing another script and I want to refer to the enemy health and make that object destroyed.

    This is my wrong script
    Code (CSharp):
    1. public class DestroyWhenDead : MonoBehaviour {
    2.  
    3.     //GameObject monster;
    4.     //public GameObject health;
    5.  
    6.     void Start() {
    7.         //EnemyScript = GameObject.Find("Health");
    8.     }
    9.    
    10.     // Update is called once per frame
    11.     void Update () {
    12.         EnemyScript enemyScript = GetComponent<Health> ();
    13.         if (health <= 0)
    14.         {
    15.             Destroy (gameObject);
    16.         }
    17.     }
    18. }
    It says, that:
    error CS0118: `DestroyWhenDead.health' is a `field' but a `type' was expected
    rror CS0029: Cannot implicitly convert type `T' to `EnemyScript'
    and
    error CS0019: Operator `<=' cannot be applied to operands of type `UnityEngine.GameObject' and `int'
     
  2. Lethn

    Lethn

    Joined:
    May 18, 2015
    Posts:
    1,583
    Well right away I can see that your both your health's are upper case H and lower case h so try fixing that first, can't see anything else obviously wrong just yet but that's often the biggest culprit.

    "health" on your if statement should be "Health", try that and we'll see if any other errors pop up or if it changes.
     
  3. Argonxx

    Argonxx

    Joined:
    Apr 16, 2017
    Posts:
    37
    It says:
    Assets/DestroyWhenDead.cs(16,42): error CS0246: The type or namespace name `health' could not be found. Are you missing an assembly reference?
    The name `health' does not exist in the current context'

    So, it doesn't correspond to the 'health'.
     
  4. Argonxx

    Argonxx

    Joined:
    Apr 16, 2017
    Posts:
    37
    I've changed that to
    Code (CSharp):
    1.     public int Health;
    2.  
    3.     void Start() {
    4.         EnemyScript enemyScript = GetComponent<"Health">();
    5.     }
    6.    
    7.     // Update is called once per frame
    8.     void Update () {
    9.        
    10.         if (Health <= 0)
    11.         {
    12.             Destroy (gameObject);
    13.         }
    14.     }
    15.     }
    And now it says only: error CS1525: Unexpected symbol `)' - but it has no sense.
     
  5. Lethn

    Lethn

    Joined:
    May 18, 2015
    Posts:
    1,583
    Oh, hang on, I think I might know what you've done now I've got my second coffee.

    Code (CSharp):
    1.         EnemyScript enemyScript = GetComponent<"Health">();
    2.  
    I'm not sure what you're attempting to do with the first bit, might need more context but GetComponent<EnemyScript.Health>(); should be correct, don't use quotation marks, did you get this from a tutorial or something?

    Going to get some documentation because I've done this before myself with other scripts and it works fine, could I perhaps take a look at your enemy script as well?
     
    Last edited: Jul 23, 2017
  6. Argonxx

    Argonxx

    Joined:
    Apr 16, 2017
    Posts:
    37
    When I changed that in such a way, it had made a lot of strange errors.

    This is a part of enemy script
    Code (CSharp):
    1. public class EnemyScript : MonoBehaviour {
    2.     public Animator animator;
    3.     public Transform healthBar;
    4.     private SpriteRenderer healthBarSprite;
    5.     public GameObject enemyDead;
    6.     public GameObject player;
    7.  
    8.     public Transform[] checkpoints;
    9.     private int checkpoint = 0;
    10.  
    11.     private Vector2 desiredVelocity = Vector3.zero;
    12.     private Vector2 desiredForce = Vector3.zero;
    13.     private Vector2 desiredDirection = Vector2.zero;
    14.  
    15.     public int acceleration = 10;
    16.     public int speed = 2;
    17.    
    18.     public MeleeAttack meleeAttack;
    19.  
    20.     private Rigidbody2D rb;
    21.     private float attackStarted;
    22.     private Transform currentTarget;
    23.     private bool attacking = false;
    24.     public float health = 250;
    25.     public bool takesDamage = true;
    26.     public float DestroyAfterTime = 3.0f;
    27.  
    28.  
    29.     void Start () {
    30.         rb = GetComponent<Rigidbody2D>();
    31.         healthBarSprite = healthBar.GetComponent<SpriteRenderer>();
    32.         rb.freezeRotation = true;
    33.         enemyDead.SetActive (false);
    34.  
    35.     }
    36.    
    37.  
    38.     void Update () {
    39.         healthBarSprite.color = Color.Lerp(Color.red, Color.green, health / 250);
    40.         healthBar.localScale = new Vector3(health%250 / 250, 1, 1);
    41.         animator.SetBool("fight", false);
    42.    
    43.         if (health <= 0)
    44.         {
    45.             enemyDead.SetActive (true);
    46.             enemyDead.transform.position = transform.position;
    47.             transform.rotation = Quaternion.identity;
    48.             gameObject.SetActive (false);
    49.             Destroy (enemyDead, DestroyAfterTime);
    50.  
    51.         }
     
  7. Lethn

    Lethn

    Joined:
    May 18, 2015
    Posts:
    1,583
    Are you absolutely sure you need that public integer there? Try this, let me know how it goes.

    Code (CSharp):
    1.  
    2.     void Start() {
    3.    
    4.     }
    5.  
    6.     // Update is called once per frame
    7.     void Update () {
    8.      
    9.         if (EnemyScript.health <= 0)
    10.         {
    11.             Destroy (gameObject);
    12.         }
    13.     }
    14.     }
     
  8. Argonxx

    Argonxx

    Joined:
    Apr 16, 2017
    Posts:
    37
    Ok. It says now: error CS0120: An object reference is required to access non-static member `EnemyScript.health'

    I think that it still can't get access to the Health in the above enemyScript. But when I place the code to get to the EnemyScript.Health element, then this element is red, what means, that it can't also refers that to the script. Strange.
     
  9. Lethn

    Lethn

    Joined:
    May 18, 2015
    Posts:
    1,583
    That is really weird, I'm afraid I've run out of ideas so it's probably best if you wait for somebody more experienced, I can tell you though that I've used script.namedinteger before on my own code and it works just fine usually. Not sure what's going on that it would behave like this.
     
  10. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Both of you need to go back to the learn section. ;)

    This is a pretty straight forward solution. Assuming the EnemyScript is on the same component as DestroyWhenDead, then the following code will work.

    Code (CSharp):
    1. public class DestroyWhenDead : MonoBehaviour {
    2.  
    3.     void Update () {
    4.         EnemyScript enemyScript = GetComponent<EnemyScript> ();
    5.         if (enemyScript.health <= 0)
    6.         {
    7.             Destroy (gameObject);
    8.         }
    9.     }
    10. }
    Of course you should probably cache the component reference as a good habit.

    Code (CSharp):
    1. public class DestroyWhenDead : MonoBehaviour {
    2.  
    3.     EnemyScript enemyScript;
    4.  
    5.     void Awake () {
    6.         enemyScript = GetComponent<EnemyScript> ();
    7.     }
    8.    
    9.     void Update () {
    10.         if (enemyScript.health <= 0)
    11.         {
    12.             Destroy (gameObject);
    13.         }
    14.     }
    15. }
     
    Ryiah and Lethn like this.
  11. Lethn

    Lethn

    Joined:
    May 18, 2015
    Posts:
    1,583
    Oh for crying out loud, of course it works like that :p

    Thanks Kiwasi, I'm going to double check my code because I bet I'll have put my code in there somewhere like that and that's why it all works, I got it half right at least.

    Code (CSharp):
    1.         Text scoreText = GameObject.Find ("scoreText").GetComponent<Text> ();
    2.  
    Yes, of course, there it bloody is, I just wasn't reading the code off right, I was wondering why there were errors popping up even after this, you need both, Kiwasi's solution is definitely correct.
     
  12. Argonxx

    Argonxx

    Joined:
    Apr 16, 2017
    Posts:
    37
    Oh yes, it works very well :D Great thanks Kiwasi! Now I can try to make another interaction. When two of monsters are already dead, then the conversation box should become active. I did it like that.
    Code (CSharp):
    1. public class Mission1 : MonoBehaviour {
    2.  
    3.     public GameObject monster1;
    4.     public GameObject monster2;
    5. //it's a canvas
    6.     public GameObject message;
    7.  
    8.     void Start () {
    9.  
    10.         message.SetActive (false);
    11.     }
    12.  
    13.     void Update () {
    14.         if(monster1&&monster2 == null)
    15.         {
    16.             message.SetActive (true);
    17.         }
    18.     }
    19. }
    Why is it not working?
     
  13. Lethn

    Lethn

    Joined:
    May 18, 2015
    Posts:
    1,583
    I'l leave this one to Kiwasi lol :p
     
  14. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Code (csharp):
    1.  
    2. if (monster1 == null && monster2 == null)
    3.  
     
    Ryiah and Lethn like this.
  15. Argonxx

    Argonxx

    Joined:
    Apr 16, 2017
    Posts:
    37
    Yes, it should work. I'll check that today evening.
     
  16. Argonxx

    Argonxx

    Joined:
    Apr 16, 2017
    Posts:
    37
    Unfortunately it doesn't work. I did a simple red square which should become active when two of the monsters will be dead. Instead they are null the square is still invisible.
     
  17. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Guess you'll have to do some debugging then! Log the null checks to see which one isn't null, etc etc.
     
  18. Argonxx

    Argonxx

    Joined:
    Apr 16, 2017
    Posts:
    37
    Debugging showed no red alerts, only couple of yellow, but not connected with null function. But can it be so, that null is treated as a bool and without putting it in such a way it will not work?
     
  19. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Code (csharp):
    1.  
    2. if (monster1 != null) Debug.Log("monster1", monster1);
    3. if (monster2 != null) Debug.Log("monster2", monster2);
    4.  
     
  20. Argonxx

    Argonxx

    Joined:
    Apr 16, 2017
    Posts:
    37
    I found in the web that there is no possibility to check if anything is or not active in hierarchy. Any of gameobject.activeSelf; .activeInHierarchy etc. are not working. That's a shame, but it works like that.

    That's why I found the other solution. I have a script which is responsible for counting enemies. But the enemy is not active at the beginning. He appears after the conversation with one of the characters. I've wrote a script and attached it to the sensor object. The sensor is active, when the health of the enemy is >0. So, when the sensor is active it has a tag Enemy. But after the monster death it becomes inactive. Counting script "sees" it and he sends information to the collision box (on trigger), that it can already show the conversation box, because all the enemies are already killed. Mission passed. And it works! :D
     
  21. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Um....those definitely work. Not sure what to tell you and where you found that incorrect information.
     
    Kiwasi likes this.