I’ve been working on dungeons for a while now, so I think it’s time to get back to gameplay stuff and feedback. Namely, I want to start doing some HUD/UI work. The big picture is that I am going to keep it very simple and add only the crucial HUD stuff. “It’s there because there is no better way to show it.” I am not actually 100% sure what I need in the HUD because I don’t have my gameplay finalized. It’s all gravitating towards heavy gunplay, so that’s what I’ll plan for the HUD. I want some RPG elements (inventory, levels, stats) too but I will not add any of that yet unless I actually get to implementing those.
The big part of work at this point is to wire it all in the game to the actual player’s vitals. A new HUD system, new HUD canvas and camera, scripts to connect it all, all the initialization and update pipelines, relevant value change events and updates, proper world initializing and restarting, etc.
Well anyway, I definitely need a health bar. The player currently has no way of knowing their health or how much damage things deal. This will be a fixed HUD element (that is, not in the world of somehow moving around the HUD) and I won’t be doing anything overly fancy. I made some sprites some time ago for a shootery game prototype and I’ll just use them here for now. They are already almost in the format I want:
I will go a step further from the basic horizontal fill-style bar logic. Instead, the bar is made up of individual segments, including segments for left, middle and right bits — both foreground and background. Arranged as UI elements, it looks like this (1 with left sprite, 8 with middle, and 1 with right for a total of 10 elements):
To note, I have a custom layout script that knows how to lay out all its children in a specified direction, here – left-to-right. That way I don’t need to bother manually spacing things out every time I need things to arrange themselves in a row (or table).
Here’s a bar with some of the segments missing:
The one tricky bit here is that I might have 10 UI elements for a health bar, but use only 6. However, I need to preserve the rightmost element as is, that is I am using elements 1 to 5 and 10 when I need 6 bars:
The segments represent a chunk of player’s health, set in the bar options. In the actual game, I have more granular health values than just the old-school style 1 hit = 1 bar. Currently, I have 10 health per segment. I’m not sure if this is something I want to display to the player, or if I will keep my current health values as non-integers. At the same time, I don’t want a health bar that spans 30 segments, because getting hit is unavoidable and shouldn’t be a massive penalty in my game. For now, I am fading the bar segment that is currently “being damaged”:
As an example, here the player has a max of 60 health and are currently on about ~45 health. This is between 4 and 5 full bars, so the 5th bar is faded proportionally. So it’s really as straight-forward as it appears. Some of the math to note here is using the values correctly to actually see the bar fade proportionally at extremes:
I just like to point out how finicky something like this can be. (Then again, I am inventing some arbitrary requirements for myself, like a segmented bar, when a two-sprite filled bar would have taken me 10 minutes to do.)
I also have sprites for armor and shields, so I might as well use these (this is all just excuses to post screenshots):
Of course, I need to implement shields and armor in the game first. There’s a lot of ways to do this, but I think I will just do the same amount/max amount as health does. I will also make incoming damage hit shields first, then armor, then health and overflow from one to the next correctly. I don’t know yet what the actual gameplay for this is. I can imagine some abilities or items that might give you armor or shields.
Anyway, here are the full bars:
In-game, the health/armor/shield max amounts are set by mob definition and tracked by the mob’s vitals container. Here are sample bars for 60, 20, and 40 points respectively:
Now the damage can hit whatever the “first layer” is, like shields:
Once shields deplete, I hide the whole bar and just leave the armor visible:
So now armor can get damaged:
One final case is when the player has shields but not armor. The bars look weird (compared to how they normally are) if the lower one is not offset as expected:
So I move the shield bar to the armor bar’s spot when there is no armor to show:
And all of this works fairly nicely:
I am keeping a background for shields and armor visible, implying a certain maximum from some source. I’m not sure this is actually how I would do this. Although it does make it clear what the total extra protection was before it depletes. For example, a depletable armor item.
One of the things I previously mentioned is the weapon reload, which has no feedback yet. It’s an important part of gameplay and so I should show the bullets on the HUD. I also had some basic sprites for this:
In fact, they use pretty much the same logic as the bars, just without fading:
Is this overkill? I think this is going to get annoying when the bar is constantly changing size. The player’s bar is already doing animations. I think I should just show bullets as 24/30 (this way I can even show the right ammo type as icon):
Of course, I need a new font now (default Arial won’t really fit the game):
And may be a new icon:
Good enough. For reference, my full-screen HUD will probably be this big relative to the full viewport:
I don’t really know where I want to put the player’s info HUD elements. Top-left is the arch-typical retro-y location. I could consider other corners or having a settings option for this, but I think I will just go with the basic recognizable style. My camera is also leaning back, if that matters. I don’t think this is an area where I need particular originality.
What else goes on the HUD then? I am not sure I want any sort of HUD or in-world UI for enemies for now, because most enemies die in a few hits anyway. This isn’t quite the RTS level of micromanagement where I need to see unit health. For now, I’ll leave them without any health bars by default. I think a health bar for the bosses (like a serious mob in an arena room) health might be a good idea for those epic battles. Firstly, I need to add an enemy type to enemy definitions so I know which mobs to track:
This is just a simple flag for now that doesn’t affect gameplay yet. Then I need to make an enemy tracker that detects enemies in range, and tracks and untracks them correctly. The important bit here is the distance when a boss is “detected” and “undetected”. (These are HUD-only concepts for now.)
Good thing is I can almost completely reuse my player’s health bar logic for this. I only need to align the bars to the right and have the bar deplete left-to-right:
There is one other feedback item I want to add to my health bars and that is the same kind of white hit blink like when enemies are hit. I don’t want to blink the whole bar, but just the current segment. It’s not quite as easy to just tint (color-lerp) and fade the sprite, because the default Unity UI sprite shader doesn’t do both and just using the alpha channel doesn’t work. First, I need a custom script with a tintable image that can be moved over some target sprite. And I need a custom shader variant that always keeps that image at maximum tint and alpha-fades the opacity only. Some tinkering later, this works okay:
The blinker has two options: the hang time (initial full opacity period) and fade speed (gradual lerp speed to 0). A blinker can be “reblinked” and it will go back to full. One visual problem is when the segment “damages into” the next segment — this causes the blinker to jump abruptly between segments (can be seen in above gif). This is even worse if one takes a multi-segment damage, like some boss getting owned by some ultimate ability. Abrupt UI changes is something I really dislike.
To have multiple blinkers, I basically encapsulate all the blinker logic in a subclass, and create as many blinkers as I need. Then I only need to additionally keep track of reusable images I use for blinking. Some more tinkering later, this works great:
All the same stuff works with the shields and armor bars. The only other issue is that shield and armor bars disappear instantly when they expire. This means the blinker does too. What I need is to fade it away slow enough that all blinkers finish their stuff. And it’s decent enough if you don’t pay too much attention to tiny discrepancies (shield bar teleported to armor bar spot):
And here’s the boss getting rapidly hit for multiple bars at a time:
The GIFs, so many GIFs!
I am complicating my UI code with the blinker logic, but I also don’t want my health bar to be the one doing this. This is something I can write once and then reuse elsewhere, if not in immediate HUD.
Alright, let’s go all the way: powerup bar. I also had sprites for this (that prototype was very… similar):
Will I have powerups? I don’t really know. I’d like to, but it’s a significant time investment into gameplay that I might not have time for. I might do some simple re-usable ability, sort of like a mana bar.
I could just accumulate the bar until it’s past a certain threshold and then use some special ability that spends all the power. The idea is that the player could use their power early and spend only some of it, but they cannot spam it all the time. I can do the threshold fairly easily and indicate it visually by swapping the foreground sprites with alternate versions:
Now, I need to somehow indicate that the bar is “active”. In case of the power bar, it mean the power is currently active. I can use a white background sprite that’s slightly bigger than the bar for this and stretch it to fit.
So everything together it looks like this:
Well, let’s go all out and use the same for gaining health, armor and health (it’s subtle, so it’s not very good in a GIF format due to speed):
This way it gives a little “friendly” indicator when gaining stats happens, which isn’t as intrusive as the stat loss blink.
We’ll see how this feels and I’ll likely tweak it, though I won’t cover any minor changes I do.
With that, I think I am coming to the end of the persistent HUD elements I need. I can’t think of anything else I really need (not that I really needed all that flashy feedback). And the things I can think of are just feature creep. The bottom-line is that I don’t have the art resources to have many HUD elements, so I have to be conservative. I will still need UI menus and such for the game, but that’s a separate blog post.