Search Unity

C# - HP displayed with hearts on GUI

Discussion in 'Scripting' started by Zukas, Oct 23, 2014.

  1. Zukas

    Zukas

    Joined:
    Dec 17, 2013
    Posts:
    40
    Hello fellow scripters, I'm working on health system which is displayed using hearts. One part of the script calculates how many and what kind of hearts must be done, at the moment there's 3 types.
    • Full Heart - 2HP.
    • Half Heart - 1HP (With other part grayed out, think it as of 1/2).
    • Empty heart - (Completely grayed out).
    All of the calculations for how many of each heart type should be displayed are counted into integers.

    So if max HP was 8 and current HP, it would be just 4 Full Hearts.
    If it was 5 HP and max HP was 8, it would be 2 full hearts, 1 half heart, and 1 empty heart.

    I've tried various loops on how to display them in right order using GUI.DrawTexture and so on, but I couldn't make it work right, besides that I've also got very very big FPS drops. What are possible ways to do it, how would you try do it, or what other way could I try for it. It would be also great if you explained direction in which I should work so I'd get it work on 4.6 Beta GUI.

    If I wrote something confusing in some part, please notify me and I will try to explain it better, English isn't my mother language, nor I'm used to forums. Thanks in advance!
     
  2. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    The number of full hearts would be
    Code (csharp):
    1.  
    2. int fullHearts = currentHealth / 2;
    3.  
    And the number of half hearts would be
    Code (csharp):
    1.  
    2. int halfHearts = currentHealth % 2;
    3.  
     
  3. Zukas

    Zukas

    Joined:
    Dec 17, 2013
    Posts:
    40
    Yes, I know. My calculation system works just fine and as it should be, problem is I can't seem to get them display in right order.
     
  4. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    A simple for loop with GUI.DrawTexture ought to work fine (plus one more DrawTexture call if you have half a heart). Why don't you post your code (use the "insert code" button, between the movie icon and the disk icon), and perhaps we can help you find the error.
     
  5. Zukas

    Zukas

    Joined:
    Dec 17, 2013
    Posts:
    40
    This is how my calculation looks like:
    Code (CSharp):
    1. int fullHeart;
    2.         int halfHeart;
    3.         int emptyHeart;
    4.  
    5.         if(charController.health%2==1)
    6.         {
    7.             fullHeart = (charController.health - 1) / 2;
    8.             halfHeart = 1;
    9.         }
    10.         else
    11.         {
    12.             fullHeart = charController.health / 2;
    13.             halfHeart = 0;
    14.         }
    15.  
    16.         if(charController.health%2==1)
    17.         {
    18.             emptyHeart = ((charController.maxHealth - (charController.health + 1)) / 2);
    19.         }
    20.         else
    21.         {
    22.             emptyHeart = ((charController.maxHealth - charController.health) / 2);
    23.         }
    And this is how I try to display them:
    Code (CSharp):
    1. for(int i = 0; i < totalHearts; i++)
    2.         {
    3.             print("Full hearts: " + fullHeart + " Half Hearts: " + halfHeart + " Empty Hearts: " + emptyHeart);
    4.             if(i <= fullHeart)
    5.             {
    6.                 GUI.DrawTexture(new Rect(i * 64 + 10,10,64,64),heartIcon);
    7.             }
    8.             else if(i + halfHeart >= fullHeart && halfHeart > 0)
    9.             {
    10.                 print("Should print halfheart");
    11.                 GUI.DrawTexture(new Rect(i * 64 + 10,10,64,64),heartHalfEmptyIcon);
    12.             }
    13.             else if(i <= fullHeart + halfHeart + emptyHeart && emptyHeart > 0)
    14.             {
    15.                 GUI.DrawTexture(new Rect(i * 64 + 10,10,64,64),heartEmptyIcon);
    16.             }
    17.         }
    Hearts usually show up in wrong order, in most cases half heart doesn't even show up at all, and together with all that, FPS drops very very much, any insights on how could I try fix this?
     
    Last edited: Oct 24, 2014
  6. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Why don't you just draw them separately? Make a for loop to draw the full hearts, then another for loop to draw the half hearts, and lastly a loop to draw the empty ones? Skip all your crazy conditional logic. I also don't understand why you're using if statements to calculate the number of hearts and why you're doing division for the empty ones. Isn't empty always total - (full + half)?
     
  7. Zaladur

    Zaladur

    Joined:
    Oct 20, 2012
    Posts:
    392
    Calculations can be simplified up top, for sure.

    Code (csharp):
    1. int full = health/2;
    2. int half = health%2;
    3. int empty = maxhealth-full-half;
    Lots of confusing conditionals in your loop too. As Kelso said, you can draw three separate loops and just keep a counter going through all three to adjust for heart position. No need for any ifs.
     
  8. Deleted User

    Deleted User

    Guest

    I would, Add them to array after you calculate them in order... full add first, then add what is remaining,, IE half heart or quarter heart of monkey for that matter.

    Then just draw the array to screen.
    Clear it, and rebuild it as needed.
    I think you are overly complicating your issue.

    life Array[max hearts]
    (graphic, screen position, bool filled)
    /add values to array
    add all your positions in order from left to right
    array[0] (graphic none, screen position x,y, bool filled false)
    array[1] (graphic none, screen position x,y, bool filled false)
    array[2] (graphic none, screen position x,y, bool filled false)

    int pos =0; // keep track of pos
    //calculate how many full hearts there are and set them
    array[pos] (graphic full heart, screen position x,y, bool filled true)
    pos++;
    loop until no more full hearts..

    then check remaining life to see what your end heart will be
    if half
    array[pos] (graphic half heart, screen position x,y, bool filled true)
    else if quarter
    array[pos] (graphic quarter heart, screen position x,y, bool filled true)

    loop through all items in array, if bool filled = true then draw to screen..
    use array to tell what you want to draw..
    end of loop.
     
    Last edited by a moderator: Oct 24, 2014
  9. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    All good advice, and I'll add just one more: the framerate drop is almost certainly do to the print statement. Not the drawing of the hearts. A half-dozen DrawTexture calls won't bog your game down at all.
     
  10. cmcpasserby

    cmcpasserby

    Joined:
    Jul 18, 2014
    Posts:
    315
    Ya it is often suppriseing how slow print and log statements are in most systems.
     
  11. Zukas

    Zukas

    Joined:
    Dec 17, 2013
    Posts:
    40
    Alright, I guess I'll do three separate loops, but how could I make the offset for their position using some integer, like I use i as an integer in my for loop and use make one same offset trough out all 3 loops? And thanks for all the responses by the way guys! :D
     
  12. A.Killingbeck

    A.Killingbeck

    Joined:
    Feb 21, 2014
    Posts:
    483
    Create an offset variable outside the scope of all the loops, and update it within each.
     
    JoeStrout likes this.
  13. Zukas

    Zukas

    Joined:
    Dec 17, 2013
    Posts:
    40
    No idea how I just simply haven't thought of it, got it also to work! Thanks!
     
    JoeStrout likes this.