Author Topic: FixedDimensions  (Read 15115 times)

Ugur

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 60
    • View Profile
FixedDimensions
« on: January 16, 2014, 06:23:43 AM »
Is there any way to get NGUI to display the controls in fixed dimensions?
So that the buttons (all controls and ngui stuff really) have the same physical (not pixel) dimensions, no matter which screen size and screen dpi the device has?

By the name one could assume that the "FixedSize" value for scaling style in UIRoot would do that, but nay, it actually does not, the controls still get scaled based on the screen height.
This makes no sense at all to me, seriously, who wants his buttons to have different dimensions when one holds the device in portrait and again different ones when one holds it in landscape?

So yeah, is it possible in any way to get it to work in a way where the controls always have the same physical dimensions, no matter which screen res/screen height/screen dpi ?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: FixedDimensions
« Reply #1 on: January 16, 2014, 11:56:34 PM »
Fixed Size does just that, and controls won't scale on screen height. Fixed size keeps the UIRoot of exact, non-changing dimensions. If UIRoot doesn't change, and the UI camera's ortho size doesn't change, everything will remain the same exact size proportionally to screen height, regardless of screen size.

Ugur

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 60
    • View Profile
Re: FixedDimensions
« Reply #2 on: January 17, 2014, 02:01:17 AM »
Hm, maybe its not clear what i'm asking.
So basically, what i'd like (and what would make sense for most UIs) is that when i have a rectangle of 1 cm x 1cm in physical dimensions, then that should stay 1 cm x 1cm no matter which screen dimensions and dpi the app runs at.

As far as i can tell it does not work at all like that in NGUi. Instead the dimensions change with changing screen height. And dimensions of UI elements don't "just" change with changing screen dimensions or dpi (would already be not good), but even when the overall dimensions of the screen and dpi are exactly the same and just the orientation is different.

Maybe the usability is not clear, so let's go through it:
-I open the ngui example scene "Example 0 - Control Widgets"
-I change scaling style in the UIRoot to FixedSize
-I hit play
-I change the dimensions of the game window forth and back between 960x640 and 640x960
-This is the look i get:




What should instead happen would be that all would stay exactly the same physical dimensions.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: FixedDimensions
« Reply #3 on: January 17, 2014, 11:18:57 PM »
Fixed size must be just that -- fixed. Once you set it, it will remain like that, regardless of screen size. All widgets will keep their size proportionally to the manual height. So if you had a widget that took 1/3rd of the screen, it will still take 1/3rd of the screen even if the screen size changes.

NGUI is always based on screen height, and never on screen width. So the first pic is based on screen height of 960, while the second pic is based on screen height of 640. If you want it to be based on DPI instead, set the manual height accordingly using your own logic.

Ugur

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 60
    • View Profile
Re: FixedDimensions
« Reply #4 on: January 18, 2014, 01:37:09 AM »
Yeah, that’s exactly what i complained about =)
First FixedSize is a wrong name then, more fitting would be something like scaledRelativeToScreenHeight or something like that. Cause its really not fixed size, its fixed relative size at best, not even that since only relative in one direction.
Second, besides the name, way more important: the functionality itself is bad.
Again, when you think about the usability, who wants his buttons to have different dimensions in portrait mode than in landscape mode on his smartphone/tablet?

For a good modern UI system there really should be a mode (which likely should even be the default setting), let’s say fixedPhysicalDimensions, which as i said would make the buttons always have the exact same physical dimensions no matter which screen width, height or dpi the app runs at.
So one can anchor things and make the available room for (scroll)panes etc change fitting to the screen dimensions, and any user interaction control parts like buttons have the same physical dimensions so they always look good and are well usable with touch and mouse.

I’d say this is actually one of the most essential features for doing multiplatform stuff with a UI system, especially but not only when doing stuff for touch screen devices which are used in both portrait and landscape orientation and where one has to ensure buttons used with touch always have the same physical dimensions in both portrait and landscape and also generally always have the same physical dimensions on any screen resolution and dpi so that they are actually well usable with touch with your fingers.
(This will also become very important on desktops and laptops very soon since more and more of them go higher dpi, weird special resolutions, get touch support and more and more of the better desktop screens allow rotating the screen so it can be used in portrait and landscape, too. So it is most essential for UI to be usable in fixed physical dimensions for user input controls independent of resolution, dpi and screen orientation)

A button which has right dimensions for being touched with your finger in portrait orientation but then gets scaled down in landscape orientation and hence looks bad and worse has too small touch are in landscape device orientation makes absolutely zero sense.

Besides lacking in usability, yeah, it also looks really bad to have bitmap stuff scaled smaller there just because the user looks at it in a landscape instead of portrait screen orientation.


Now ok, let's get constructive here =)
So far ngui does not have any such feature, so will you add it for an update?

I’d say (besides better looking fonts/text rendering and better working and more intuitive anchoring/relative panel sizing needed and vector graphics assets support) this is THE most important required functionality for a modern multiplatform UI system.


I’ll just brainstorm some on how a fixedPhysicalDimensions enforcer could maybe be done, anyone feel free to add to or improve on the thoughts =)

So maybe when choosing FixedPhysicalDimensions as new scaling style setting in the UIRoot, it could expose the property fields baseScreenWidth, baseScreenHeight, baseDPI.
So one would basically enter the values for the screen the UI is made in as base setting.
It could also set the current game view's settings as base values automatically at the start.

Ok, then based on that the script could whenever the screen width, screen height or dpi changes (happens when changing device orientation or user changes resolution setting) or generally is different than your base settings, it would calculate scale factor needed to scale things accordingly to lead to all having the same physical dimensions.

Do you think trying to implement the fixed physical dimensions feature this way could work?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: FixedDimensions
« Reply #5 on: January 18, 2014, 02:30:21 AM »
Did you see this post linked from the Useful Stuff sticky?

http://www.tasharen.com/forum/index.php?topic=2397.0

Ugur

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 60
    • View Profile
Re: FixedDimensions
« Reply #6 on: January 18, 2014, 05:27:17 AM »
yeah, i did, but that does not do what i asked =) With those scripts the buttons still get scaled to different physical dimensions when the screen dimensions change.
What should happen is more that it works like the PixelPerfect scaling style setting for the UIRoot on the end that it doesn't change with changing screen width or height, but unlike the PixelPerfect setting it should take screen dpi into consideration so that it has the same physical dimensions on any dpi screen.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: FixedDimensions
« Reply #7 on: January 18, 2014, 10:19:11 PM »
Yeah, I understand what you're asking, but the DPI setting is not something that can be relied upon. It's not guaranteed to give accurate results. It may work for some platforms, but not for all -- and certainly not for PC platforms with the variety of monitors. So it would be, at best, a hack that works for some (but not all) mobile devices.

Ugur

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 60
    • View Profile
Re: FixedDimensions
« Reply #8 on: January 19, 2014, 11:45:41 AM »
Pinging Screen.dpi should give correct values on most modern mobile devices.
Yes, its not on all, nor on all desktop options or in editor.
Still, it would then be a viable choice to when Screen.dpi returns 0 assume a hardcoded value for current dpi, so then base dpi and current dpi would be the same and then the resulting look would basically be the same as the PixelPerfect setting.
(since the scale differences between base dpi and current dpi would be 0 so the scale factor be 1, so no scaling)
Whereas for any of all the devices where it returns the correct value (most modern mobile devices at least) it would be scaled as it should be so buttons etc always have the same physical dimensions.
So this solution would in worst case (0 returned for Screen dpi) be as usable as the PixelPerfect setting and in all cases where the correct Screen.dpi is returned it would be much better to use than both PixelPerfect and the basically totally buggy feeling FixedSize scaling mode setting.
Cause as it is, FixedSize basically leads to wrong look in at least one screen orientation on basically all devices which allow to change the screen orientation, and not just on those, basically whenever the screen height changes for whatever reason.

Ugur

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 60
    • View Profile
Re: FixedDimensions
« Reply #9 on: January 19, 2014, 01:04:04 PM »
ok, i gave it a try and mocked something up =)

Probably best would be to add a new scaling style to UIRoot.cs but i didn't do that for now since i don't want that to be overwritten when i update the NGUi package.

So for now i just did it in a separate script, which i called UIRootFixedPhysicalSizeEnforcer.cs

So you can put this script onto the gameObject that contains the UIRoot and set the UIRoot's scaling size to FixedSize.


UIRootFixedPhysicalSizeEnforcer.cs :

  1. /*
  2. Ugur:
  3. this will scale content based on screen dpi with the thought that buttons, unless wanted otherwise for special cases, should always have the same physical dimensions, no matter which resolution, dpi, screen dimension or screen orientation
  4. that way getting around the issues of UIRoot scaling style PixelPerfect (too small on high dpi screen) and FixedSize (buttons getting scaled based on screen height so one then suddenly has different button dimensions in portrait and landscape screen orientation)
  5.  
  6. usage:
  7. -select the gameObject which has the UIRoot script on it
  8. -set UIRoot scaling style to FixedSize
  9. -Add this script to the gameObject which has the UIRoot script on it
  10.  
  11. Note: in editor, desktop and some specific devices Screen.dpi returns the value 0, in that case either provide a hardcoded value for currentDpi or else in that case the scaling result will be the same as setting PixelPerfect as scaling style in the UIRoot.
  12. */
  13.  
  14. using UnityEngine;
  15. using System.Collections;
  16.  
  17.  
  18. [RequireComponent(typeof(UIRoot))]
  19.  
  20. [ExecuteInEditMode]
  21.  
  22. public class UIRootFixedPhysicalSizeEnforcer : MonoBehaviour
  23. {
  24.        
  25.         UIRoot mRoot;
  26.         public const float defaultDpi = 160;
  27.         public float currentDpi;
  28.  
  29.  
  30.         private float storedScreenWidth;
  31.         private float storedScreenHeight;
  32.  
  33.         void Awake () { mRoot = GetComponent<UIRoot>();
  34.                 currentDpi = Screen.dpi;
  35.                 if (currentDpi == 0f) currentDpi = defaultDpi;
  36.         }
  37.  
  38.  
  39.        
  40.         void Update ()
  41.         {
  42.                 if(storedScreenWidth!= Screen.width || storedScreenHeight!= Screen.height){
  43.                         float factor = currentDpi / defaultDpi;
  44.  
  45.                         mRoot.manualHeight = Mathf.FloorToInt(Screen.height/factor);
  46.  
  47.                         //Debug.Log("current screen dpi:"+currentDpi+",factor:"+factor+",manualHeight:"+mRoot.manualHeight);
  48.  
  49.                         storedScreenWidth = Screen.width;
  50.                         storedScreenHeight = Screen.height;
  51.  
  52.                 }
  53.  
  54.         }
  55. }
  56.  
  57.  
  58.  



I'm not sure if its the best way to do things, and may even be off in a way, i just quickly put it together and tested it in editor and on iPhone (4s) and iPad (3) and it looked and worked fine in both landscape and portrait on both (so my UI buttons etc always had the same physical dimensions no matter if iPhone or iPad or which screen orientation the device was in =) )
(update: also tried it on htc one and transformer prime now, same result, looking good in both landscape and portrait and the ui gets the same physical dimensions on all =) )


Thoughts/improvement suggestions and any feedback appreciated =)
« Last Edit: January 19, 2014, 04:32:39 PM by Ugur »

metaphysician

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: FixedDimensions
« Reply #10 on: February 06, 2014, 03:31:53 AM »
not to butt in on this thread, but is there any way to perhaps resize UIRoots based on the physical screen dimensions? can a script poll for a device's resolution and act accordingly? i'm having issues with your script Ugur, but it may be how i'm implementing it. at the moment it acts exactly as you don't want - it resizes text smaller on larger PPI devices.

scott


Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: FixedDimensions
« Reply #11 on: February 06, 2014, 03:45:47 AM »
This is something I've messed with in the past. It's fairly easy to just set the manualHeight at run time based on Screen.dpi or whatever other factors you want to do.

Just make a scrip you put on your UIRoot and has a reference to the UIRoot then you can set it to your hearts content. Generally you only need to change the height on certain changes like rotation of the screen and on start.

Something else that would be nice to have rely on dpi is drag/click distances, which right now is based on "pixels" which make little sense in the mobile space, as 10 pixels on a iphone 5 is 0.03inches and the same on an ipad 2 is 0.3 inches - a WORLD of difference in the physical world. Optimally, the distances used would be physical mm or inches, which are then translated to pixels on screen via some formula.

metaphysician

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: FixedDimensions
« Reply #12 on: February 06, 2014, 04:01:11 AM »
interesting... so if i had a setup script like:

so if i simply just have a script that in the Start() function uses Screen.height. like:

if(Screen.height < 1536){
//change settings for nonRetina
} else {
// use Retina Settings
}

that would work?

Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: FixedDimensions
« Reply #13 on: February 06, 2014, 04:02:32 AM »
That's what I'm doing. ;)

metaphysician

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: FixedDimensions
« Reply #14 on: February 06, 2014, 05:40:29 AM »
so - one question on the resizing thing. i'm trying to resize the scale of the UIRoot but it doesn't let me edit it. before when i was resizing, i was using Anchors. this worked fine before but not sure it is a preferred method?