I’m trying to figure out a method for making a health bar in my HUD that is non-rectangular - specifically, a sphere that fills up with liquid or something from bottom to top. Normally for health bars I’ve always just used scale to set how full the bar is, which of course only works if the bar is straight.
At the moment I see two ways to go about it - have the bar have only a finite number of positions of fullness, each saved as a seperate image in a texture atlas, and cycled through like a sprite animation. This of course would work fine but would not animate smoothly, only in pre-defined chunks. The other method I see is digging through the docs on set-pixel and see if I can figure out a way of carving the exact shape needed with code.
Any thoughts or suggestions? Anyone else tried something like this before?
the pixel approach would be easy. just draw a horizontal line till you read the “border color” (black or whatever)
be it to empty it or to fill it.
Alternative ideas are pure geometry based ones though they might not really be any faster unless your orb is surrounded by non transparent areas so you could basically make the orb + surrounding a mask and draw the filling as a single quad behind that plane.
I would use dreamora’s second approach with a masking object in front of a square plane.
If you have transparent areas around the orb, create an object that just culls whatever is behind it. This culling object could be a square with a circle cut out of its center, or you could use a plane with a material using an alpha with a circle in its center to determine where to cull.
This is how I did a variety of effects in the HUD for touch ko.
Example Shader (just culls whatever is behind it on its layer):
Others seem to have posted the (probably better) approaches, but…
To add to what others are suggesting, you asked specifically about an Orb, why not use a … well orb (sphere), either 2 colour or half “health” color, half transparent, and rotate the orb based on health?
I think I’ll be going with Adam’s handy dandy shader, it sounds quite simple and effective. I didn’t even know you could use an object as a mask for another object, which is pretty much perfect for this scenario.
So… I tried this out and it just culls everything behind the object in question all the way to the background, no matter what layers the objects in question are on. Am I missing something? How do I tell it to only effect specific objects?
Change the queue so that things that get culled are after Background and things that are not are before it (so Background-1 or something)
Sandwich stuff depth-wise so back is health meter plane, middle is culling object, front is frame object. (Well this is assuming your HUD is on a separate camera anyway)
I’ll probably go with multiple cameras. I’m not familiar with shaders at all, never wrote one myself, so I don’t really know what changing the queue is actually doing (I played with it a bit but haven’t been able to produce different results).
Why not using a texture with fE 10 frames (from empty to filled) ? and you can animate allways only the uper part of the water with an another texture that has fE 4 frames.
Adam,
Can you explain how to Render it to a separate camera? I too need the culling shader to only cull a certain layer/object, and not all the way to the background. How can I do this? ( I don’t know much about shaders either)
Use this during an OnGUI code. It draws an image cropping it (not scaled) horizontally based on a normalized value (0.0 through 1.0) so an orb image would work just fine. Take note though you need to change it a bit if you want it to crop vertically.
static public void DrawBar(int x, int y, int w, int h, Texture2D bg, Texture2D fg, float val)
{
// Create one Group to contain both images
// Adjust the first 2 coordinates to place it somewhere else on-screen
GUI.BeginGroup( new Rect(x,y,w,h));
// Draw the background image
if (bg != null)
{
GUI.DrawTexture( new Rect(0,0,w,h), bg);
}
// Create a second Group which will be clipped
// We want to clip the image and not scale it, which is why we need the second Group
GUI.BeginGroup( new Rect(0,0,(int)(val * w), h));
// Draw the foreground image
GUI.DrawTexture( new Rect(0,0,w,h), fg);
// End both Groups
GUI.EndGroup();
GUI.EndGroup();
}
why not have 2 textures with transparency.
One texture be your empty “orb” container. This would have the center semi transparent so the liquid shows.
Second texture is the orb full, with an alpha map around it so it is transparent.
Then just scale the texture vertically… And maybe horizontally.
I ended up using the shader Adam posted and a second camera (this technique was ultimately used in OMG Pirates! to achieve the power-up sphere in the top left corner). Just had to set the second camera’s clear flags to knock out the background, and use a plane with the above shader to slice off the portion of the full sphere that I didn’t want to see.
MikaMobile
In Battleheart, how are you going about coding the “line” commands? (Drag the line then perform some action?) Also how are you actually creating the visible line?
The line (and dot on the end under your finger) are just two textured quads. Both ends of the line are bound to joints. Using the unit’s position, and the current position of your finger (derived from a raycast each frame against a ground plane) I position the end joint of the line at the finger’s position and the starting joint at the origin, thereby stretching the length of it from point A to point B. I’m also rotating the whole line to face its destination as well - its basically just a quad being rotated and scaled to connect two points in space. To keep it from being too herky-jerky there’s some lerping going on to smooth out the motion.
That is awesome. Wouldn’t have thought of doing it that way. Another question, how do ya’ll handle your environments. In our game Word Warrior, everything is orthographic but we had the artists design the assets in perspective to give it the perspective “feel”. Are you guys actually using a perspective camera? If so how do you keep your 2d mesh textures from “disappearing”? Also with your ground textures, how do you piece everything together? Just us SM2, make some pixel perfect repeating textures and then just drag multiple sprites together so they like right?
Couldn’t you use 2 images. One for the bar the other is the round gui graphic with transparancy drawn over top of it? Would this give you the effect you are looking for?