GM2 - Animated GUIs with few drawcalls!

After 24 pages of posts in the original GUIManager thread, I figure it was time to start anew so people won’t have to read through it all to figure out how to get things moving. I’m amazed at how many people have tried the manager and I hope that it has been helpful. Thanks to all for the constant feedback and I hope to continue improving upon the manager. I also would love to see some of the innovative things being produced with the manager, so if anybody wants to show off their stuff, please post it.

Features of the GM2 is:

  • Full transforms available. Position, full 3D rotation, scaling, and depth.
  • Reduce all GUI elements down to one drawcall
  • Use of texture atlas. This can be compressed to save memory
  • Animation system can animate any parameter in the GUI element
  • Frame animation system for sprite animation needs
  • Get callbacks to the GUI element when a touch event occurs
  • Fade in/out individual elements or all elements
  • Tint or shade GUI elements
  • Resize GUI elements dynamically
  • Integrate GUIText and GUITexture to the scene
  • Up to 10 GUILayers to create interesting overlays
  • Support for all 5 touches on the iPhone
  • Works for both iPhone Unity and regular Unity. So code once and build for both.
  • Adjustable sized touch area response for GUI element.
  • Screen resolution independent. The manager is not just for the iPhone anymore.
  • Much simpler setup from previous versions
  • Pixel perfect GUI object collisions. Create crazy shapped buttons and now have them send false touches anymore.

Usage:

  1. Create an empty project.

  2. Import the package into your empty project. You should now get the Plugins, Shader, Textures folder, etc…

  3. Create a game object and name it “GUI”. Attach the GUIManager script from the Plugins folder to this object. Set the screen resolution. This is the main GUI system. If you wish to use the iTouch script for development on Unity Standard, attach that script to the object also.

  4. Create a game object under the “GUI” object just created. This is going to be the quad manager. Attach the GUIQuadManager script from the Plugins folder to this object. Set the position and rotation to 0,0,0. Set the scale to 1,1,1.

  5. Create a new game object and make it a child of the quad manager. Set the position and rotation to 0,0,0. Set the scale to 1,1,1. Attach the GUIQuadObject script to it from the Plugins folder.

  6. Fill out the setting in the inspector for the quad manager:

  • Material - Create a material with the texture atlas and use the ‘GUIManager’ shader or the ‘GUIManager with Backface’ shader if you need to render both sides of the quad. You’ll find the shaders in the GUIAssets->Shaders folder.
  • Alloc Block Size - You can set to to whatever you want. It just has to be 1 or more. This is amount of memory to allocate after all memory from the previous allocation is used up.
  1. You need to create 10 new user layers so that all the GUI objects will only be rendered by the respective GUICameras and not the main one. You can do this by clicking the layers pulldown and selecting Add New Layer. Then type in GUILayer1 for User Layer 8, GUILayer2 for User Layer 9, etc…for the ten new layers.

  2. Fill out the settings in the inspector for the child:

  • MColor – Set the tint and alpha for the gui object.
  • MWidth - The width of the gui object
  • MHeight - The height of the gui object
  • MLocation - The initial location on the screen this gui object should be at. The anchor is in the middle of the gui.
  • MRotation - The initial rotation of the gui object.
  • MScale - The initial scale of the gui object.
  • MUV - The lower left UV coords of the texture map to skin this gui object.
  • MDepth - The layer order. Larger value objects gets placed further back.
  • MAnimUV – This is the UV coords for the first frame in a sprite animation filmstrip.
  • MAnimCols – The number of columns for the sprite animation filmstrip.
  • MAnimMaxFrames – The total number of frames in the sprite animation.
  • MCollider - You can select None, Square or Circular hit areas used for touch inputs.
  • MCollider Size – Size of the touch area associated with this gui object.
  • MVisible - Is this gui object visible
  • MEnabled – Determine if the gui object will response to inputs like the mouse or touches.
  1. Make sure to select the layer value of the parent and all the children to the render on the GUILayer you want.

  2. Turn off the layers you created in the main camera under the Culling Mask settings. The layers you created should be unchecked.

  3. Create the gui handler script. This script handles the callbacks from the manager. You will do all your app logic here. Attach this also to the child object. You should now have a single gui object on the screen when you run the project. Please check out the sample scene included in the package to see how the manager can be used.

Reference:
GUIQuadObj Class:
This class handles the quad for all the GUI elements. It communicates with the GUIQuadMgr to merge all the elements into a single mesh.

Parameters:

  • GUIQuadObj.QuadManager: Gets a pointer to the GUIQuadMgr this object is attached to.
  • GUIQuadObj.QuadSprite: Gets a pointer to the GUISprite class used internally.
  • GUIQuadObj.Tint : Set/Get the objects color.
  • GUIQuadObj.Width: Set/Get the objects pixel width.
  • GUIQuadObj.Height: Set/Get the objects pixel height.
  • GUIQuadObj.Location: Set/Get the objects location on the screen in pixel coordinates.
  • GUIQuadObj.Rotation: Set/Get the objects rotation in degrees. You can do rotation on all three axis. To get rotation with perspective, set the camera under the master GUI object to perspective. Otherwise, you’ll get orthographic rotations.
  • GUIQuadObj.Scale: Set/Get the objects scale. One unit represent on width/height value of the object.
  • GUIQuadObj.UV: Set/Get the UV coordinates for the lower left corner of the quad.
  • GUIQuadObj.Depth: Set/Get the layer depth of the object. Larger numbers places the object farther back.
  • GUIQuadObj.AnimUV: Set/Get the UV coordinates of the start of the sprite animation filmstrip.
  • GUIQuadObj.AnimCols: Set/Get the number of columns in the sprite animation filmstrip.
  • GUIQuadObj.AnimMaxFrames: Set/Get the total number of frames in the sprite animation.
  • GUIQuadObj.Visibile: Set/Get the objects visibility.
  • GUIQuadObj.Enabled: Set/Get whether the object responds to input events.

Methods:

  • void GUIQuadObj.StartFPS (int StartVal, int EndVal, float Speed, FrameMode AnimMode)
    This functions start the sprite frame animator. The start frame, end frame, and FPS is used to control the animation. The FrameMode determines the playback type:

  • GUIQuadObj.FrameMode.ForwardOneShot – Animated forward once and stop.

  • GUIQuadObj.FrameMode.ForwardLoop – Animate forward looped

  • GUIQuadObj.FrameMode.BackwardOneShot – Animated reversed once and stop.

  • GUIQuadObj.FrameMode.BackwardLoop – Animate reversed looped

  • GUIQuadObj.FrameMode.Bounce – Animate frames back and forth, looped

  • void GUIQuadObj.StopFPS ()
    Stop all sprite frame animation.

  • void GUIQuadObj.AnimateTo (float Duration, GameObject CallbackObj, object CallbackMsg, object CallbackParams, params object[ ] args)
    This function animates the GUI parameters from the current state to the desired state then call the specified callback function.

  • void GUIQuadObj.AnimateFrom (float Duration, GameObject CallbackObj, object CallbackMsg, object CallbackParams, params object[ ] args)
    This function animates the GUI parameters from the desired state to the current state then call the specified callback function.

  • void GUIQuadObj.AnimateBy (float Duration, GameObject CallbackObj, object CallbackMsg, object CallbackParams, params object[ ] args)
    This function animates the GUI parameters from the current state by the amounts in the desired state then call the specified callback function.

  • void GUIQuadObj.StartAnimation (Animate Mode, GameObject CallbackObj, object CallbackMsg, object CallbackParams)
    Starts a series of buffered animation commands then call the specified callback function. Use Ani.Animate.OneShot or Ani.Animate.Loop for the mode.

  • voidGUIQuadObj.StopAnimation ()
    Stops the current animation, but does not clear the buffered animation sequence.

  • voidGUIQuadObj.ClearAnimation ()
    Clears all buffered animation commands.

  • void GUIQuadObj.UpdateTransform ()
    Updates the vertices of the object if it has moved due to changes in the transform of itself or any of its parents. You must call after changing any of its parents transforms to re-sync the object with the new world coordinates. If you don’t do this, the hit areas and the paint area will be in the wrong place.

Callbacks/Events:

  • onGUIUp (iPhoneTouch pTouch)
  • onGUIDown (iPhoneTouch pTouch)
  • onGUIMoved (iPhoneTouch pTouch)

GUITextObj Class:
This class handles the use of the GUIText component. You don’t need to use this as you can directly handle GUIText components yourself, but I’ve already created a buffer of GUIText elements and this class is the interface. By using this interface, you won’t have to create and destroy GUIText components all the time. You can just keep reusing them.

Parameters:

  • GUITextObj.GameObj: Gets a pointer to the gameobject this GUIText component is attached to.
  • GUITextObj.TextObj: Gets a pointer to the GUIText component.
  • GUITextObj.GUIActive: Set/Get the flag to determine if the GUIText is being used by someone.
  • GUITextObj.Text: Set/Get the text string for the GUIText.
  • GUITextObj.Location: Set/Get the pixelOffset for the GUIText.
  • GUITextObj.LocX: Set/Get just the pixelOffset.x parameter.
  • GUITextObj.LocY: Set/Get just the pixelOffset.y parameter.
  • GUITextObj.GUIDepth: Set/Get the Z transform parameter. This also sets the layering order for the GUIText. The larger the number is closer to the camera it is.
  • GUITextObj.TextMaterial: Set/Get the material use for text rendering.
  • GUITextObj.Enabled: Set/Get whether the GUIText is active.

Methods:

  • void GUITextObj.SetFormat (Font pFont, TextAlignment pAlign, TextAnchor pAnchor, float pSpacing, float pTabSize)
    This function sets up all most of the GUIText parameters.

  • void GUITextObj.Reset ()
    This function releases the GUIText from usage and makes it available for reuse.

  • void GUITextObj.CheckHit (Vector3 Coords)
    This function checks to see if the user clicked on the component. Pass the mouse input values.

  • void GUITextObj.AnimateTo (float Duration, GameObject CallbackObj, object CallbackMsg, object CallbackParams, params object[ ] args)
    This function animates the GUIText parameters from the current state to the desired state.

  • void GUITextObj.AnimateFrom (float Duration, GameObject CallbackObj, object CallbackMsg, object CallbackParams, params object[ ] args)
    This function animates the GUIText parameters from the desired state to the current state

  • void GUITextObj.AnimateBy (float Duration, GameObject CallbackObj, object CallbackMsg, object CallbackParams, params object[ ] args)
    This function animates the GUIText parameters from the current state by the amounts in the desired state.

  • void GUITextObj.StartAnimation (Animate Mode, GameObject CallbackObj, object CallbackMsg, object CallbackParams)
    Starts a series of buffered animation commands. Use Ani.Animate.OneShot or Ani.Animate.Loop for the mode.

  • voidGUITextObj.StopAnimation ()
    Stops the current animation, but does not clear the buffered animation sequence.

  • voidGUITextObj.ClearAnimation ()
    Clears all buffered animation commands.

GUITextureObj Class:
This class handles the use of the GUITexture component. You don’t need to use this as you can directly handle GUITexture components yourself, but I’ve already created a buffer of GUITexture elements and this class is the interface. By using this interface, you won’t have to create and destroy GUITexture components all the time. You can just keep reusing them.

Parameters:

  • GUITextureObj.GameObj: Gets a pointer to the gameobject this GUITexture component is attached to.
  • GUITextureObj.TextObj: Gets a pointer to the GUITexture component.
  • GUITextureObj.GUIActive: Set/Get the flag to determine if the GUITexture is being used by someone.
  • GUITextureObj.Image: Set/Get the texture for the GUITexture.
  • GUITextureObj.Location: Set/Get the pixelInset for the GUITexture.
  • GUITextureObj.LocX: Set/Get just the pixelInset.x parameter.
  • GUITextureObj.LocY: Set/Get just the pixelInset.y parameter.
  • GUITextureObj.LocW: Set/Get just the pixelInset.width parameter.
  • GUITextureObj.LocH: Set/Get just the pixelInset.height parameter.
  • GUITextureObj.GUIDepth: Set/Get the Z transform parameter. This also sets the layering order for the GUITexture. The larger the number is closer to the camera it is.
  • GUITextureObj.Enabled: Set/Get whether the GUITexture is active.

Methods:

  • void GUITextureObj.Reset ()
    This function releases the GUITexture from usage and makes it available for reuse.

  • void GUITextureObj.CheckHit (Vector3 Coords)
    This function checks to see if the user clicked on the component. Pass the mouse input values.

  • void GUITextureObj.AnimateTo (float Duration, GameObject CallbackObj, object CallbackMsg, object CallbackParams, params object[ ] args)
    This function animates the GUITexture parameters from the current state to the desired state.

  • void GUITextureObj.AnimateFrom (float Duration, GameObject CallbackObj, object CallbackMsg, object CallbackParams, params object[ ] args)
    This function animates the GUITexture parameters from the desired state to the current state.

  • void GUITextureObj.AnimateBy (float Duration, GameObject CallbackObj, object CallbackMsg, object CallbackParams, params object[ ] args)
    This function animates the GUITexture parameters from the current state by the amounts in the desired state.

  • void GUITextureObj.StartAnimation (Animate Mode, GameObject CallbackObj, object CallbackMsg, object CallbackParams)
    Starts a series of buffered animation commands. Use Ani.Animate.OneShot or Ani.Animate.Loop for the mode.

  • voidGUITextureObj.StopAnimation ()
    Stops the current animation, but does not clear the buffered animation sequence.

  • void GUITextureObj.ClearAnimation ()
    Clears all buffered animation commands.

257947–9275–$gm2_100201_369.unitypackage (111 KB)

Some have asked what the sample scene is suppose to demonstrate. I know the scene look quite odd with a bunch of object just doing weird things. Well, the sample scene demonstrates some of the feature of GM2. In the scene hierarchy, there are two quad managers and six quad objects. Below describes what they're demonstrating:

TestObj1:

This is the oval PLAY object that rotates back and forth. The script attach demonstrate the animation of the transform parameters and the color transparency. The Location, Rotation, and Color parameters are being animated. Also, this script show how to create a new GUIText and GUITexture object and animate them too. Total draw calls here is 3. One for the quad, one for the GUIText, and one for the GUITexture.

TestObj2:

This demonstrates sprite animation. It is the happy face eating the lollipop. The script show how to start the animation and keep it looped. Check out the texture to see how the frames are laid out. No drawcall is added.

TestObj3:

This object is attached to the 2nd quad manager and is the large rectangular PLAY sprite in the middle of the screen. This demonstrates 3D rotations and depth control. As you can see, the object is near pixel perfect and had perspective while rotating. In order to achieve the perspective, we had to set the camera to perspective mode and therefore we needed to render on a different layer. Because a new layer was used, one drawcall was added.

TestObj4, TestObj5, TestObj6:

These three objects are the circular X sprites. This set of icons demonstrates pixel perfect collision. No input events are sent unless the mouse is within the icons. Also, even though they overlap, the correct event is returned. No drawcalls are added.

So, if I add up all the drawcalls:
+1 QuadMgr1
+1 GUIText
+1 GUITexture
+1 QuadMgr2
= 4 drawcalls.

This may still seems like a lot, but this is just a demostration. You can decide not to use GUITextures or 3D rotations and get the calls down to 2. And if no text is needed, it'll be just one call.

Wonder if an any problem with ur file? i got an invalid layer on the GUI hierarchy. besides the preview doesnt show the GUI.

In the instruction, you must still do step 7 manually. Currently, there's no ways to create GUILayer names within code, so you'll have to name the GUILayers. Just click the Layers pulldown and start naming from User Layer 8 = GUILayer1, User Layer 9 = GUILayer2, etc... all the way to GUILayer10. I'm going to see if I can find a better way to assign layers in the next release. :smile:

Thanks mate!
U rock!

I been studying ur GUIManager for several weeks and I doubt my knowledge on C# is really limited.. haha... looking forward for more tutorials and documentation soon :)

No prob. I already have plan to remove the manual creation of layers. Another step to making it easier to incorporate the manager. :)

the UILayer need to create 10 layers, is just purely for make it to function or need to depending how many UI Elements i have in my project?

and got any clue to kill the rest of the UI when i hit one of the button?

The GUILayers are necessary to run the manager. It's 10 and only 10 layers. Also, what do you mean by killing the GUI when you press a button? You can make GUI's disappear by setting the visibility flag. GUI object can't be destroyed.

oh Thanks,

Meaning all my elements only can hide first on the scene instead of load up the GUI.

My Scene

Menu

  • Setting
  • Help
  • About
  • Back

All this element i need to draw out from GM first instead of asking GM to draw on the go. So as default i hide everything.

I usually like to have QuadManagers handle each GUI screen, then I can use SetActiveRecursively to turn on/off screens without affecting the drawcalls.

Sorry folks. I just realized I posted this in the UnityGUI forum instead of the iPhone forum. This package is meant mainly for the iPhone, but you can still use it for any Unity project. Please check the iPhone forum for continued discussion on GM2.

When do more then one Guitext, I get a new drawcall for each element?

using UnityEngine;
using System.Collections;

public class Button5 : MonoBehaviour {

    public float healthPlayerGUI = 0;
    public Material mat;
    public Font GUIFont;
    private GUIQuadObj thisObj;
    private GUITextObj ptrTitle;
    private GUITextObj ptrTitle02;
    private GUITextureObj ptrImage;
    private bool FadeDir;
    private GUIManager ptrGUIMgr;

    void Awake ()
    {
        thisObj = (GUIQuadObj) gameObject.GetComponent(typeof(GUIQuadObj));
        FadeDir = true;
        ptrGUIMgr = (GUIManager) GameObject.Find("GUI").GetComponent(typeof(GUIManager));
    }

    void Start ()
    {

        ptrTitle = ptrGUIMgr.ptrTextMgr.GetGUIText(gameObject.layer);
        ptrTitle.Text = "Health " + healthPlayerGUI;
        ptrTitle.Location = new Vector2(15f, 10f);
        ptrTitle.GUIDepth = 1;
        ptrTitle.SetFormat(GUIFont, TextAlignment.Left, TextAnchor.UpperLeft, 1.34f, 10f);
        ptrTitle.TextMaterial = null;
        ptrTitle.Enabled = true;


        ptrTitle02 = ptrGUIMgr.ptrTextMgr.GetGUIText(gameObject.layer);
        ptrTitle02.Text = "Carnage " + healthPlayerGUI;
        ptrTitle02.Location = new Vector2(350f, 10f);
        ptrTitle02.GUIDepth = 1;
        ptrTitle02.SetFormat(GUIFont, TextAlignment.Left, TextAnchor.UpperLeft, 1.34f, 10f);
        ptrTitle02.TextMaterial = null;
        ptrTitle02.Enabled = true;
        }

    void FixedUpdate ()
    {
ptrTitle.Text = "Health " + healthPlayerGUI;
ptrTitle02.Text = "Carnage " + healthPlayerGUI;
    }

    void onGUIDown (iPhoneTouch pTouch)
    {
        Debug.Log(gameObject.name + " Down");
    }
}

is that surpose to happen?

Roll over or mouse over states.. we would like to use this on our web player as well, and when a user mouses over the button show a roll over state.. any thoughts on how to do this with your system.

btw we are beta testing unity 3.0 and will provide any bugs or feedback we run into with the new builds

Hi guys I'm not sure if i missed something but i can't see anywhere to obtain a copy of the GUImanager??

Cheers,
D

BUMP**

BUMP**

The last version GM2 you will find on the iPhone Development forum -> http://forum.unity3d.com/viewtopic.php?t=43084&highlight=guimanager (you have to log in first)

Where is the sample scene for that GM2 . I can download the package in the first page and .... I can't find the sample scene made with GM2..

I´m very noob with GUI, (actually i´m doing buttons with 3d text :P ), but, does the GM2 can autodetect the aspect ratio automatically?... that could be good, if user is changing resolutions so the GUITextures will never get offset..

Hi, I have a question: How does GM2 work with iPhone 4 vs 3GS? What values should I use? 480x320 or 960x640?
Do I need to write any explicit code for compatibility? Also, should I have 2 Sprite sheets, one with retina icons/textures and on for normal stuff?

Thanks,
Cristi