- Home /
GUI: How to "fill" a percentage of a texture?
I am trying to make my GUI more ... lets just say fancy, for the lack of better word :) But i am not sure it can be done in unity. Basically i have a texture that i want to fill up to a specific percentage, depending on the progress of a "upgrade".
In the example image below the "upgrade" is half filled. I am looking for a way to be able to do this, dynamically, via the gui tools or shading (if possible), so i wont need to have every stage of the "upgrade" as a separate image.
Note that only the gray border is "lighting up". :)
Any help, suggestions, directions, thoughts or comments on the matter would be appreciated :)
What i am thinking for a possible solution is to have both the 0% upgrade and the 100% upgrade images, and depending on the progress merge them at specific point on the Y axis, creating the desired effect. Although this can be a little tricky. Thoughts?
Have you seen this very popular answer? http://answers.unity3d.com/questions/14770/creating-a-circular-progressbar-timer.html
Yes this is pretty much what i need in a nut shell, but the example is applied to a 3d object with mesh renderer. Since there is no material support on the unity gui(or is it?) i dont think this solution applies here :(
In case you got the funds, consider using a procedural material, but you'll need Substance Designer for that.
Answer by LesPaul · Apr 22, 2013 at 06:16 PM
Try using the Texture2D.GetPixel() and SetPixel() functions. Put those in a loop that will cover the whole texture. First: check to where the texture should be rewritten to hight-wise. Then check which colors below that line are the color grey you make the borders that need changing using the GetPixel() function. If that pixel is the correct color, change it to the color it should be using the SetPixel() function.
Beware though: this could lag your game out a bit, but you can avoid that by only calling the loop when the bar needs to be changed hight-wise
Yeah, something along your idea. What i have done currently is a bit more optimized. Using GetPixels and SetPixels. Basically calculate what percentage need to be with the "filled" texture and what needs to be with the "empty" texture. Then copy those 2 GetPixels arrays into a third that will be the resulting SetPixels texture and compressing it for faster drawing.
Changing the third texture only when needed of course, not on every OnGUI call.
For the ones interested in the resulting code:
float fillP=0.2f;// fill percentage
empty = (Texture2D)Resources.Load("shieldempty");
full = (Texture2D)Resources.Load("shield");
half = new Texture2D(empty.width, empty.height);
int fillH = $$anonymous$$athf.RoundToInt(empty.height * fillP);
int emptyH = empty.height - fillH;
Color[] bottom = full.GetPixels(0, 0, empty.width, fillH);
Color[] top = empty.GetPixels(0, fillH, full.width, emptyH);
Color[] all = new Color[half.width*half.height];
Array.Copy(bottom, all, bottom.Length);
Array.Copy(top, 0, all, bottom.Length, top.Length);
half.SetPixels(all);
half.Compress(true);
half.Apply();
And then basically draw the texture when needed. I am currently trying to figure out a way to draw the "border" between the filled and the non filled texture. Probably with a 3rd texture that will hold only the gradient "border" texture.