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. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

GetComponent<Image>()

Discussion in 'Scripting' started by MisterSkitz, Aug 24, 2018.

  1. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    833
    Ok, so basically I have two images for a health bar in a class called HP

    public Image HP_Green;
    public Image HP_Red;


    Now upon Start() I want to grab these two images and set their active value to false in order to hide the HP bar.

    HP_Green = this.GetComponent<Image>();

    HP_Green.gameObject.SetActive(false);


    HP_Red = this.GetComponent<Image>();

    HP_Red.gameObject.SetActive(false);

    **** Issue #1 is I don't think HP_Red is going into the variable properly ****

    Now I want to inherit those variables into a Class called Detection

    OnTriggerEnter(Collider other)

    // HP healthBar = other.GetComponent<HP>();
    // healthBar.gameObject.SetActive(true);

    HP.HP_Green.gameObject.SetActive(true);
    HP.HP_Red.gameObject.SetActive(true);


    The top code that I have commented out can potentially work.. However, it doesn't.
    the bottom code works, but only if I make the construtors STATIC. Also, it only works on the HP_Green, so HP_Red never gets set back to true. UNLESS... HP_Red is being replaced or not initialized upon Start. One last note, I have OnTriggerExit() that's identical so I didn't bother posting the code.Debug.Log() does detect triggers in both functions.

    I need a professional to explain to me what is happening and why. Also, would be nice to help me fix this code lol thanks! (I just clicked control S to save this lol been coding way too long today haha!)
     
  2. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    Depending on how you have your objects and code structured in the hierarchy, the code
    this.GetComponent<Image>();
    could be returning the same image. If that is the case, then
    HP_Green
    and
    HP_Red
    would be set to the same image. So that is what could be happening there.
     
    MisterSkitz likes this.
  3. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    833
    Well, when I put the Debug.Log() on it, there appears to be 2 green and 2 red being grabbed at startup. I'm afraid that green must be overriding. How do I go about insuring they each get the correct value?
     
  4. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    Instead of putting both Image components on the same GameObject, you could place each one a separate child GameObject similar to this:
    • HP
      • Green
      • Red
    Then in your script (attached to the parent GameObject), you can get these Image components by referencing the child GameObjects like so:

    Code (CSharp):
    1. void Start() {
    2.    //Child 0 = the first child object
    3.    HP_Green = transform.GetChild(0).gameObject.GetComponent<Image>();
    4.  
    5.    //Child 1 = the second child object
    6.    HP_Red = transform.GetChild(1).gameObject.GetComponent<Image>();
    7. }
    This should prevent any confusion with references.
     
    Last edited: Aug 24, 2018
    MisterSkitz likes this.
  5. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    833
    Excellent! I'll try this now. One quick question, how to I go about setting these into my detection file? Do I use GetChild on that script as well?
     
  6. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    833
    Just an update:

    Everything works in my original code so to speak.. What I need is a way to insure that BOTH images are loading into their respective variables. As of now, the HP_Red doesn't work. My compiler, using Debug.Log() says that I'm showing 2 of each. The HP_Green behaves properly; however, the red is not showing at start nor after entering/exiting the trigger.

    I'm open to suggestions! I have tried many different variations of Cucci's suggestion but the problem was an error message "Child out of bounds". After researching, it turns out that it was not viewing them as a child object and/or the parent object was disabling them. However, Cucci, I do appreciate your response because you put me onto something new and very, very useful! I'm a rookie coder so I enjoy learning as I go :)

    With that said, I still need help assigning these variables. Keep in mind that they are currently STATIC.
     
  7. barskey

    barskey

    Joined:
    Nov 19, 2017
    Posts:
    207
    Although not specifically what you're asking for, a couple of other suggestions to consider:
    • Can you add a public Image variable and set them in the Inspector? Or a public Image[] array?
    • Can you make your image white (in the parts that need to be red or green), and then just change the color in the SpriteRenderer accordingly?
    If not, showing a screenshot of your project tree and inspector might give us a better idea what is happening.
     
    MisterSkitz likes this.
  8. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    833
    You're right, I should have provided more information. For that, my apologies.

    Basically I'm programming a health bar for a game in Unity 5. I have two images, a Red background image (HP_Red) and a green image (HP_Green). Those are my two variables to store the images into the program.These images are in a Class HPsc.

    However, I have another Class EnemyDetection. My goal is to make my HP meter invisible until an enemy is nearby. That's when EnemyDetection is called.

    I have two functions OnTriggerEnter(Collider other) and OnTriggerExit(Collider other)

    My real issue at this point is that my HPsc file isn't putting the HP_Red into the variable. Green is taking both spots according to my hundreds of Debug.Log() test. I really need to find a way to force the red into its variable and check to insure both vars are correct. I'm working on that now but nothing I'm doing is working.

    Finally, regarding your question, if I setup public nonstatic variables, my EnemyDetection Class doesn't like to inherit the constructors anymore. And I've tried recoding for nonstatic constructors but it was more broken than it is currently. My code is close to working as is, I just need to get the HP_Red variable loaded properly.

    Thanks for the reply and your time, amigo! :)
     
  9. barskey

    barskey

    Joined:
    Nov 19, 2017
    Posts:
    207
    When you get the "Child out of bounds" error, it sounds like an issue with the active state of the children. I am not near Unity to test, but I think if you have a parent gameobject with two active children, you could use Getchild(0) and GetChild(1). But after you set the first child to inactive, you'd have to use GetChild(0) again. Or at least that's what I think is going on.

    If you are using the child gameobjects as Cucci_A suggested, try setting both your HP_Red and HP_Green references before disabling either gameobject.

    Or, you can just set the Image component to disabled rather than its gameobject.
    HP_Red.enabled = false;
    Then the child count will always be 2, since the child gameobjects are always active.

    And if for some reason you need both Image components on the same GameObject (you can't/don't want to use child gameobjects), use GetComponents<Image>() and iterate over them. You'd have to test for something to be able to tell if it is red or green, maybe something like this:
    Code (CSharp):
    1. Image[] healthBars = GetComponents<Image>();
    2. foreach (var bar in healthBars)
    3. {
    4.   if (bar.sprite.name == "red_sprite_name")
    5.   {
    6.     HP_Red = bar;
    7.   }
    8.   else
    9.   {
    10.     HP_Green = bar;
    11.   }
    12. }
    Clearly not a robust solution since you are using strings to compare.
     
    MisterSkitz likes this.
  10. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    833
    I finally found a total solution to the issue!!!! Luckily I didn't have to recode anything. I simply moved the HP_Red onto the EnemyDetection script, made it a public, nonstatic variable and manually inserted it into the script via Unity inspector.

    The other issue I was having was related to trying to fade the HP bar in and out; it's a cool effect, but I had to remove that because it was being problematic! Just a side note that may help someone in the future. :)

    Thanks for all the replies! You guys are awesome!
     
    Doug_B likes this.