Search Unity

Joysticks and screen resolutions

Discussion in 'Android' started by gunga, Apr 7, 2012.

  1. gunga

    gunga

    Joined:
    Jan 2, 2012
    Posts:
    170
    Just wondering what peoples workflows are here as i'm tearing my hair out trying to find a solution.

    I've tried the penelope joystick (converted to c#) but it moves position and scale depending on the screen size.

    I've tried the UIJoystick from UIToolkit but that has bugs in it preventing propper positioning of the touch rect. :-|

    Am i supposed to scale the joystick to fit the smallest resolution and then have a small joystick for the higher resolutions?

    Any 3rd party joystick that are any good?

    Any help would be appreciated as i'm wanting to take the right direction as i've wasted a lot of time on this already.

    Thanks
     
  2. Tjitse

    Tjitse

    Joined:
    Apr 9, 2012
    Posts:
    10
    I would also be interested in how other people are going about the different screen resolutions. The way I'm going about it at the moment is to try and keep the ratio no matter the screen resolution. But that is entirely dependent on what you are trying to achieve. I downloaded the UIToolkit yesterday to see if it would work and found that same problem as you are describing. At least I think it is the same issue. In any case, I believe I figured out the issues I was having with the UIJoystiq. If you still were looking at going that direction I'll post up here the code I changed.

    In any event those are just my thoughts. Perhaps other, more experienced people would be willing to share how they go about the screen resolution.
     
    Last edited: Apr 10, 2012
  3. gunga

    gunga

    Joined:
    Jan 2, 2012
    Posts:
    170
    Yes please, at the moment i'm using UIJoystick but the rectangles are each taking up half the screen, which isn't ideal but it's working.
     
  4. Tjitse

    Tjitse

    Joined:
    Apr 9, 2012
    Posts:
    10
    I had noticed some issues with the positioning of the joystick so I replaced this corresponding code with what was originally in the layoutJoystick function.
    Code (csharp):
    1.  
    2.         //adjust the touches with the scale
    3.         float X = localTouchPosition.x;
    4.         float Y = -localTouchPosition.y;
    5.        
    6.         //fixed to adjust the touches to the scale of the image
    7.         newPosition.x = Mathf.Clamp(X, _joystickBoundary.minX, _joystickBoundary.maxX );
    8.         newPosition.y = Mathf.Clamp( Y, _joystickBoundary.minY, _joystickBoundary.maxY );
    As for the joysticks taking up most of the screen, if by that you mean the images of the joysticks themselves, then you would need to scale the joystick Sprites. You would just need to change the joystick's local scale.
    Code (csharp):
    1.  
    2.         joystick.localScale = new Vector3(scale, scale);

    I changed the original static UIJoystick create functions to make this easier to comprehend for me.

    Code (csharp):
    1.  
    2.     public static UIJoystick create( string joystickFilename, Rect hitAreaFrame, float scale)
    3.     {
    4.         return create( UI.firstToolkit, joystickFilename, hitAreaFrame, scale, (hitAreaFrame.width / 2), -(hitAreaFrame.height / 2) );
    5.     }
    6.    
    7.     public static UIJoystick create( string joystickFilename, Rect hitAreaFrame, float scale, float xPos, float yPos )
    8.     {
    9.         return create( UI.firstToolkit, joystickFilename, hitAreaFrame, scale, xPos, yPos );
    10.     }
    11.  
    12.     public static UIJoystick create( UIToolkit manager, string joystickFilename, Rect hitAreaFrame, float scale, float xPos, float yPos )
    13.     {
    14.         // create the joystrick sprite
    15.         var joystick = manager.addSprite( joystickFilename, 0, 0, 1, true );
    16.         joystick.localScale = new Vector3(scale, scale);
    17.        
    18.         return new UIJoystick( manager, hitAreaFrame, 1, joystick, xPos, yPos );
    19.     }
    On the other hand, if you meant by half of the screen the touch rectangle, then the above code will also account for that. You would define the size of the touch rectangle in the hitAreaFrame.

    I hope this helps and was what you were expecting!
     
  5. gunga

    gunga

    Joined:
    Jan 2, 2012
    Posts:
    170
    Cheers for that, i'll test it tomorrow.

    Yes i meant the touch rectangle is half my screen for each joystick, so if i try and touch any other HUD buttons they work but the joystick also gets activated.
     
  6. gunga

    gunga

    Joined:
    Jan 2, 2012
    Posts:
    170
    Are you editing the UIJoystick.cs file here?
     
  7. Tjitse

    Tjitse

    Joined:
    Apr 9, 2012
    Posts:
    10
    Yes all of the code posted was in the UIJoystick.cs file.

    If you wanted to try and change the size of the joystick touch rectangle independently from my code (i.e. in the original), you would need to change the part where you create a joystick; change the width to something other than Screen.width/2 in
    Code (csharp):
    1. new Rect( 0, Screen.height / 2, Screen.width / 2, 200 )
    in the declaration of the joystick
    Code (csharp):
    1.  
    2.         leftJoystick = UIJoystick.create( "joystickUp.png", new Rect( 0, Screen.height / 2, Screen.width / 2, 200 ), Screen.width / 4, -150 / 2 );
    3.  
    I had only changed those static create functions in the UIJoystick in order to simplify the position of the joystick sprite and to implement the scaling of the sprite.
     
  8. gunga

    gunga

    Joined:
    Jan 2, 2012
    Posts:
    170
    Sounds good. Thanks :)
     
  9. gunga

    gunga

    Joined:
    Jan 2, 2012
    Posts:
    170
    I've changed the code in the UIJoystick.cs to your code, but now i'm getting an error:

    Not sure what do change now:

    Code (csharp):
    1. joystick = UIJoystick.create("joystick_thumb.png", touchRect, joystickPosition.x, joystickPosition.y);
    Any suggestions?

    Thanks
     
  10. Tjitse

    Tjitse

    Joined:
    Apr 9, 2012
    Posts:
    10
    Yeah, probably should have clarified, but if you are using my create functions you would either need to declare your create function like this where scale is a float (if doing it this way you will not need to define the joystick sprite position; it will always be centered in the middle of the touch rectangle.)
    Code (csharp):
    1.  
    2.         leftJoystick = UIJoystick.create( "joystick_thumb.png", touchRect, scale);
    If you wanted to specify the sprite position like with what you were already doing you would just add your scale value for the sprite.
    Code (csharp):
    1. joystick = UIJoystick.create("joystick_thumb.png", touchRect, scale, joystickPosition.x, joystickPosition.y);
     
  11. gunga

    gunga

    Joined:
    Jan 2, 2012
    Posts:
    170
    Thanks. This may seem a silly question, but is there a way to make the rect stay on the edge of the screen even when the screen resolution is changed?
     
    Last edited: Apr 11, 2012
  12. Tjitse

    Tjitse

    Joined:
    Apr 9, 2012
    Posts:
    10
    I've been having problems figuring out how to handle multiple resolutions myself so I may not be the biggest help. However if I'm understanding you correctly, if you want it to stay on the left side of the screen you would just define your touchRect at 0 for the left pos.
    Code (csharp):
    1. touchRect = new Rect(0, topPos, rectWidth, rectHeight);
    If you wanted it on the right just do
    Code (csharp):
    1. touchRect = new Rect(Screen.width - rectWidth, topPos, rectWidth, rectHeight);
    I haven't exactly tested it myself but I do believe that should work.
     
  13. Tjitse

    Tjitse

    Joined:
    Apr 9, 2012
    Posts:
    10
    If you are changing the resolution of the game window after you started it, the UI will not change accordingly. You would need to restart the preview to try and see it on a different resolution. Don't know if this is actually the problem but I'm just taking a stab in the dark.
     
  14. gunga

    gunga

    Joined:
    Jan 2, 2012
    Posts:
    170
    Thanks, i'll give that a go. :)
     
  15. gunga

    gunga

    Joined:
    Jan 2, 2012
    Posts:
    170
    Thanks that worked. Just need to make the touch rect be a percentage of the screen and it'll work for all sizes. :)
     
  16. Tjitse

    Tjitse

    Joined:
    Apr 9, 2012
    Posts:
    10
    I'm glad you got it working.
     
  17. gunga

    gunga

    Joined:
    Jan 2, 2012
    Posts:
    170
    Works great. Thanks alot. you should submit your changes to UIToolkit Github. :)
     
  18. gunga

    gunga

    Joined:
    Jan 2, 2012
    Posts:
    170
    Hi again,

    Is there any way to make the touch rect the size of the joystick background graphic automatically?

    It's all working great apart from that. At the smallest iphone res all the graphics including the joysticks are the SD versions, the touch rects stay the same size as the high resolution versions and are way too big. The joysticks centre in the touch rectangle and end up somewhere near the middle.

    I tried resizing the rect for the small display but then when played on ipad res the touch rect is far too small.
     
  19. Tjitse

    Tjitse

    Joined:
    Apr 9, 2012
    Posts:
    10
    So let me lead with saying I don't exactly like doing what I've been doing to fix these issues. As I'm sure there has to be a better way. That being said I think this code should fix the problems with the joystick. From my experience the UIButton was working fine but I may just be misinterpreting your problem.

    Code (csharp):
    1.    
    2.    
    3.     public static UIJoystick create( string joystickFilename, float scale) {
    4.        
    5.         return create( UI.firstToolkit, joystickFilename, new Rect(0,0,0,0), scale, 0, 0);
    6.     }
    7.    
    8.     public static UIJoystick create( string joystickFilename, Rect hitAreaFrame, float scale) {
    9.         return create( UI.firstToolkit, joystickFilename, hitAreaFrame, scale, (hitAreaFrame.width / 2), -(hitAreaFrame.height / 2) );
    10.     }
    11.    
    12.     public static UIJoystick create( string joystickFilename, Rect hitAreaFrame, float scale, float xPos, float yPos )
    13.     {
    14.         return create( UI.firstToolkit, joystickFilename, hitAreaFrame, scale, xPos, yPos );
    15.     }
    16.  
    17.     public static UIJoystick create( UIToolkit manager, string joystickFilename, Rect hitAreaFrame, float scale, float xPos, float yPos )
    18.     {
    19.         // create the joystrick sprite
    20.         var joystick = manager.addSprite( joystickFilename, 0, 0, 1, true );
    21.         joystick.localScale = new Vector3(scale, scale);
    22.        
    23.         if (hitAreaFrame == new Rect(0,0,0,0)) {
    24.             // grab the texture details for the normal state
    25.             var normalTI = manager.textureInfoForFilename( joystickFilename );
    26.             hitAreaFrame = new Rect( xPos, yPos, normalTI.frame.width * scale, normalTI.frame.height * scale );
    27.             xPos = hitAreaFrame.width/2;
    28.             yPos = -hitAreaFrame.height/2;
    29.         }
    30.            
    31.        
    32.         return new UIJoystick( manager, hitAreaFrame, 1, joystick, xPos, yPos );
    33.     }


    you would then just call the create function like this
    Code (csharp):
    1.  
    2.         leftJoystick = UIJoystick.create( "joystickUp.png", 1.0f);
    and it should size the touchrect to the image size. If you decide you want to up the size just set the touch offsets to something else
    Code (csharp):
    1.  
    2.         leftJoystick.normalTouchOffsets = new UIEdgeOffsets( 15 );
    however you probably would still want to account for different resolutions. I am by no means, master of this subject so I hope that helps. :)
     
    Last edited: Apr 20, 2012