How can I create dynamic health bars?

Godot Version

4.2.2

Question

I’m trying to make segmented health bars kind of like in Overwatch and The Finals.

I currently have a stretched out Godot icon.svg colored red and black with proportion to health, but that only tells you the ratio. A health bar with segments like this gives players a lot more information. I can’t figure out how to even approach this though.

These health bars also stay the same size no matter how far or close they appear on the screen. I’m not sure what shader property does that.

image

what information are segmented health bars trying to convey?

Each segment represents 25 health in those games, but it could represent any fixed amount of health.

1 Like

You can probably do so by attaching a Sprite3D to your characters and enable the “Billboard” flag (“Y-billboard” will lock pitch, but quad will head toward camera) and enable “Fixed Size”.

You might be able to use a regular texture with an alpha gradient and use alpha scissors.

Or you can create a subviewport in which you can instance any Node2D or Control to draw your health bar, or use a full subviewport quadmesh and play around with shaders.
Finally add the subviewport path to the new viewport texture you created in the Sprite3D.

I’m not sure how to achieve good subviewport UI quality yet though.

1 Like

what information are segmented health bars trying to convey?

Segmented health bars make it easier to distinguish at a glance between enemies having not much health (few large bars), and enemies having a lot of health (lots of smaller bars).

2 Likes

so you want a segmented health bar, with each section representing a specified amount of health? You also want the size to scale between players and enemies. And youre using shaders to accomplish this? I’m not being sarcastic or anything, just new to godot and gamedev in general and am generally curious! Maybe we can figure this out :smiley:

idk if this is helpful, in the step by step guide, theres a section on using signals and it provides an example on health bars:

Any node in Godot emits signals when something specific happens to them, like a button being pressed. Other nodes can connect to individual signals and react to selected events.

Signals have many uses. With them, you can react to a node entering or exiting the game world, to a collision, to a character entering or leaving an area, to an element of the interface changing size, and much more.

For example, an Area2D representing a coin emits a body_entered signal whenever the player’s physics body enters its collision shape, allowing you to know when the player collected it.

In the next section, Your first 2D game, you’ll create a complete 2D game and put everything you learned so far into practice.

maybe you can attach a shader to a signal or something to change the value and size of health bars?

I’m kind of just looking for a shader script that does the segmenting. Right now I use a simple shader that doesn’t have the segmentation and I just set a shader var to the health ratio each frame.

oh, cool. i dont know much about shaders. sounds simple enough if you know what to do :smiley:

Yeah, I don’t though, which is why I’m asking. Shaders are hard.

dont know how relevant this is.
found a video on segmenting health bars with shaders:
edit: you did say you were looking for a script though.
edit: disregard the youtube video. this is a much more relevant resource i think.

its circular. im sure you could tailor it to your need though!
edit: sorry if none of this is helpful. here’s one more video and ill leave you alone.

The second link you sent is what I currently have for my health bars.

that what it seemed like

could you possibly string together multiple sections/boxes of health (mini health bars if you will) to somehow replicate the screenshot above?

my logic being once one box has depleted, it tabs over to the next box, and so forth. you could reference (dunno if this is the correct word) each individual box to a total health value somehow? (i have no clue what im talking about)

seems convoluted. and im positive theres probably a simpler way. this might just get you to where you need to be for now?