- Home /
Progress bar moving texture?
I have a progress bar in my scene which basically increases its length, every time a certain input is given.
//This is in onGUI
GUI.BeginGroup(group2);
GUI.Box(box2, full, guifull);
//this is in update
group2 = new Rect(0, 0, Screen.width * 0.6f * barDisplay,Screen.height * 0.04f);
box2 = new Rect(1.5f, 2.5f, Screen.width * 0.6f, Screen.height * 0.04f);
barDisplay = mov*(1/(float)themaxmovespossible);
Now, my question is, how do I get this bar, to have a moving/changing constant texture. Something (or almost similar to) Gmail's loading bar, or the bar below a google image when you open it.
Example: http://www.thinkcreative.com/extension/site/design/site/images/animated_progress_bar.gif
I wish to get this effect somehow. My main issue is, this bar is being created dynamically using onGUI. I don't know how in the world will I be able to get the GUIstyle of this elemet to be animated. I could use a sprite sheet or something, but that would be if it was a plane texture made in the heirarchy, not a guistyle, that too one created dynamically by script.
Thanks!
I have read up a few questions on this before, but none solved my doubt particularly which is why I am creating a question!
Answer by brycedaawg · Oct 08, 2013 at 05:41 PM
A simple way to approach this problem is by using Unity's GUI.DrawTextureWithTexCoords; a link to this method's reference can be found here: http://docs.unity3d.com/Documentation/ScriptReference/GUI.DrawTextureWithTexCoords.html
Like GUI.DrawTexture, you can use this method to draw a texture, within a rectangle, on the screen. Unlike GUI.DrawTexture, however, you get to pick another rectangle with which Unity will 'slice' a section of the texture out and place onto the screen. Using this, you can effectively 'slide' the rectangle across the texture over time, giving you the same effect as the animated gif file you linked, but with the added benefit of using only a single frame image and not needing to render it in 3d in your scene.
Here's a very simple script I wrote that demonstrates using GUI.DrawTextureWithTexCoords. You'll need to provide your own texture, and it will most definitely stretch accross the screen, but it should provide you with enough information to create your own progress bar in your project.
using UnityEngine;
using System.Collections;
public class GUILoadBar : MonoBehaviour
{
private float loadBarProgress = 0.0f;
private const float loadBarSpeed = 0.25f;
public Texture loadBarTexture = null;
void OnGUI()
{
//Draw loading bar with offset texture coordinates
GUI.DrawTextureWithTexCoords(new Rect(Screen.width * 0.4f, Screen.height * 0.4f, Screen.width * 0.2f, Screen.height * 0.1f), loadBarTexture, new Rect(loadBarProgress, 0.0f, 1.0f, 1.0f), false);
}
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
//Move the bar along; keep it's position between zero and one for best float point precision
loadBarProgress += Time.deltaTime * loadBarSpeed;
if (loadBarProgress >= 1.0f) loadBarProgress -= 1.0f;
}
}
Really nice dude! Would this also work for say a button, in which I just want the button to switch textures over a period of time?
You could iterate over a few sub images in a sprite sheet using this method, yes. However, if you just want to switch between a few different textures over time, I'd recommend doing just that; save overcomplicating things for yourself.
Answer by robertbu · Oct 08, 2013 at 07:36 AM
I see two different approaches to this problem. One approach uses a set of textures to animate the bar. The link you provided is to an animated GIF, which is really composed of 16 separate images. You can do the same thing in Unity. You initialize artex in the following code to the set of images that animate the progress bar. Adjust 'percentage' to cause the bar to grow or shrink.
#pragma strict
var artex : Texture[];
var percent = 0.5;
var framesPerSecond = 8.0;
private var curr = 0;
function Update() {
curr = (Time.time * framesPerSecond) % artex.Length;
}
function OnGUI() {
if(Event.current.type.Equals(EventType.Repaint))
Graphics.DrawTexture(Rect(10, 10, artex[0].width * percent, artex[0].height), artex[curr], Rect(0,0,percent, 1.0), 0, 0, 0, 0);
}
Another approach is to use a Quad in world space. With an game object in world space, I can control the material offset and scale/tiling. Here is the setup:
Add the following single tile segment to the project. I used Advanced and RGBA32.
Create a new material: Unlit/Texture with the tile segment as the texture
Create a Quad and size it to (1.0, 0.2, 1.0).
Attach the created material to the Quad.
Attach the following script.
Tile Segment:
Script:
#pragma strict
var offsetSpeed = 1.0;
var scaleRatio = 4.0;
private var offset = 0.0;
function Update () {
offset -= Time.deltaTime * offsetSpeed;
renderer.material.SetTextureOffset("_MainTex", Vector2(offset,0));
renderer.material.SetTextureScale("_MainTex", Vector2(transform.localScale.x * scaleRatio, 1.0));
}
You adjust the transform.localScale.x to make the bar shrink and grow. Note that I did not get a perfect cut on the segment, but it is close and you get the idea. Also note that neither of the solutions implement the progress bar background.
Thanks Robert! I believe I'll be going with the artex approach, as I'm doing everything in onGUI and according to screen coordinates.
If possible, could you explain the artex approach in a little more detail and possibly tell me how to do some variations in it as well?
The code works by rotating through a series of frames to animate the action. The easiest way to understand the code is to play with it. One source of frames is animated GIFs (including the one at your link). Pull any animated GIF into a later-version of Photoshop, and you can save out the frames. Or Google "get frames from animated gif," and you will find both online solutions and downloadable tools for extracting frames.
Once you have the frames, import them into your project. Attach the above script to an empty game object. Then in the inspector, first set the size of artex to the number of frames, then drag and drop the frames in the slots of the array. Hit play. You can adjust the Percentage variable in the inspector and watch the progress bar grow and shrink while still animating.
Shortcut: You can use the lock icon in the upper right corner of the inspector to lock the view to your script. Then you can select all the frames and drop them all on artex at once.
I don't know what you mean by variations.
Answer by ShadoX · Oct 07, 2013 at 08:05 AM
You could try displaying a animated texture and hide it using some layer, I presume. I'm not too sure how the loading bar is supposed to look since the example you linked to isn't animated either.
Your answer
Follow this Question
Related Questions
Load Level 01 Progress Screen 0 Answers
Want to create a moving line over a filling object 1 Answer
Trying to pick one or the other 1 Answer
Timer With GUI 0 Answers
Is it possible to get a smooth WebGL Progress Bar? 0 Answers