Announcement

Collapse
No announcement yet.

Repeating life/heart system on the HUD?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    Repeating life/heart system on the HUD?

    Hi y'all,

    I'm looking to replicate a pretty common health system, where your health is shown as a series of hearts (or some other image) on your HUD. The hearts/whatevers deplete as you take damage, and can be expanded by upgrading your total health in some way. This system is most obviously apparent in the Zelda series, of course, where you can collect Heart Pieces to upgrade health.

    After a few days of searching I've failed to find any direction on this, so I'm coming here for help. I thought I would be okay if I found some tutorials on using the Expandable Area palette and/or the Uniform Grid Panel palette, but no dice so far.

    Hope someone understands what I'm looking for.

    And whether or not you do -- have a pleasant day!
    I'm an artist! Check out my work at https://cinebst.wixsite.com/cinebeastart and hit me up!

    You can e-mail me at cinebst@gmail.com.

    #2
    While I haven't done something like this, I feel like it's a pretty similar methodology to a health bar. With a health bar, when the player takes damage -> tell widget to update the bar -> widget gets current health and max health of player and adjusts the bar accordingly.
    For "full" hearts, I suppose you'd want your health variable to be an int and when changed -> tell widget to update hearts -> it gets player health and updates the hearts accordingly.
    For "part" hearts (like latest zelda where a heart can be divided up into 3 parts), either the above would work but multiply it by 3, or you could use a float where whole numbers represents a full heart and the left over would tell the last heart to update accordingly, only showing a part of the heart.

    So how would the hearts update accordingly?
    You could get the player health and the widgets current hearts, compare and add or remove as needed.
    To keep things simple, the hearts could be contained inside a horizontal box, and you'd just add to or remove from the box.
    For a grid panel, some extra math is needed to put the heart into the correct grid slot.

    The heart would probably be its own widget, and for part hearts, it would hold the logic for only displaying part of itself.

    Note that when I write "add heart", I mean that either creating the heart widget as needed, or create the maximum amount of hearts and then just toggling their visibility as desired.
    Try to keep important logic inside the player or controller. The widget should only have the logic for the visuals.

    Comment


      #3
      Originally posted by ste1nar View Post
      ... or you could use a float where whole numbers represents a full heart and the left over would tell the last heart to update accordingly, only showing a part of the heart.
      Thank you, and I like the sound of this, but I have questions. How can I tell the widget which heart is the last heart? How do I divide one float value representing health among three or four or however many heart widgets? I'm not familiar with the methodology for any of that.
      I'm an artist! Check out my work at https://cinebst.wixsite.com/cinebeastart and hit me up!

      You can e-mail me at cinebst@gmail.com.

      Comment


        #4
        I threw together this:
        Click image for larger version

Name:	hearts1.png
Views:	1
Size:	119.0 KB
ID:	1127684

        Click image for larger version

Name:	hearts2.png
Views:	1
Size:	68.6 KB
ID:	1127687

        Click image for larger version

Name:	hearts3.png
Views:	1
Size:	235.9 KB
ID:	1127689

        So in this example the idea is:
        1. When the HUD widget is created, create the max number of hearts that there can be, add them to the container (in this case a horizontal box) and hide them.
        2. When the player health changes:
        2A: loop through the currently displayed hearts and hide them
        2B: get the players current health, floor it to get number of whole hearts and using a loop with that number, set that many as visible.
        2C: Get the remainder of the player health, get the heart widget and somehow tell it to update to account for the remainder.
        2D: update how many hearts the widget is displaying.

        The only thing I am not sure how to do is displaying part of the heart. There are many ways to display it, like -
        - Display it partially, lerping the texture from top to bottom?
        - Have it like a pie/clock thing, whatever that is called?
        - Like in newest zelda where each heart consists of a number of pieces?
        And I'm not sure how to only show part of a texture.

        And etc.
        The blueprint setup above can of course be optimized and adjusted in various ways. I notice now, you may want to start the loops at index 0. Don't take the blueprints too litteral, it's more of an example.
        Last edited by ste1nar; 05-06-2017, 08:34 PM.

        Comment


          #5
          Wow, thanks! This is really helpful.

          Originally posted by ste1nar View Post
          The only thing I am not sure how to do is displaying part of the heart.
          I approached the issue with a dynamic material. When I was only working with one heart, all I did was feed my current health into the material's Alpha, which depleted the heart in a pie shape.

          Click image for larger version

Name:	ue4_heart_alpha_ste1nar.png
Views:	1
Size:	51.1 KB
ID:	1127714

          As you can see, I've changed things so that I'm feeding your % variable into the Alpha instead, but I'll be honest, I'm not sure what this variable is for. And it's not really working the way it should be yet.

          Click image for larger version

Name:	ue4_hearts_wrong_ste1nar.png
Views:	1
Size:	81.7 KB
ID:	1127715

          There are a couple of aesthetic issues too.

          For one thing, I don't actually want to remove/hide the hearts as they are depleted. After all, the player wouldn't be able to tell at a glance how many total hearts they have if they've taken damage. Instead I just want the hearts in question to be grayed out. (Kind of like how it looks in that image, but all of those are a work in progress.)

          For another, right now the hearts are appearing and disappearing from the left-hand side of the screen. How would I go about changing that? In your average Zelda, for instance, the right-most heart depletes first, and so on, until only the left-most heart remains when the player is near death. Like this:
          Click image for larger version

Name:	legend-of-zelda-hearts.png
Views:	1
Size:	2.1 KB
ID:	1127716
          I like where all this is going, though. I feel like I'll have it wrapped up with a little more back-and-forth. You're a huge help, dude.
          I'm an artist! Check out my work at https://cinebst.wixsite.com/cinebeastart and hit me up!

          You can e-mail me at cinebst@gmail.com.

          Comment


            #6
            Well glad you find it useful. The things you point out are good points that I did not think of.
            So skipping the whole setting visibility:

            Click image for larger version

Name:	Hearts5.png
Views:	1
Size:	253.4 KB
ID:	1127721

            Click image for larger version

Name:	Hearts4.png
Views:	1
Size:	14.8 KB
ID:	1127722

            So now all the heart widgets are always visible, driving their visual state with a 0-1 float. So a whole heart, 1, will be full and then the left over heart will receive what's left over. Which is shown in the bottom right - I simply use a progress bar for this example. But you could drive the alpha of a material or the pie shape you mentioned should work.

            As for the hearts depleting left to right, they don't for me when I use a horizontal box to hold the hearts with the code above. What are you using to hold them?

            Another thing to think about is when the player increases the max life, so when that happens there should be an event inside the widget that adds new hearts.

            Comment


              #7
              Originally posted by ste1nar View Post
              As for the hearts depleting left to right, they don't for me when I use a horizontal box to hold the hearts with the code above. What are you using to hold them?
              Hmm. I wanted to use a wrap box, in case the hearts grow too many, but I switched back to a horizontal box. I'm having problems, though.

              Click image for larger version

Name:	ue4_ste1nar_health_full.png
Views:	1
Size:	46.5 KB
ID:	1127727

              For the sake of clarity I swapped out my hearts for progress bars, like you. That's full health. (I set the default max health to seven for this test, although it appears that eight are created.)

              But here's what happens when I take damage:

              Click image for larger version

Name:	ue4_ste1nar_health_hurt.png
Views:	1
Size:	27.0 KB
ID:	1127728

              That's wonky, right?

              Here's the Event Construct:

              Click image for larger version

Name:	ue4_ste1nar_hud_event_construct.png
Views:	1
Size:	70.9 KB
ID:	1127729

              The event I'm using to update the hearts/bars is from a Blueprint Interface. Whenever the player gets hurt (or finds health) we call that event, sending the player's current and max health. So here's that:

              Click image for larger version

Name:	ue4_ste1nar_hud_update_stats.png
Views:	1
Size:	142.4 KB
ID:	1127730

              Looking at it now, I'm noticing a possible discrepancy between your graph and mine. You're grabbing the "health" from the player reference, but is that the current or maximum health?
              I'm an artist! Check out my work at https://cinebst.wixsite.com/cinebeastart and hit me up!

              You can e-mail me at cinebst@gmail.com.

              Comment


                #8
                I think I see the problem. As for your last comment, see it as the current health.
                I think that the problem is that during sequence 0, the bars are reset but the loops last index is the current health - the new health, where as you'd want to use the old number of displayed hearts - the "current hearts" variable in my setup, which is a variable inside the widget.
                If it makes it easier, you can "get children" of the horizontal box and foreach loop each of them to reset them.

                "(I set the default max health to seven for this test, although it appears that eight are created.)" - Is it the zero index that's adding the extra?

                Comment


                  #9
                  Thank you! Your directions seem to have fixed most of the issues.

                  Originally posted by ste1nar View Post
                  "(I set the default max health to seven for this test, although it appears that eight are created.)" - Is it the zero index that's adding the extra?
                  This is where I'm still having trouble. Check this out:

                  Click image for larger version

Name:	ue4_ste1nar_inaccurate_health.png
Views:	1
Size:	17.1 KB
ID:	1127771

                  That's what the health UI looks like at 0 health. The character is dead. And yet there's still a whole bar of health remaining in the UI. That would sure confuse anybody playing. There are two For Loops in the event (not counting the For Loop in Event Construct). I tried changing their index from 0 to 1, but all that seemed to do was shift the issue, like this:

                  Click image for larger version

Name:	ue4_ste1nar_extra_index.png
Views:	1
Size:	11.2 KB
ID:	1127772

                  What do you think?
                  I'm an artist! Check out my work at https://cinebst.wixsite.com/cinebeastart and hit me up!

                  You can e-mail me at cinebst@gmail.com.

                  Comment


                    #10
                    Oh, you're using max health to set the last loop index. I don't think you ever need the max health at all, only the current health. Or if you prefer to keep it, I think it would fix it to flop those lines from max health and current health.
                    So max health should lead to last index of first loop. I would use a floor +1 instead.
                    Current health should lead to that floor node in your screen shot and the - node.

                    Comment


                      #11
                      Instead of trying to track individual hearts, you can use a repeating heart texture and just fill the bar normally.
                      https://www.casualdistractiongames.com

                      Comment


                        #12
                        Originally posted by ste1nar View Post
                        Oh, you're using max health to set the last loop index.
                        Not anymore. Sorry, I should have posted my updated graph in my last post.

                        Click image for larger version

Name:	ue4_ste1nar_graph.png
Views:	1
Size:	156.8 KB
ID:	1127778

                        As you can see, I'm not using Max Health for anything anymore. And I took your advice and added a variable in the UI that keeps track of our current hearts. That variable is first set in Event Construct, and used to determine how many hearts/bars to display.

                        The problem persists, though.

                        Also, thanks for the suggestion, [MENTION=11900]OptimisticMonkey[/MENTION], but that wouldn't quite capture the effect I'm going for.
                        Attached Files
                        I'm an artist! Check out my work at https://cinebst.wixsite.com/cinebeastart and hit me up!

                        You can e-mail me at cinebst@gmail.com.

                        Comment


                          #13
                          Ah now I know what it is, because I had the same bug. It was my setup all along - When updating the whole hearts, the loop starts at index 0, so most things needs to be reduced by 1.
                          So it should be:
                          Floor - -1 - last index of the last loop.
                          Floor - Get child at (so removing the addition node).
                          Floor - current health (so removing the addition node).

                          That zero index always complicates things.

                          Comment


                            #14
                            Originally posted by ste1nar View Post
                            So it should be:
                            Floor - -1 - last index of the last loop.
                            Floor - Get child at (so removing the addition node).
                            Floor - current health (so removing the addition node).
                            I'm not 100% following you, sorry. Something like this?

                            Click image for larger version

Name:	ue4_ste1nar_graph.png
Views:	1
Size:	157.8 KB
ID:	1127786

                            I also went and added a -1 to the last index in the Event Construct, since the UI was creating an extra, empty bar/heart. As far as I can tell this is mostly working, but I'm still seeing a discrepancy between the health displayed in the HUD and the actual health in the player blueprint. Now, when the player drops to 0 health, half a bar is displayed on the HUD.

                            Click image for larger version

Name:	ue4_ste1nar_inaccurate_health.png
Views:	1
Size:	10.4 KB
ID:	1127789

                            I must've misunderstood one of your points.
                            I'm an artist! Check out my work at https://cinebst.wixsite.com/cinebeastart and hit me up!

                            You can e-mail me at cinebst@gmail.com.

                            Comment


                              #15
                              Now it's looking identical to what I have and mine's working.
                              When health becomes 0, does it always display half a bar, or the previous health amount? I mean, does it display 0.5 bar even if the previous hp was say 5.2?
                              Is it possible that you query the health and if <= 0, it does not update the widget?

                              My nodes:
                              Click image for larger version

Name:	Hearts7.png
Views:	1
Size:	86.7 KB
ID:	1127792

                              Click image for larger version

Name:	Hearts6.png
Views:	1
Size:	165.4 KB
ID:	1127793

                              Comment

                              Working...
                              X