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

    EskemaGames

    Joined:
    Jun 23, 2010
    Posts:
    319
    Maybe I'm missing something but I cannot find anything wrong in the code. All the fonts are supposed to be rendered from 0,0 wich is topleft right?

    So a font in drawtext(0, 50) should be just in 0 position, but I've got the position moved around 20 pixels, so to draw something at 0,50 I must draw it at (-20,50)

    Am I missing something here?
     
  2. numeric

    numeric

    Joined:
    Jan 31, 2010
    Posts:
    170
    Is there a way to find out from code which atlas ( standard/retina) is being used?
     
  3. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @Apple, UI.instance.isHD will let you know

    @Eskema, can you post a screenshot and your code?
     
  4. EskemaGames

    EskemaGames

    Joined:
    Jun 23, 2010
    Posts:
    319
    Forget it, I just rebooted my imac and everything works as expected ¿¿??
     
  5. coder3d

    coder3d

    Joined:
    May 19, 2011
    Posts:
    5
    Why does UIToolKit use its own mesh batching implementation? Isn't it faster to use unity's built-in draw call batching as it is implemented in C++ with knowledge of unity internals?

    SM1 is also managed in a c# component, but SM2 uses unity's automatic batching.
     
    Last edited: May 24, 2011
  6. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @coder3d, there is a branch in the Github repo that uses Unity's batching. Feel free to grab it and give it a shot. (Many thanks to @QuickFingers performance tests) It was found that a single mesh was a LOT faster. FPS and frame time were drastically reduced by using a single mesh. It wasn't even comparable and as the sprite count increased the difference in speed was even greater.
     
  7. jjobby

    jjobby

    Joined:
    Nov 28, 2009
    Posts:
    160
    Why don't you update it in main branch? Is there any problem?
     
  8. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @jjobby, that branch was experimental and as mentioned in the previous message it was far less performant so it got tossed away for the current setup which is much faster.
     
  9. jjobby

    jjobby

    Joined:
    Nov 28, 2009
    Posts:
    160
    Oh, sorry. I misinterpret it. *_*
     
  10. ChrisE

    ChrisE

    Joined:
    Nov 19, 2010
    Posts:
    14
    I was looking at the license. You could not use (unmodified) UIToolKit to create the GUI for a game starter kit sold in the asset store, correct?
     
  11. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @ChrisE, we haven't gotten the license up just yet but one stipulation that will definitely be in it is that it cannot be resold in any way. We really want this to be a community driven project that no one ever has to pay for. Since the advent of the Asset Store everyone wants to sell everything and there isn't the sharing going on that used to. UIToolkit is here to bring back the sharing spirit.
     
  12. Matkins

    Matkins

    Joined:
    Aug 24, 2009
    Posts:
    152
    I'm getting the following exception appear repeatedly when i'm running the game on device:

    Code (csharp):
    1. IndexOutOfRangeException: Array index is out of range.
    2.   at UIToolkit.lookAtTouch (Touch touch) [0x0007e] in /Users/mattatkins/Documents/Live jobs/PL300653 - Catch the Soap/unity/Bubbimals/Assets/Plugins/UIToolkit/UIToolkit.cs:193
    3.   at UIToolkit.Update () [0x00012] in /Users/mattatkins/Documents/Live jobs/PL300653 - Catch the Soap/unity/Bubbimals/Assets/Plugins/UIToolkit/UIToolkit.cs:48
    It doesn't always happen, but occasionally when i'm spamming the screen with my fingers (it's the nature of the game) I notice a load of these errors.

    I've only actually got a single UISprite in use at the time, nothing touchable.

    Any ideas?
     
  13. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @Matkins, the base code is locked at 5 touches. You can increase that in the UIToolkit.cs file and the UISwipeRecognizer.cs file if you are using it.
     
  14. coder3d

    coder3d

    Joined:
    May 19, 2011
    Posts:
    5
    Currently if you get a UISprite's position.y directly the value is negative.
    Would't it be better to use a BottomY=0 and topY=height coordinate instead, like in cocos2d?
     
  15. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @coder3d, you could easily add an Extension class that lets you mimic cocos2d's API. Extension methods are awesome for getting things to work they way you like. See the positioning and animation extension classes in UIToolkit if you don't know how to construct them.
     
  16. coder3d

    coder3d

    Joined:
    May 19, 2011
    Posts:
    5
    To use an external class only to change the position of a sprite is a little overkill. Soon it will be like to use J2EE :)

    I could subclass or change the method directly. My suggestion was only that maybe that should be the default behavior as a negative value isn't much intuitive. Negative values should only appear in out of screen elements.
     
  17. coder3d

    coder3d

    Joined:
    May 19, 2011
    Posts:
    5
    Well, thinking about it, actually that is what we do with a Transform component, but it doees more than simply change the positioning coordinate and at least is is integrated in the GameObject class by default. Anyway, sprite positioning should not need something so fancy.
     
    Last edited: May 25, 2011
  18. coder3d

    coder3d

    Joined:
    May 19, 2011
    Posts:
    5
    The fundamental problem is this.

    y = 50;
    UISprite s = UI.firstToolkit.addSprite("sprite.png", 100, y);
    s.position.y != y

    this is a bug in my view.
    You could use Flash's coordinates with top=0, bottom=height, but that would be less intuitive than cocos2d's because you would need to decrease Y to go up.
     
  19. Matkins

    Matkins

    Joined:
    Aug 24, 2009
    Posts:
    152
    How come LookAtTouch() is being called when i've got no TouchableSprites in existence? Is there any reason?
     
  20. bjohnson8704

    bjohnson8704

    Joined:
    Jan 30, 2011
    Posts:
    54
    @Prime, I haven't gotten to finish the pause code test yet as I've had to implement some things in my game before I can get to it. I've come across another little problem that's probably just me not knowing how to do something properly. Basically my problem is that I'm trying to start new animations using:
    Code (csharp):
    1.  
    2. currentButtonAni = UIObjectAnimationExtensions.scaleTo(currentButton, .1, Vector3(.6,.6,.6), Easing.Circular.easeInOut);
    3. currentButtonAni.autoreverse = true;
    4. currentButtonAni.onComplete = function(){new animations...};
    5.  
    That of course works fine the first time, but if I try to execute the function that the code is contained in again, it goes straight to the new animations before finishing the currentButtonAni and then restarts the new animations again once currentButtonAni.autoreverse is complete. I assumed that it is because currentButtonAni.onComplete never gets reset, but that's just a guess. My thought was to try and reset currentButtonAni.onComplete to null after the onComplete function is complete, but nothing I've tried has seemed to work. So now I'm assuming that I'm just on the wrong track altogether. I'm sure this is one of those things that is going to be so obvious once it's put in front of my face, but right now I'm just perplexed. Any help would be greatly appreciated. Thanks
     
  21. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @Matkins, lookAtTouch is called for all touches. It will eventually shortcut out when it goes looking for a touchablSprite and can't find one.

    @bjohnson, I'm not sure what is going on there. Could be a bug but I'm out of town so can't check. Out of curiosity, have you tried a fromTo animation for that one?
     
    Last edited: May 26, 2011
  22. Patyrn

    Patyrn

    Joined:
    Feb 17, 2011
    Posts:
    57
    Does this have drag drop support?
     
  23. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @Patyrn, there is no specific drag drop support but extending the UIToolkit objects to have it would be relatively easy.
     
  24. Patyrn

    Patyrn

    Joined:
    Feb 17, 2011
    Posts:
    57
    Cool. Hopefully someone does that. I'm not nearly good enough at C# to attempt it.
     
    Last edited: May 27, 2011
  25. bjohnson8704

    bjohnson8704

    Joined:
    Jan 30, 2011
    Posts:
    54
    @Prime, yeah, I've tried the fromto also. Also tried it without autoreverse and still the same results. After messing around with the UIAnimation script for a little bit, I found that if I comment out "sameAnimationType.stop();" "_spriteAnimations[sprite].Remove( sameAnimationType );" in the following code, the animations will play properly(for a number of times before it the player starts slowing down to a crawl...which I assume is the reason why that portion of code is there in the first place).

    Code (csharp):
    1. // check for any previously running animations of this type.  we dont want them fighting
    2.         if( _spriteAnimations.ContainsKey( sprite ) )
    3.         {
    4.             var sameAnimationType = _spriteAnimations[sprite].Where( i => i.aniProperty == aniProperty ).FirstOrDefault();
    5.             if( sameAnimationType != null )
    6.             {
    7.                 sameAnimationType.stop();
    8.                 _spriteAnimations[sprite].Remove( sameAnimationType );
    9.             }
    10.         }
    While I have no idea if the problem is in that code, that's by far the closest I've come to figuring it out.
     
  26. Patyrn

    Patyrn

    Joined:
    Feb 17, 2011
    Posts:
    57
    Hmmm. My button is registering clicks in the right place, but is displaying like 20x normal size and in completely the wrong part of the screen. Not sure what's wrong.

    Edit: Oh, gotta change the layer on the child GO to your UI layer too. Whoops.
     
  27. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @bjohnson, can you post the source (and any relevant surrounding code) for both animations?
     
  28. bjohnson8704

    bjohnson8704

    Joined:
    Jan 30, 2011
    Posts:
    54
    Here's the code for one. "moveGuiIn" moves my in game gui items back on to the screen after game is unpaused.
    Code (csharp):
    1.  
    2. if(!continueButton){
    3.     continueButton = UIButton.create(UI.firstToolkit, "pause_menu_continue.png","pause_menu_continue.png", 160, 1000, 3);
    4.     continueButton.centerize();
    5.     }
    6.     continueButtonAni = UIObjectAnimationExtensions.positionFromTo(continueButton, .5, new Vector3(Screen.width/4,500,1), new Vector3(Screen.width/4,-125,1), Easing.Circular.easeIn);
    7.     continueButtonAni.onComplete = function(){
    8.     UI.instance.playSound(droppingSound);
    9. };
    10.  
    11. continueButton.onTouchUpInside += function(){
    12.    continueButtonAni = UIObjectAnimationExtensions.scaleTo(continueButton, .1, Vector3(.6,.6,.6), Easing.Circular.easeInOut);
    13.    continueButtonAni.autoreverse = true;
    14.    continueButtonAni.onComplete = function(){
    15.     UIObjectAnimationExtensions.positionFromTo(pauseTitle, .5, new Vector3(Screen.width/2, 0 - 30, 0), new Vector3(Screen.width/2, 0 + 500, 0), Easing.Circular.easeIn);
    16.     UIObjectAnimationExtensions.positionFromTo(continueButton, .5, new Vector3(Screen.width/4,-125,1), new Vector3(Screen.width/4 - 1000,-125,1), Easing.Circular.easeIn); 
    17.     UIObjectAnimationExtensions.positionFromTo(restartButton, .5, new Vector3(Screen.width/4 * 2.5,-125,1), new Vector3(Screen.width/4 * 2.5 - 1000,-125,1), Easing.Circular.easeIn);
    18.     UIObjectAnimationExtensions.positionFromTo(optionsButton, .5, new Vector3(Screen.width/4 * 1.75,-225,1), new Vector3(Screen.width/4 * 1.75 - 1000,-225,1), Easing.Circular.easeIn);
    19.     UIObjectAnimationExtensions.positionFromTo(mainButton, .5, new Vector3(Screen.width/4 * 3.25,-225,1), new Vector3(Screen.width/4 * 3.25 - 1000,-225,1), Easing.Circular.easeIn);
    20.     UIObjectAnimationExtensions.alphaFromTo(tint, .5, .6 , 0, Easing.Circular.easeIn);
    21.     moveGuiIn();
    22.    };
    23. };
     
  29. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @bjohnson, I don't see any glaring issues though I do have a suggestion that could possibly make your menu a bit simpler (if I am understanding what it does). I am assuming that you have 5 buttons that slide in when pausing. Let me know if I am incorrect in which case what I am about to say disregard. Stick all 5 buttons in a UIHorizontalLayout then you can just animate the container in/out. One of the demo scenes has a very similar example.

    I am going to try to reproduce what you are getting now.
     
  30. bjohnson8704

    bjohnson8704

    Joined:
    Jan 30, 2011
    Posts:
    54
    @Prime, thanks for the suggestion. While they do slide out at the same time, the buttons drop in and bounce separately. I guess that means I could place them into a UIHorziontalLayout container after they have finished with their separate entrances though and that would probably help out at least a little.
     
  31. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @bjohnson, here is a simplified version of what I believe you are shooting for. Just use the demo scene and change the KitchenSinkManager.cs file to be the following:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4.  
    5. public class KitchenSinkManager : MonoBehaviour
    6. {
    7.     public AudioClip scoresSound;
    8.     public AudioClip optionsSound;
    9.    
    10.     private UIButton continueButton;
    11.     private UIButton pauseTitle;
    12.     private UIButton restartButton;
    13.  
    14.    
    15.     void moveIn()
    16.     {
    17.         restartButton.positionTo( .5f, new Vector3( 0, -125, 0 ), Easing.Circular.easeIn );
    18.         pauseTitle.positionTo( .5f, new Vector3( 0, -250, 0 ), Easing.Circular.easeIn );
    19.         continueButton.hidden = false;
    20.     }
    21.    
    22.  
    23.     void Start()
    24.     {
    25.         restartButton = UIButton.create( "optionsUp.png", "optionsUp.png", -400, 125 );
    26.         pauseTitle = UIButton.create( "scoresUp.png", "scoresUp.png", -400, 250 );
    27.        
    28.         continueButton = UIButton.create( "playUp.png", "playUp.png", 300, 125 );
    29.         continueButton.centerize();
    30.         continueButton.hidden = true;
    31.        
    32.         continueButton.onTouchUpInside += ( button ) =>
    33.         {
    34.             var continueButtonAni = continueButton.scaleTo( .1f, new Vector3( .6f, .6f, .6f ), Easing.Circular.easeInOut );
    35.             continueButtonAni.autoreverse = true;
    36.             continueButtonAni.onComplete = () =>
    37.             {
    38.                 // slide buttons out
    39.                 restartButton.positionTo( .5f, new Vector3( -400, -125, 0 ), Easing.Circular.easeIn );
    40.                 pauseTitle.positionTo( .5f, new Vector3( -400, -250, 0 ), Easing.Circular.easeIn );
    41.                 continueButton.hidden = true;
    42.            };
    43.         };
    44.     }
    45.    
    46.    
    47.     void OnGUI()
    48.     {
    49.         if( GUI.Button( new Rect( Screen.width - 150, 0, 150, 40 ), "Pause" ) )
    50.         {
    51.             moveIn();
    52.         }
    53.     }
    54. }
    55.  
     
  32. bjohnson8704

    bjohnson8704

    Joined:
    Jan 30, 2011
    Posts:
    54
    @Prime, I believe you just solved my problem. I had all that continue button code placed in a function that was getting called every time the game was paused and I'm guessing that that must be a big no no. I just switched my code to the start function and it seems to be working like a charm just as the example you posted did. Can you confirm that having that code(i'm assuming it's the onComplete portion) in a function that gets called numerous times would be the problem? I guess I don't really need a definite answer as that seems to be, but it's nice to hear advice from someone who knows what they're doing. :p Anyways, thanks again! Hopefully this will let me push forward...and allow me to get that pause code fully tested.
     
  33. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @bjohnson, if that was getting called multiple times it definitely would be an issue. A new OnComplete handler would get added each time it is called causing all kinds of fun stuff to happen. After enough times so many animations would be called at the same time I'm surprised it just didnt lock up altogether. Each time there is a += a brand new event handler is added and the old one still exists.
     
  34. Patyrn

    Patyrn

    Joined:
    Feb 17, 2011
    Posts:
    57
    Do you have any idea why TexturePacker is sometimes turning my textures red?
     
  35. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @Patyrn, if you are using the free version, you cannot use certain tools like scaling, exporting to pvr, etc. If you export at 100% scale and to a png you should be fine.
     
  36. bjohnson8704

    bjohnson8704

    Joined:
    Jan 30, 2011
    Posts:
    54
    @Prime, thanks! That definitely was my problem then. Excellent lesson for me as I really had no idea what that did(or that it was even an event handler)...guess that shows how (un)advanced my programming is. :p Well, I think that's one of the biggest things I've learned in quite a while, so if I'm learning I guess that means I'm on the right track. :) Really, thanks again! It's beyond awesome how helpful you've been.
     
  37. Patyrn

    Patyrn

    Joined:
    Feb 17, 2011
    Posts:
    57
    Does positionFromTopRight work on UIVerticalLayout? It's not throwing an error or anything, but it doesn't seem to do anything either.
     
    Last edited: May 27, 2011
  38. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @Patyrn, positionFromXX will work fine with UIVerticalLayout. Just be sure that all your children are added first so that it has a proper width/height to work with.
     
  39. Patyrn

    Patyrn

    Joined:
    Feb 17, 2011
    Posts:
    57
    Cool, worked.
     
  40. Patyrn

    Patyrn

    Joined:
    Feb 17, 2011
    Posts:
    57
    When creating multiple sprite sheets, do you add all the scripts to the same child game object, or give each their own game object?
     
  41. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @Patyrn, check the demo scene called multiple atlas demo. You will have one root GameObject with the UI script then one child on that GO for each atlas that has the UIToolkit script on it.
     
  42. Patyrn

    Patyrn

    Joined:
    Feb 17, 2011
    Posts:
    57
    I'm finding how the text works fairly confusing. Browsing the example project you suggest I find you create your UIText with "prototype" and "prototype.png", yet the atlas name is "textDemoSheet". textDemoSheet appears to point at prototype.png, but there is no prototype.png in the resources folder. Could you enlighten me a little bit on what's going on here. :)

    PS: Sorry for all the questions.
     
  43. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @Patyrn, the readme file on Githib has a walkthrough for setting up text. Basically, you export from the program of your choosing a .png and a .fnt file. Rename the .fnt to .txt and dump it in the resources folder then add the exported .png to your normal atlas.
     
  44. Patyrn

    Patyrn

    Joined:
    Feb 17, 2011
    Posts:
    57
    Do you mean this readme:

    This doesn't say anything about which files to reference where, and what they have to be named. For example:

    Code (csharp):
    1. var text = new UIText( "prototype", "prototype.png" );
    Is the first value the path + filename to the .fnt file (renamed .txt?).
    Is the second value the path + filename to the exported bitmap font png, or the sprite sheet png?

    I'm setting it up with my best guess, and getting this error:

    Exception: can't find texture details for texture packer sprite:Textures/UI/Text/geo.png
    UISpriteManager.frameForFilename (System.String filename) (at Assets/Plugins/UIToolkit/BaseElements/UISpriteManager.cs:171)
    UIText..ctor (.UIToolkit manager, System.String fontFilename, System.String textureFilename) (at Assets/Plugins/UIToolkit/UIElements/UIText.cs:118)
    UIText..ctor (System.String fontFilename, System.String textureFilename)
    BuildShips.Start () (at Assets/Scripts/UI/BuildShips.cs:14)
     
  45. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @Patyrn, no paths are required. Everything is loaded using the standard Resources.Load. Use the sample scene as a template for how to do things.
     
  46. Patyrn

    Patyrn

    Joined:
    Feb 17, 2011
    Posts:
    57
    Ok I got it to load without an error, but it's using my buttons sprite sheet instead of my text sprite sheet. I've tripple checked that I'm passing it the right one as the first parameter when creating my UItext.
     
    Last edited: May 31, 2011
  47. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    The first parameter to UIText is not an atlas. It is the image exported from the font generator program which should be added to your actual sprite atlas.
     
  48. Patyrn

    Patyrn

    Joined:
    Feb 17, 2011
    Posts:
    57
    I'm using this constructor:

    public UIText( UIToolkit manager, string fontFilename, string textureFilename )

    First param is the UIToolkit (I'm using multiple atlases).

    My second parameter is the name of the .fnt file (renamed to .txt), and my third parameter is the name of the png that my bitmap font generator exported. It's still showing random slices of an atlas I didn't even pass it. :(

    Edit: Some more info. If I delete the other atlas so I have ONLY the text atlas, it works. I'm not sure that the UIText class is respecting the atlas parameter, though I can't see anything obviously wrong with it.
     
    Last edited: May 31, 2011
  49. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @Patyrn, do you have a simplified sample project you can export and send my way so I can give it a look?
     
  50. Patyrn

    Patyrn

    Joined:
    Feb 17, 2011
    Posts:
    57