Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Irregularly shaped bars

Discussion in 'Immediate Mode GUI (IMGUI)' started by nickavv, Nov 28, 2009.

  1. nickavv

    nickavv

    Joined:
    Aug 2, 2006
    Posts:
    1,801
    Okay, so I know how to make a standard rectangular health bar with UnityGUI, but I was wondering how to do a bar like this:



    or a circular bar, or any other irregular shape. Thanks!
     
  2. KaelisAsur

    KaelisAsur

    Joined:
    Apr 9, 2009
    Posts:
    361
    Simply have a set of textures corresponding to certain health thresholds and use that.
     
  3. nickavv

    nickavv

    Joined:
    Aug 2, 2006
    Posts:
    1,801
    I had thought of that, but what if the plus sign was angled, so each section had to raise or lower diagonally? Or what about circular bars?
     
  4. KaelisAsur

    KaelisAsur

    Joined:
    Apr 9, 2009
    Posts:
    361
    Just make an 'angled plus' texture, then?
     
  5. nickavv

    nickavv

    Joined:
    Aug 2, 2006
    Posts:
    1,801
    No, because then when you decrease the height of the texture it will stop fitting its border image (as a slanted image shrinks vertically the intensity of the slant flattens). There has to be a way to use a certain texture as a mask, including it's transparent pieces, so that a masked texture doesn't show up around the outside of the mask.

    And that still doesn't answer the question about circles. These are things I feel like I should know. :p
     
  6. KaelisAsur

    KaelisAsur

    Joined:
    Apr 9, 2009
    Posts:
    361
    I think there is a misunderstanding.

    By 'set of textures corresponding to certain health thresholds' i meant that for every health threshold, you would have a different texture.

    Lets say you have for example 100 hp total, and decide to make 10 thresholds, so 0, 10, 20, 30 etc. So for 0, you draw a texture with an empty circle. For 10, you draw a circle filled in 10%. For 50%, you draw a circle filled in half. Then you cycle through those textures whenever hp changes.
     
  7. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    I thought so from Nick's second post, but I wanted to see how things developed first. I don't know of a better way to do this than to use a texture sheet, on a textured polygon. I haven't been using OnGUI lately, and don't know if the two things are compatible. For my GUI, I'm just switching the UVs on textured quads when appropriate, but that's certainly a pain compared to Unity GUI. I wish that Unity GUI used that kind of system instead of whatever slower method it does now. However, if it was so easy to make it simple, powerful, and fast, I'm sure that would have been what UT did in the first place.

    Now, either way, it's kind of lame, because you don't have the single-pixel precision level of a procedural approach. But in practice, I think you'll be okay as long as you know your own game, and create an appropriate amount of versions of the graphic.
     
  8. nickavv

    nickavv

    Joined:
    Aug 2, 2006
    Posts:
    1,801
    Oh, wow, that's a pain. >.- Okay, if that's what it takes, sure.
     
  9. DocSWAB

    DocSWAB

    Joined:
    Aug 28, 2006
    Posts:
    615
    Animating the UVs on a texture atlas is certainly a clean way to go.

    We did the following because we are capable at doing Flash animations and were able to leverage that:

    1. In Flash, create a tweened animation with all of the states of the health bar.
    2. Export the frames as PNG with alpha. (This gets you all of the images quickly and you don't have to assemble a texture atlas.)
    3. Put the images in the Unity Project in the Resources folder.
    4. Write a script that finds the files by name and assembles and array pointing to the textures.
    5. Quantize your health levels to the array index and select that texture to display.
    6. We display the texture on a GUITexture object but it could be applied to a custom GUIStyle in OnGUI just as easily.
     
  10. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    If you're not too attached to GUI calls, you could also use two textures: one for the background and another one for the contents that need to move with a value.

    Then render the background in a quad and the foreground in another quad. Now animate this second quad shrinking in size in the y direction corresponding to the variable it is mapped to. Of course, that would stretch the texture, which is not what we want. Therefore, we need to scale the v texture coordinate of the shrinking quad as well. You can do this simply by setting the Material.mainTextureScale variable on your material.

    While this will require a (small) amount of programming, at least it can be re-used. Unlike the "create dozens of textures" method, which requires you to create dozens of textures every time you need such a bar. It does have the disadvantage of abruptly cutting off the overlay texture, which may not look as pretty as having a custom image per state.
     
  11. DocSWAB

    DocSWAB

    Joined:
    Aug 28, 2006
    Posts:
    615
    All these methods are good, depending on what shape the meter is. Ours is truly irregular and can't be produced by moving and stretching.
     
  12. Barbur

    Barbur

    Joined:
    Oct 30, 2009
    Posts:
    160
    I don't get why it is not possible to tweak the u,v of a a Texture inside a Rect and being draw with a GUI.DrawTexture call. That call could have the option to modify the u,v coords of the texture. So now to do a simple uniform health bar I have to do miracles!
     
  13. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    You can actually do this with the GUI, but there's an extra little bit of complexity. You can render the background image using GUI.DrawTexture, but you can obscure part of the level gauge image by using a group. If you reduce the height of the group while increasing the top coordinate by the same amount, the height of the group will reduce. If you then draw the gauge texture inside the group, but use a negative top coordinate, the top of the image will be cut off by the top edge of the group. Since the explanation is a bit complicated, I've attached an example. This will also give you the chance to feast your eyes on some genuine programmer art. Bon appetit!
     

    Attached Files:

  14. Barbur

    Barbur

    Joined:
    Oct 30, 2009
    Posts:
    160
    Wow seems like this is what I was looking for. It is the group suppose to clip the filling texture? Because in my project does not seem to clip it. Do I need to do something extra like playing with depths? For some reason the texture is being drawn out of the group margins....
     
  15. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    The group should clip the fill texture. If you vary the level value between 0 and 1, you should see the fill texture shrink and grow within the outline. Depths shouldn't be an issue here.

    Is anything happening at all when you do this or is something happening but not what you wanted?
     
  16. Barbur

    Barbur

    Joined:
    Oct 30, 2009
    Posts:
    160
    First of all I have to say that I am using Unity Wii. Maybe there is something related Smile

    I copied your function and used a simple colored texture. I tried to draw only the group and the texture being clipped. But what I see is the hole texture moving down. It is like the group does not clip the colored texture for some reason. I am drawing the Group with another texture and it seems to grow correctly. Also the bar texture seems to move down. So I have no idea what could be happening.
     
  17. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    I guess this could be a Wii-specific issue (the code works on a Mac). Licensing restrictions mean that we can't really discuss Wii coding on the forum. Contact support@unity3d.com to get further help with this.
     
  18. Ricks

    Ricks

    Joined:
    Jun 17, 2010
    Posts:
    650
    Thanks this example "art" also helped me a lot.