Search Unity

GUIManager

Discussion in 'iOS and tvOS' started by besuser, Apr 30, 2009.

  1. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    I’ve been a long time user of Unity and have come to this great forum many of times when I’ve gotten stuck. I must say that this community is the best and most helpful I’ve seen of any game engine site. As I’ve learned so much from the forums, I’d like to contribute back to the community.

    One of the most troublesome things about working with the Iphone is the limited drawcalls and memory. For me, most of the optimization is done on the GUI. How to possibly keep the drawcalls down and use less memory. With the inspiration of others on this forum, I’ve come up with a possible solution that hopefully others can benefit from too. Now, this is only my interpretation of one possible solution and it works for me, but it's not by all means the answer to every situation. I give a shout out to the following for their great work:

    SpriteManager by Brady
    SpriteUI by CedarParkDad
    Ani.Mate by Adrian


    Features of the GUIManager is:
    - 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
    - Get callback to the GUI element when a touch event occurs
    - Fade in/out individual elements or all elements
    - Tint or shade GUI elements
    - Realtime depth sorting
    - Resize GUI elements dynamically
    - Mirroring. This can reduce texture needs by half.
    - Make GUI groups by parenting. There no need to be a direct child of the manager anymore.
    - Integrate GUIText and GUITexture to the scene
    - Layer up to 5 panels to create a windowed effect
    - 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. This helps detect touches even when the GUI object is small.
    - Pixel Perfect collision for mouse input.
    - Dynamic re-orientation when switching from portrait to landscape or vice versa.


    Usage:
    1. Create an empty project.

    2. Download the Unity package.

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

    4. Drag the GUIManager prefab into the hierarchy.

    5. Create 10 user layers. Start with user layer 8 and name it GUILayer1. Continue on naming the successive layers GUILayer2, GUILayer3...GUILayer10.

    6. In the GUI game object, create a game object. This is going to be the parent. 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.

    7. Create a new game object and make it a child of the parent. 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.

    8. Fill out the setting in the inspector for the parent:

    * Material - Create a material with the texture atlas and use the GUIManager Sorted shader. Apply it here.
    * Alloc Block Size - You can set to to whatever you want. It just has to be 1 or more.

    9. 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.
    * 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
    * Enabled - Will the gui object respond to input events
    * MFlipped – Is the gui image flipped horizontally

    10. Make sure to select the layer value of the parent and all the children to the render on the layer you want.

    11. Turn off the layers you created in the main camera under the Culling Mask settings. The layers you created should be unchecked. Otherwise, you double your drawcalls.

    12. 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. That should be it. Just run the project and you should see your newly created GUI.

    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.
    - 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.Enabled: Set/Get whether the object responds to inputs.
    - GUIQuadObj.Visibile: Set/Get the objects visibility.
    - GUIQuadObj.Flip: Set/Get the objects flipped flag.

    Methods:
    - 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.

    - void GUIQuadObj.StopAnimation ()
    Stops the current animation, but does not clear the buffered animation sequence.

    - void GUIQuadObj.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 Touch)
    - onGUIDown (iPhoneTouch Touch)
    - onGUIMoved (iPhoneTouch Touch)


    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.

    - void GUITextObj.StopAnimation ()
    Stops the current animation, but does not clear the buffered animation sequence.

    - void GUITextObj.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.

    - void GUITextureObj.StopAnimation ()
    Stops the current animation, but does not clear the buffered animation sequence.

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

    Attached Files:

  2. CedarParkDad

    CedarParkDad

    Joined:
    May 28, 2008
    Posts:
    98
    Ahhhh...now this is nice. I've been trying to get this to work correctly, and it's nice to see someone else get it done :) Congrats! I'll play with this a bit and provide some feedback. One word of advice when going forward: do not assume you will get every state you would expect. I would want to redo SpriteUI with that understanding, but I'm in too deep now. Basically, you'll sometimes get a Move without getting and Enter or Down, or just stop getting a touch instead of getting an Exit or an Up. That is why SpriteUI has become such spaghetti code...well, that and I never get that time to go back and clean it up ;-)

    Thank you for letting us play with this...I'm having fun just playing around now instead of making a game.
     
  3. Andrej-Vojtas

    Andrej-Vojtas

    Joined:
    Jan 12, 2009
    Posts:
    67
    Very nice, thank you for sharing this!
     
  4. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    Thanks all. CedarParkDad, I basically left it up to the user to figure out the touch states. I just do the callbacks in whatever order the touch phases come in. I'm sure this could be update to provide a known sequential path, so I'll have to think about this one.
     
  5. Muckel

    Muckel

    Joined:
    Mar 26, 2009
    Posts:
    471
    wow man....
    much respect !
    thank you very much...
    now i have again very nice stuff to play with :)

    kerstin :oops:
     
  6. kenlem

    kenlem

    Joined:
    Oct 16, 2008
    Posts:
    1,630
    Perfect! Just what I needed right now. Thanks.

    I don't see how to set or update the texture associated with the button. Anyone?
     
  7. kenlem

    kenlem

    Joined:
    Oct 16, 2008
    Posts:
    1,630
    MUV - phew... :) I knew it had to be there somewhere.
     
  8. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    I've updated the GUIManager such that it will create the GUI elements in the order specified by the Depth parameters. As long as the GUI elements are children of the main manager script, just set each childrens depth and the manager will sort them and set them up properly. This will allow you to order them up front, but not re-order then on the fly.
     
  9. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    I have a question with your tool. I got it up and running ok. I have a button that I have a show and a hide function on. The code is below:


    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class BtnPlayer1 : MonoBehaviour {
    5.  
    6.     private GUIObject thisObj;
    7.    
    8.     void Awake ()
    9.     {
    10.         thisObj = (GUIObject) gameObject.GetComponent(typeof(GUIObject));
    11.     }
    12.    
    13.     void Start ()
    14.     {
    15.         Show();    
    16.     }
    17.    
    18.    
    19.     void Show()
    20.     {
    21.         thisObj.AnimateTo(0.5f, "location", new Vector2(260f,250f));
    22.         thisObj.StartAnimation (Animate.OneShot);
    23.     }
    24.    
    25.     void Hide()
    26.     {
    27.         thisObj.AnimateTo(0.5f, "location", new Vector2(1000f,250f));
    28.         thisObj.StartAnimation (Animate.OneShot);
    29.     }
    30.        
    31.     void onGUIDown ()
    32.     {
    33.         SendMessageUpwards ("Hide", null, SendMessageOptions.DontRequireReceiver);
    34.         Hide();
    35.     }
    36.    
    37.     void onGUIUp ()
    38.     {
    39.         Debug.Log("Scores Up");
    40.     }
    41.    
    42.     void onGUIMoved ()
    43.     {
    44.         Debug.Log("Scores Moved");
    45.     }
    46. }
    47.  
    48.  
    Fairly straightforward, whenever the Hide() function is called though

    I get an error

    ArgumentOutOfRangeException: Less than 0 or more than list count.
    Parameter name: index
    0

    System.Collections.ArrayList.RemoveAt (Int32 index)
    GUIObject+<>c__CompilerGenerated0.MoveNext () (at Assets/Plugins/GUIObj
    ect.cs:289)


    I have a renamed version of this script on another 2 buttons as well.

    My question is how do I have a controllable sequencing of animations?

    Cheers
    Mark
     
  10. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    Blastone. Let me check this out and I'll get back to you. In the meantime, just to let you know, the animation sequences are being handle per object using a coroutine. So, the calls to StopAnimation and ClearAnimation could accidentally empty the array before the coroutine returns. This would cause the out of index error. I've been working on fixing this up so I'll let you know.
     
  11. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    Hi Blastone. It appears that you called the Hide() function twice in a row. One with the sendMessage command and then a direct call to Hide. This confused my startAnimation function. I've patch the code so that if an animation is in progress, it will return a false when you call startAnimation. This means you'll just need to stop the animation first or let the animation finish before it'll let you start the next set of animations.
     
  12. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    ah, the common trap for young players the double function call. Thanks for the code update, Ill play with it tonight.

    While on the feature request pathway:

    A "delay" would be awesome....

    I'm currently implementing it with an animation call to the same position over a timeframe, but it would be great to have a delay like in the Ani.Mate.To stuff (which you are using)

    One thng I did notice what that when I set the mRotation of the GUIObject in a function call of its button control script it didnt rotate. I ended up doing a very fast 0.01s rotation animation on it to rotate it properly.


    Anyways congrats on a nice set of tools, its got all my hud stuff down to a single draw call which is just great, and im really really really happy about having a single asset image and just picking the bits I need from that for the buttons and other display items.

    Its a lot faster then mapping it all in 3d :D


    now when it maps text that will be even better :D
     
  13. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    Sorry to ask another question, but Im also having a few issues getting the visible tag to work.....

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class Powerup : MonoBehaviour {
    6.  
    7.     private GUIObject thisObj;
    8.    
    9.     void Awake ()
    10.     {
    11.        
    12.         thisObj = (GUIObject) gameObject.GetComponent(typeof(GUIObject));
    13.         thisObj.location = new Vector2(158f, 240f);
    14.        
    15.     }
    16.    
    17.     void Start ()
    18.     {
    19.        
    20.         HideCircle();
    21.     }
    22.    
    23.     void Update()
    24.     {
    25.         thisObj.rotation += 2;
    26.     }
    27.    
    28.     void HideCircle()
    29.     {
    30.         thisObj.visible = false;
    31.         thisObj.StartAnimation (Animate.OneShot);
    32.     }
    33.    
    34.     void ShowCircle ( string type )
    35.     {
    36.         thisObj.AnimateTo(0.8f, "scale", 1.5f);
    37.         thisObj.StartAnimation (Animate.OneShot);
    38.     }
    39.  
    40. }
    41.  

    When I click the MVisible checkbox it turns visibility on and off (but not when running) but Im unable to script it. Did I miss something?

    One thing I have also noticed is that when I scale an item down in size, sometimes it leaves a large version of it on the screen towards then end of it. I can package up a demo of that if you like as its a strange one.
     
  14. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    Yeah, the inspector isn't realtime. I made the variables public so our art guys could do the initial setup of the GUIs. You can only update the varaibles via code. For the visibility, just use GUIObject.visible = true/false. As for the scale issue, I definately like to take a look at it. Thanks for helping me test this.
     
  15. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    I did try controlling the visibility with script using

    GUIObject.visible = true/false

    where GUIObject is the object in question (see my code above) but without success.

    Ill package you up a version with that scaling bug as well. Im happy to help you out its a pretty sweet little tool, and fun too.

    And I'm more then happy to throw requests to ... easing perhaps!
     
  16. blockimperium

    blockimperium

    Joined:
    Jan 21, 2008
    Posts:
    452
    Is there a way to tell a GUIObject to fade itself out while its moving? I'm trying to combine effects if possible.
     
  17. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    @Blastone. You can do easing and most other options as defined in AniMate. I did notice a small error in the Ani code which I think I've fixed. Anyhow, to use the easing, type this:

    thisObj.AnimateTo(4f, "location", new Vector2(120f,240f), "rotation", 180f, "easing", Ani.AnimationEasingType.SinusoidalEasing);

    Here are the easing modes you can use:

    LinearEasing
    QuadraticEasing
    CubicEasing
    QuarticEasing
    QuinticEasing
    SinusoidalEasing
    ExponentialEasing
    CircularEasing


    @gregorypierce. I don't think fading will be possible since all the sprite use the same material. If you faded one sprite, you'd fade all of them.


    I still have to figure out the visibility issue, but I've been working on trying to integrate some sort of text sprite. Unfortunately I think I'll have to re-write the manager to handle more than just quad sprites to do that.
     
  18. martaaay

    martaaay

    Joined:
    Apr 13, 2009
    Posts:
    136
    Very nice! I started playing with this last night. Has anybody done any performance tests on the various pieces? I need button pushing, straight line animation, and some minor scaling, so hopefully I'm not taxing the system too much..
     
  19. martaaay

    martaaay

    Joined:
    Apr 13, 2009
    Posts:
    136
    To add multiple touch support, replace GUIManager.cs's first Update bits with
    Code (csharp):
    1.  
    2.     void Update ()
    3.     {
    4.         RaycastHit hit;
    5.        
    6.         //Handle touch input
    7.         foreach (iPhoneTouch tmpTouch in iPhoneInput.touches) {
    8.             Ray ray = guiCamera.ScreenPointToRay (tmpTouch.position);
    9.            
    10.             switch (tmpTouch.phase)
    11.  
     
  20. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    Thanks Martaaay. It will definately be nice to have multi-touch. I'll add into the code base.
     
  21. blockimperium

    blockimperium

    Joined:
    Jan 21, 2008
    Posts:
    452
    Okay I just got around to trying to use this and working through the steps to get it setup. There is a bunch of stuff in the download that isn't addressed at all in the first post. Can someone summarize what's necessary?

    I created a new project
    I extracted GUIManager 051309
    I create a new Empty Game Object

    I see in the Assets/Plugins folder there is a GUIManager.cs, but there are a bunch of things in here is well. Can someone update with some getting started steps. I'll then turn that into a series of tuts for the wiki.
     
  22. 1r0nM0nkey

    1r0nM0nkey

    Joined:
    Apr 8, 2009
    Posts:
    131
    Looks promising. A couple things that caught my eye were:

    * you could use Rect.Contains (...) instead of RayCasters and Colliders for hit detection, taking care to manage layers, of course.

    * it is a fairly simple matter to add iPhoneTouchPhase.Cancelled to beef up the input handlng

    * a great companion to atlas managers is a texture stitching tool, there is source out there that can be ported; a good starting point is NVIDIA texture tools
     
  23. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    @Martaaay. I've added your multitouch code, but I haven't tested it yet and I don't have access to a iphone at the moment. Could you check to see if it's working. Thanks a bunch.

    @BlaStone. I've fixed the visibility problem. Looks like the animator kept on turning the sprite back on. Also, I found a circular reference in the SpriteManager code. Anyhow, should be fixed.

    @gregorypierce. Sorry my user's guide was so brief, but I'm focused more on creating apps for the iphone than writing up a length tutorial. I'll get around to it I sure.

    @1r0nM0nkey. I decided to use colliders so I wouldn't have to manager my own rects. Also, the colliders orient themselves to the transform of the sprite. This seemed easier than having to do my own transforms on a rect to make it follow the sprite.
     
  24. blockimperium

    blockimperium

    Joined:
    Jan 21, 2008
    Posts:
    452
    I don't want you to. I want you to focus on keeping forward momentum. As soon as I can figure out how to get it all installed and working I'll write up a full length tutorial. Right now I'm just trying to figure out what are the right steps for getting it setup and I'll put together a tut for it.
     
  25. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    No problem gregorypierce, here ya go:

    1. Create an empty project.

    2. Extract the GUImanager zip file. You'll get a Unity package.

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

    4. Create a game object. This is going to be the parent. Attach the GUIManager 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 parent. Set the position and rotation to 0,0,0. Set the scale to 1,1,1. Attach the GUIObject script to it from the Plugins folder.

    6. Fill out the setting in the inspector for the parent:

    * Material - Create a material with the texture atlas and the GUISorted shader. Apply it here.
    * Alloc Block Size - You can set to to whatever you want. It just has to be 1 or more.
    * UILayer - You need to create a new layer so that all the GUI objects will only be rendered by the GUICamera and not the main one.

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

    * PGUIManager - Drag the parent object to this location.
    * 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.
    * MCollider - You can select square or circular hit areas for input.
    * GWidth - The width of the gui object
    * GHeight - The height of the gui object
    * MVisible - Is this gui object visible

    8. Make sure to change the layer value of the parent and all the children to the layer you created earlier.

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

    10. 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.

    That should do it. You should see your single gui object somewhere on the screen.
     
  26. blockimperium

    blockimperium

    Joined:
    Jan 21, 2008
    Posts:
    452
    Excellent, thanks! I will be using GUIManager in my Newbie guide to help people get game GUIs going. Appreciate the assist.

    By the time I'm finished the series I expect that any newbie should be able to start from limited knowledge of Unity and get a simple game running with all the bells and whistles and be ready for the more advanced topics that Unity's team will cover.
     
  27. kenlem

    kenlem

    Joined:
    Oct 16, 2008
    Posts:
    1,630
    Does anyone know how to handle multiple screens? Would you have multiple instances of GUIManager?
     
  28. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    kenlem, it is possible to use multiple instances of the GUIManager. The only problem is that the one on this thread was only designed to be used as a single instance. This is so because the manager creates an instance of camera for use with the manager. If you create multiple instance, you get multiple cameras and that would multiply your draw calls. I do have a modified version that I use personally that can do it, but it's much more complicated to use and not very polished for general consumption. If you want to be adventurous, you can remove the create camera code in the manager and create your own static camera which you could reference to in the manager. Then you can instance as many as you want and only use a single camera to render all the GUIs.
     
  29. kenlem

    kenlem

    Joined:
    Oct 16, 2008
    Posts:
    1,630
    Thanks. That modification should work.

    My first thought was to create a hierarchy of items and turn things on and off as I need them.

    GUIManager
    MainMenu
    Button1
    Button2
    Help
    Button3

    That didn't work because I used empty game objects as the parent of each separate menu screen (MainMenu and Help). When GUIManager iterates through children, it expects those children to be spites (GUIButton).

    Now I'm wondering if I could do the same trick but just use an actual GUIButton for the parent?
     
  30. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    You won't be able to use a button as a parent since the parent (GUIManager) goes through all the children, sorts them, and then creates the mesh with them. You can create the heirarchy like this:

    Main Menu (GUIManager)
    Button 1
    Button 2
    etc...

    Help Screen (GUIManager)
    Button 3

    If you're able to remove the camera creation code from the manager, the above setup will work. Just make a static camera with the same settings as the one created by the GUIManager and you're good to go.
     
  31. kenlem

    kenlem

    Joined:
    Oct 16, 2008
    Posts:
    1,630
    Well that was easy.

    I just added another camera, removed its listener, edited the GUIManager.cs to not create the camera but still setting all the settings and made the GUICamera variable public. No need to worry about the settings on the camera as the GUIManager script does it.

    Perfect...
     
  32. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    You got it. You can also use a series of cameras and layers to create overlapping GUIs. This will allow you to mix GUIText/GUITexture objects with the GUIManager objects. Now, this won't save you draw calls, but it will give you more flexibility with your GUI interfaces.
     
  33. DarkJedi

    DarkJedi

    Joined:
    Apr 15, 2009
    Posts:
    48
    This alternative GUI framework sounded like the easiest to get to grips with so I just gave it a shot, and was impressed with how quickly you can get GUI elements up and running! 8)

    Thanks besuser, this is simply stunning!

    One feature I have added is the ability to "flip" (i.e. mirror) a texture on a GUIObject, something that saved us a bit of space in our texture map for parts of our GUI that were symmetrical.

    This was done simply by rotating the object around the Y axis 180 degrees as well. It works well enough for our purposes, though probably would need changing in a different plane (we only use XY).

    Rotation of a flipped GUIObject is in the opposite direction for a flipped object as well of course.

    Anyway, I shall PM you GUIObject.cs (based on 051409) in case it is an approach you might want to accommodate in the future! :)

    Thanks!

    Dan
     
  34. kenlem

    kenlem

    Joined:
    Oct 16, 2008
    Posts:
    1,630
    GUIManager seems really powerful. I like the way I can add personality to my GUI using the animation features. My menu buttons respond to touch by bouncing and wobble around. I think it helps to add a bit of polish to a project.
     
  35. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    Looks like I accidentally uploaded the Unity project folder instead of export a Unity package. I re-uploaded a package instead of the project folder.
     
  36. BigRedSwitch

    BigRedSwitch

    Joined:
    Feb 11, 2009
    Posts:
    724
    Hey,

    Nice work! I've been building this into my game today, and I've come up against a few problems - can you help me?

    1) With the following code:

    Code (csharp):
    1.  
    2. var Cleared: boolean;
    3.  
    4. function Start () {
    5.        Cleared = false;
    6. }
    7.  
    8. function Update () {
    9.     if ( Globals.Mode == Globals.AttractMode )
    10.     {
    11.         thisObj.AnimateTo ( 3.0, "location", Vector2 (35, 35) );
    12.         thisObj.StartAnimation(Animate.OneShot);
    13.     }
    14.     else if ( Globals.Mode == Globals.GameOver )
    15.     {
    16.         thisObj.AnimateTo ( 3.0, "location", Vector2 (-35, -35) );
    17.         thisObj.StartAnimation(Animate.OneShot);
    18.     }          
    19.     else
    20.     {
    21.         if ( Cleared == false )
    22.         {
    23.             thisObj.ClearAnimation();      
    24.             Cleared = true;
    25.         }
    26.     }  
    27. }
    28.  
    I keep getting the following exception:

    ArgumentOutOfRangeException: Less than 0 or more than list count.

    I figured I was calling ClearAnimations too many times, but as you can see, I've stopped that with the boolean, but it still spazzes out?

    2) Is there any way to make the texture of the GUI fade? I've looked at the shader for anything obvious, but I don't understand the shader language, so I can't easily modify it to allow this. It'd just be *incredibly* useful to me to be able to fade stuff out - doesn't matter if it's the whole thing, would just be cool.

    Thanks in advance for any advice - your code really does the stuff! :)
     
  37. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    Please try the updated version I uploaded today. It may solve your problem. If not, can you post a complete script so I can try it out on my end? As for the fading, unfortunately it is not possible since all the GUIs share the same material. If you use alpha on the material, it will fade all your GUIs.
     
  38. kenlem

    kenlem

    Joined:
    Oct 16, 2008
    Posts:
    1,630
    Might be nice to include an alpha so the entire GUI could be faded in and out.
     
  39. kenlem

    kenlem

    Joined:
    Oct 16, 2008
    Posts:
    1,630
    Just a thought about multitouch...

    I'd like to have the option on the GUIManager object to support either single or multitouch depending on what I'm doing. For example, I want the menu screens of my app to be single touch so that it doesn't get confused and respond to multiple touches and try and navigate away to two different screens. For the in game HUD, it make sense to enable multitouch for the interface.

    I can, of course, update my own copy of the code. Just putting it out there.

    Thanks again for GUIManager.
     
  40. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    Kenlem, if you have a system that works and you'd like me to integrate it into my code base, I'd be happy to do it.
     
  41. kenlem

    kenlem

    Joined:
    Oct 16, 2008
    Posts:
    1,630
    I'll send you the code snippet.
     
  42. BigRedSwitch

    BigRedSwitch

    Joined:
    Feb 11, 2009
    Posts:
    724
    This is what I'm after - it makes menu transitions look much slicker. :)
     
  43. BigRedSwitch

    BigRedSwitch

    Joined:
    Feb 11, 2009
    Posts:
    724
    Can you post a link to the new version? Cheers! :)
     
  44. Rapzid

    Rapzid

    Joined:
    Apr 25, 2009
    Posts:
    123
    besuser: Is your package still good to go with testing on non iPhone unity? The reason I ask is because I'm doing all of my coding in Windows first. I'll be doing iPhone specific stuff and iPhone testing a litte further down the road.
     
  45. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    @Rapzid. Yes it is. I've updated the iPhone.cs script such that it will work for both standard Unity and iPhone Unity. The preprocessor variable automatically adjusts for this.

    @S7arbvck. I see. If you want to fade all the GUIs, then it definitely possible. Let me look into this one. By the way, the latest version is always in the first post on this thread.
     
  46. besuser

    besuser

    Joined:
    Oct 9, 2007
    Posts:
    292
    OK. I've updated the shader to actually use the tint color as a parameter. Now, you can tint and set the alpha for all your GUIs. Remember, since all the GUIs use the same material, these settings will apply to everything. So, now you can lerp the alpha and fade the whole GUI out. Have fun!!! :D
     
  47. Rapzid

    Rapzid

    Joined:
    Apr 25, 2009
    Posts:
    123
    Is the test scene messed up? I two big buttons and one rotates on it's own and the other kinda blinks... They are on top of each other.

    Nm, I think I see what's going on.
     
  48. BigRedSwitch

    BigRedSwitch

    Joined:
    Feb 11, 2009
    Posts:
    724
    Dude - you rule. Works a treat! :)

    Thanks! :)
     
  49. BigRedSwitch

    BigRedSwitch

    Joined:
    Feb 11, 2009
    Posts:
    724
    Hey, again,

    Seems I'm having some issues...

    If I call an animation, like:

    Code (csharp):
    1.  
    2.           thisObj.AnimateTo ( 1.0, "location", Vector2 (240, 400) );
    3.           thisObj.StartAnimation ( Animate.OneShot );
    4.  
    I can't start another animation after this one without calling "ClearAnimation" first - even if the original animation has been stopped for a while. This is a bit of an issue, as my buttons scroll into and out of screen-space to keep the screen as clear as possible. What am I doing wrong?

    Also, thanks a bunch for adding the alpha on the texture, but how do I access it from the GameObject logic scripts? The material is part of the GUIManager, so accessing it from my Javascript code could be pretty difficult, no?

    Finally, a bit of a change I made - I turned all the colliders into triggers in the code - it works in exactly the same way but prevents you from having to turn off the collisions between the UI layer and other colliders in your scene. :)
     
  50. kenlem

    kenlem

    Joined:
    Oct 16, 2008
    Posts:
    1,630
    I don't have the source in front on me but I believe the GUIButtons can see the associated GUIManager. Look in the GUIObject source for something like getGUIManager or access to the variable.