Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Prime31 UIToolkit Multi Resolution GUI Solution Ready for Use...and it's free

Discussion in 'iOS and tvOS' started by prime31, May 3, 2011.

  1. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    Introducing UIToolkit for Unity available on Github

    (Intro tutorial available on YouTube here: http://youtu.be/WeV1zbMpm5k)

    We are proud to make available an amazing tool for creating HUD's, menus and animated sprites today! UIToolkit aims to make creating interactive menu systems and HUDs with a single draw call for multiple resolutions/devices dead simple. That's quite a mouthful and a tall order. The library comes with a bunch of different UI widgets out of the box and it makes creating your own widgets extremely simple. Mouse support is available while in the Unity editor for quick and easy testing along with a debug mode that displays the touchable rectangles in your scene live. Some conveniences for dealing with HD resolutions (iPhone 3 vs iPhone 4 for example) are optionally provided and include:

    • automatic texture swapping to a double resolution texture for HD
    • automatic reconfiguration of UV coordinates
    • automatic handling of double resolution UIFonts

    The kitchen sink and text test demo scenes included with the UIToolkit are an exceptional example of the power of the system. You can run these demo scenes on a non-retina iPhone, retina iPhone and an iPad and the exact same code will layout the controls and text in the same places. On top of that, the retina and iPad will receive textures that are twice the size automatically so they will remain pixel perfect and looking crisp!

    Built in UI Components

    UIToolkit provides all the standard controls you would expect and more. There is an exceptional attention to detail with regards to the way the controls feel when using them. For example, all touchable UI components can have highlightedTouchOffsets added. This mimics what Apple does with their iOS controls by adding a padding around the control that is activated while the control is being touched. If you set the highlightedTouchOffsets to have an extra 30 pixels and a user touches the button, they can slide their finger an extra 30 pixels outside the boundary of the button and it will remain highlighted. You can experience this by opening any Apple app on your iPhone with a button in it and touch your finger on it than slide it around off the button further and further until it is deselected. This behavior is available out of the box for any controls included with UIToolkit or any custom controls that you add. So what does UIToolkit include out of the box?

    • UISprite: the base of every component that can be seen. All UISprites can have animations added to them that can be played on demand.
    • UIButton: standard button with selected state, optional sound on touch down and delegate action on touchUpInside
    • UIContinousButton: UIButton that can either report every frame that a finger remains on it or when a finger touches down or up
    • UIToggleButton: 3 state button that can be used just like a checkbox if desired
    • UIProgressBar: standard progress bar that offers 2 modes of progression: texture stretching or just revealing the texture as progress advances
    • UISlider: slider that works in both the horizontal and vertical direction
    • UIKnob: rotating knob control
    • UIText and UITextInstance: reads in a .fnt file and displays text including line breaks (base code courtesy of EskemaGames)
    • UIJoystick: joystick control with configureable dead zone and background image
    • UISwipeDetector: control that is capable of detecting swipes in any combination of directions (up, down, left, right)

    Animations Baked in to Every Component

    Animate localScale, alpha, rotation and position with one line of code. You can animate to, from or from-to for any of the animation types and specify your easing style. You can even create your own easing equations if you so desire.


    Why are we releasing such an awesome product for free?

    Over the last couple years we have seen a lot of really fun games made with Unity thrive in the App Store. We have also seen a bunch that are solid games with less than optimal looking menus and HUDs made with the standard Unity GUI classes. Unity GUI works great on desktop but it does not perform optimally on mobile devices. Enter UIToolkit. If you look at some of the top games in the App Store there is one thing they all have in common: polish. Try playing around with the menus, pause screens and HUDs on some of the great Unity-made games out there like Gears and BattleHeart. They are smooth as silk and look great on retina, non-retina and the iPad. These are highly polished games that have a great feel from the moment you launch them all the way through to the end. UIToolkit helps reduce the man-hours to get this kind of polish and we want to see every Unity developer succeed so this release is us doing our part to help the community provide a better end product.

    Extending UIToolkit

    UIToolkit was designed from the start to be as easy as possible to extend. We want the community to make some really cool controls that can be shared. Creating a new control can be done easily by just extending the UITouchableSprite class and implement one or more of the touch-related methods: onTouchBegan, onTouchMoved, onTouchEnded. That's all it takes. If you make an awesome custom control feel free to send us a pull request on Github and we will include it for the rest of the community to use.

    So, Let's See Some Code

    UIToolkit has an easy to use workflow and API. Once you have your textures created (using the free version of the excellent Texture Packer) you can reference them by name. This is all it takes to make a button in the top-left corner of the screen that has an extra 30 pixel touch offset padding when highlighted:

    Code (csharp):
    1. var playButton = UIButton.create( "playUp.png", "playDown.png", 0, 0 );
    2. playButton.highlightedTouchOffsets = new UIEdgeOffsets( 30 );
    Pretty simple, right? You may notice that this doesn't do anything all that magical with regards to layout though, so let's see an example of creating a UIToggleButton with relative positioning (in the top-right corner) so that it works on all resolutions:

    Code (csharp):
    1. var x = (int)UIRelative.xPercentFrom( UIxAnchor.Right, .1f );
    2. var y = (int)UIRelative.yPercentFrom( UIyAnchor.Top, .1f );
    3. var toggleButton = UIToggleButton.create( "cbUnchecked.png", "cbChecked.png", "cbDown.png", x, y );
    Not all that much more difficult. Now go download it and add that extra polish to your game so that you end up with a hit! Get it now on Github!
     
    Last edited: May 7, 2011
    SanSolo likes this.
  2. defjr

    defjr

    Joined:
    Apr 27, 2009
    Posts:
    436
    Brilliant! Thanks for sharing this.
     
  3. Toad

    Toad

    Joined:
    Aug 14, 2010
    Posts:
    298
    This looks fantastic! Very generous of you to give it out for free. Thanks!! :)
     
  4. wesrm

    wesrm

    Joined:
    May 20, 2009
    Posts:
    193
    Awesome! Great work!!! Thanks very much for such a generous contribution to the unity3d community.

    -Wes
     
  5. Muckel

    Muckel

    Joined:
    Mar 26, 2009
    Posts:
    471
    Thank you very much !
     
  6. squidbot

    squidbot

    Joined:
    Jan 4, 2011
    Posts:
    128
    You freaking rock.
     
  7. mmuller

    mmuller

    Joined:
    Nov 23, 2010
    Posts:
    92
    Amazing!!

    Just starting my new project (which will also include your Adwhirl option on iOS) so this has come at a fantastic time :D

    Thank you so much for releasing a gem for free...
     
  8. Gigiwoo

    Gigiwoo

    Joined:
    Mar 16, 2011
    Posts:
    2,981
    Well, I like your products, so I'm really excited. Will try it out.

    Questions:

    * Layouts and Containers - I don't see any containers in there. Are you planning to add layout/container type controls? Ie, panels that hold other objects that can be adjusted/animated/moved/scaled by just affecting the parent? This type of thing is incredibly powerful when building little panels of buttons. They can all fly on at the same time.

    * Scroll Bars - Goes along with Containers.

    * More? Are you considering this done or are you planning to add to it?

    * Asset Store? Are you going to add this to the Unity Asset Store?

    Look forward to trying it out.
    Gigiwoo.
     
  9. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @Gigiwoo,

    * UIPanel is actually next on my list. It didn't quite make the initial release but being able to group buttons/widgets and move them around is incredibly handy. We wanted to get this out ASAP so the UIPanel got pushed out of the initial release.

    * Scroll bars are on the roadmap but a little ways out.

    * I don't think this will ever be done. We plan on using it in every game we make so it should see plenty of love in the future. We also are hoping to see some new UI controls coming from users out there. Which brings me to...

    * ...absolutely not going to be in the Asset Store. We want this to be a community project, not something the we alone support. It was made to be easily extensible and we would love to see what creative controls can come from other folks using the library.
     
  10. RobbieDingo

    RobbieDingo

    Joined:
    Jun 2, 2008
    Posts:
    484
    Brilliant! Thank you Mike.
     
  11. mindlube

    mindlube

    Joined:
    Oct 3, 2008
    Posts:
    993
    @MikeD thanks for this invaluable community resource!
     
  12. TaintedLemon

    TaintedLemon

    Joined:
    May 4, 2011
    Posts:
    16
    This definitely looks promising and making it free / community supported is amazing :D

    I've had a browse through the code and was wondering if there's a way to determine if a gui event has been fired. If I have a 3d scene and I'm going to fire a ray into it to perform some action, I only want to do this when the user hasn't clicked the user interface (To prevent both clicking the button and modifying the scene behind the button at the same time). Can this be done by simply testing if getButtonForScreenPosition() is null before firing the ray? or is there a more correct way of handling this situation?
     
  13. maxfax2009

    maxfax2009

    Joined:
    Feb 4, 2009
    Posts:
    410
    Awesome - What a Star Mike his :)
     
  14. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @Tainted, everything in the UIToolkit is run from an orthographic camera in 2d. You *could* pull that off with a little work but it isn't the focus of the toolkit.
     
  15. ant001

    ant001

    Joined:
    Dec 15, 2010
    Posts:
    116
    would be great to have 3d UI toolkit, thanks prime(31) really cool work as always.
     
  16. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @anti001, I know it isn't free, but Bradys EZGui works in 3D and is a fantastic product that you should definitely consider if you haven't already.
     
  17. giyomu

    giyomu

    Joined:
    Oct 6, 2008
    Posts:
    1,094
    Really nice , thanks for your share :)
     
  18. TaintedLemon

    TaintedLemon

    Joined:
    May 4, 2011
    Posts:
    16
    @Prime31

    Sorry I didn't explain myself very well. The 3D scene stuff is all my own code. Basically my code works like so

    Code (csharp):
    1. bool guiEventOccurred = HandleGUI();
    2. if( ! guiEventOccurred )
    3. {
    4.    //Perform my own code where I use the Input.touches[0].position to fire a ray in 3D and select an object.
    5.    //I don't want to select an object which is behind a button on the screen
    6. }
    Since my gui code is horrible, I'd love to change over to using this system. I'm just trying to figure out the kinks before I commit myself to performing all the code changes.
     
  19. minevr

    minevr

    Joined:
    Mar 4, 2008
    Posts:
    1,018
    floow mail...
     
  20. mindlube

    mindlube

    Joined:
    Oct 3, 2008
    Posts:
    993
    @TaintedLemon, same situation here- probably is a common use case. At first glance at the code, I think either what you suggested with getButtonForScreenPosition() or perhaps something using UISwipeDetector "Swipe detector view - big, giant touchbleSprite behind all others". Probably there are other possibilities.
     
  21. 3Duaun

    3Duaun

    Joined:
    Dec 29, 2009
    Posts:
    600
    simply awesome, very generous of you. I love my Prime31 plugins!
     
  22. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @TaintedLemon, that should work just fine. You can use the getButtonForScreenPosition() method and if it returns something other than null ignore the touch and don't shoot off your ray.
     
  23. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    Added a little note about the awesome animation system baked into UIToolkit to the main post...
     
  24. itech

    itech

    Joined:
    Jul 28, 2010
    Posts:
    139
    Thanks !
     
  25. Barbur

    Barbur

    Joined:
    Oct 30, 2009
    Posts:
    160
    I am starting to be a Prime31 fan! Thanks a lote Mike!
     
  26. smkamran

    smkamran

    Joined:
    Jun 21, 2010
    Posts:
    23
    Amazing product. I would love to use it in my projects.
     
  27. RolfBertram_dot_me

    RolfBertram_dot_me

    Joined:
    Mar 1, 2011
    Posts:
    128
    Not sure if this info makes sense here regarding implementing it in this GUI system, but I found a tutorial on how to apply a text to a texture of any 3D shape, in this example a mug. I wonder if this makes sense to use for showing score on a game object, since there is mention of some slowness of this method in the tutorial. If someone knows more about the possible slowness issue, and the usefulness of this method for frequently updated text, like a score, on a 3D surface, please comment.

    http://blog.almostlogical.com/2010/08/20/adding-text-to-texture-at-runtime-in-unity3d-without-using-render-texture/
     
  28. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    Looks awesome.

    Small question, in this code example:
    Code (csharp):
    1. var playButton = UIButton.create( "playUp.png", "playDown.png", 0, 0 );
    2. playButton.highlightedTouchOffsets = new UIEdgeOffsets( 30 );
    Could the images also be referenced with an index, to avoid string creation (GC) and string lookups?
     
  29. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @smag, you could assign the uvRect directly. Most controls have "raw" constructors that don't take in any strings. we purposely went with the string route though in order to keep the code readable, work across SD/HD and most importantly so the texture atlases can be totally rebuilt/modified at any time and still work with the same code. Those pesky tradeoffs...
     
  30. Mousey

    Mousey

    Joined:
    Oct 29, 2008
    Posts:
    16
    This looks great - many thanks Prime31!

    Not to go too off topic (maybe someone can point me to a seperate thread), but what's the problem with string creation / lookups, as mentioned by Smag?
     
  31. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    I see the benefits of that, but if each image would get a number in the atlas, you could keep those benefits (except readability, but that can be solved by the user if they use enums). However, this would only work well if the TexturePacker keeps the order of the images in it's exported files consitant.

    Well, strings will increase the garbage that the garbage collector has to collect. So the more strings you use, the quicker the GC has to kick in, which can cause small hitches.

    In this case however, most of these things will be setup at the start of your scene so it shouldn't be that big a deal.
     
  32. Mousey

    Mousey

    Joined:
    Oct 29, 2008
    Posts:
    16
    Thanks Smag. :)
     
  33. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    TexturePacker will reconfigure the order depending on the new sprites added to best fit the setup. Believe me, I tried every way possible to go without string creation and the cost of making a few strings at startup outweighed every other option. They all required some post or pre processing which just isn't worth the extra work. Letting the GC do it's job and collect some strings at startup and keeping a nice, simple workflow far outweighed the alternatives.
     
  34. Gigiwoo

    Gigiwoo

    Joined:
    Mar 16, 2011
    Posts:
    2,981
    Fantastic! Brilliant idea!

    I've co-run an open source project for many years now (www.delta3d.org), so I've been where you're about to go. It is a really enjoyable process - one that can lead to many opportunities, is personally satisfying, and is at the same time very challenging. One of the neatest thing about a project like that is when you start getting user submissions and even better, major adopters/users/partners.

    I haven't used GIT yet, but I guess now is as good a time as any to learn it :).

    Gigiwoo
     
  35. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @Gigiwoo, sounds like you have some work to do. Here is your todo list:

    1. grab yourself a copy of Gitbox (free) or Tower (paid but really nice)
    2. make the container objects you were asking about previously
    3. send over a pull request
     
  36. jjobby

    jjobby

    Joined:
    Nov 28, 2009
    Posts:
    160
    I'm currently experimenting about GUI solution for mobile development. You've come at the right time.

    Thank you very very much for this awesome release!!!
     
  37. EskemaGames

    EskemaGames

    Joined:
    Jun 23, 2010
    Posts:
    319
    This prime guy is the number one, once again a really complete solution and this time for free :)
     
  38. afalk

    afalk

    Joined:
    Jun 21, 2010
    Posts:
    164
    Looks like an outstanding start Prime! Downloaded the files this morning and looking forward to experimenting with your system and to the Container addition you're working on!

    Thanks again!

    AF
     
  39. mindlube

    mindlube

    Joined:
    Oct 3, 2008
    Posts:
    993
    This is a nice feature - to be able to embed font bitmaps in a texture atlas! very cool
     
  40. leonardoaraujo

    leonardoaraujo

    Joined:
    Jun 3, 2010
    Posts:
    87
    Very nice work! One question guys does this GUI system works on Android (I did not tested on Iphone yet)
     
  41. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @leonardoaraujo, the next push will have Android support. Due to the way Android handles StreamingAssets (poorly) we may have to just make a quick switch to using TextAssets instead so that Android works out of the box. Technically, then entire UIToolkit works fine on Android except for that one small thing: reading the StreamingAssets files.
     
  42. leonardoaraujo

    leonardoaraujo

    Joined:
    Jun 3, 2010
    Posts:
    87
    Thanks Prime31 for the great tool I will wait for the next version with android support
     
  43. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @leonardoaraujo.santos, looks like you have no more excuses to not use UIToolkit :) Android support was just pushed to the Github repo.

    A new experimental branch is also out in the wild that replaces the single mesh with quads for each UI element. At this point, I'm not sure what will be used going forward but it doesn't matter so much because the API will be identical.

    Quick note for anyone out there using UIToolkit: you have to rename the .json config files and .fnt files to .txt (and move them to a Resources folder) now due to Android not having a smooth StreamingAssets solution. Check the README for details.
     
  44. Sam at FPS

    Sam at FPS

    Joined:
    Sep 1, 2009
    Posts:
    80
    First off UIToolkit is awesome. Great work Prime31.

    Quick question about making sliders hidden. When I set my slider to hidden it doesn't seem to make the slider knob hidden as well. You can test this in the kitchen sink demo by making the slider hidden immediately after creating it in Start. (Using myslider.hidden = true)

    Am I missing something here? Is there a different way to hide things if they are composed of more than one Sprite? As a quick test I just added a method to UISlider that hides itself and its knob and it all seems to work.

    On a related note, should we be wary of creating UI objects and using them straight away? I seem to recall in GUISpriteUI that some UI classes were temperamental if you did stuff to them striaght away. i.e. hiding them, setting values. Basically, once a UISprite object is created is it all good to go or is there some setup still to happen?
     
  45. TaintedLemon

    TaintedLemon

    Joined:
    May 4, 2011
    Posts:
    16
    @Sam, what you need to do is make the hidden attribute virtual in UISprite, then in UISlider add the following:

    Code (csharp):
    1. public override bool hidden
    2.     {
    3.         get { return ___hidden; }
    4.         set
    5.         {
    6.             // No need to do anything if we're already in this state:
    7.             if( value == ___hidden )
    8.                 return;
    9.  
    10.             if( value )
    11.         {
    12.                     manager.hideSprite( this );
    13.             manager.hideSprite( _sliderKnob );
    14.         }
    15.             else
    16.         {
    17.                     manager.showSprite( this );
    18.             manager.showSprite( _sliderKnob );
    19.         }
    20.         }
    21.     }
     
  46. Sam at FPS

    Sam at FPS

    Joined:
    Sep 1, 2009
    Posts:
    80
    @TaintedLemon Thanks for the code. That's what I was thinking about doing, but just wasn't sure if there was perhaps some other, in built, way to do it. Like a static or helper method somewhere that I was missing.

    When I've finished the insane amount of work I've got on at the moment, I might have to try and get git access from @prime31 and jump on the improvements bandwagon. Adding an Allignment option to UIProgressBar would be a good place to start maybe.
     
  47. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @Sam and @Tainted, I just pushed a fix for this that pretty much does what TaintedLemon mentioned. I also wired it up in the kitchenSink demo scene to the toggle button for demonstration purposes.
     
  48. shabazzster

    shabazzster

    Joined:
    Mar 17, 2010
    Posts:
    104
    can you deliver as a .unity package please?
     
  49. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @shabazzster, there is a unitypackage available in the downloads on Github

    The latest push also received much cleaner relative positioning support. See the kitchen sink demo for example code.
     
  50. mehware

    mehware

    Joined:
    Nov 19, 2007
    Posts:
    739
    Can I use this for windows and os x too? Keep it up Prime31 :D