Author Topic: UIRoot  (Read 59860 times)

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,154
  • Toronto, Canada
    • View Profile
UIRoot
« on: November 20, 2013, 11:44:01 PM »
Overview

UIRoot always lies at the bottom of the NGUI UI hierarchy (or top, depending on how you look at it!)

It's responsible for keeping the scale of the UI somewhat more manageable. Since widget coordinates are generally specified in pixels, a 800 by 400 widget will be 800 by 400 units, which is... quite large. UIRoot shrinks itself by the inverse of the screen's height, thus keeping the widgets small and easier to work with.

   

UIRoot has several scaling styles for you to play with. Flexible style lets your UI always be in pixels, and a 300x200 widget will always take 300 by 200 pixels on the screen. This also means that viewing your UI on a low-res device will make your widgets appear rather large in size, and viewing your UI on a high-res device will make your widgets appear small. On the plus side, with this setting your UI will always remain as crisp as possible.

Constrained is the exact opposite of that. When the UIRoot is set to this setting, your screen will always remain the same size as far as NGUI is concerned, regardless of the actual screen size. This means that if a 300x200 widget takes 25% of your screen with the resolution of 1920x1080, it will still take 25% of the screen when you drop your resolution to 1280x720. If you don't want to worry about how your UI will look at different screen sizes and you don't care much about making it as crisp as possible, choose this setting. Don't forget to set the Content dimensions setting when choosing this option.

You can further refine the constrain by choosing whether the content will Fit on the screen or whether it will Fill the screen (when 'fit' is off). Think of it as your Desktop wallpaper. When you choose the Fit method, the wallpaper will always be fully visible on the screen, where if you go with a Fill method, it will always completely fill the screen while maintaining its aspect ratio. Same idea here. See the attached image for more information.

ConstrainedOnMobiles setting is a combination of the two. It will behave as if the setting was "Flexible" on desktop builds, and it will act as if the size was "Constrained" when targeting mobile platforms.

If you go with the Flexible option, don't forget to set the Minimum and Maximum Height values. These values are used to keep your virtual screen size within "sane" values. So for example if your UI is set to Pixel Perfect mode, and the Minimum Height is set to 720, then some player tries to run your application with the resolution of 800 by 600, the UI will behave as if the setting was "Constrained" with the Content Height set to 720.

Shrink Portrait UI option is designed to adjust your UI's size when the screen is in Portrait mode. It's similar to a height-based adjustment, but it will take the width into consideration as well.

Pro-Tip

The UIRoot always scales itself by 2 / ScreenHeight, where ScreenHeight is either the actual screen height (in pixel perfect mode), or the manual height that you've specified (in fixed size mode). In doing so, the camera that draws the UI can remain at Orthographic Size of 1.

If you don't need the auto-scaling functionality of the UIRoot, you can get rid of this component altogether.

Class Documentation

http://tasharen.com/ngui/docs/class_u_i_root.html

If you have a question regarding this component or would like me to clarify something, just post a reply here.
« Last Edit: August 22, 2014, 04:30:24 AM by ArenMook »

emperor1412

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: UIRoot
« Reply #1 on: December 18, 2013, 02:33:06 AM »
I suggest to have a scale factor which is used to scale up the gameobject that UIRoot is attached to and to set NGUI camera's size property. For example I am using NGUI anchoring with rage tool, I choose the screen height to be 640, scaling style is FixedSize, and the whole NGUI system is too small compared to unity unit. The transform's scale of UIRoot attached-gameobject is set to 0.002472188 which is very small and Rage tool is messed up with that tiny scale. Thus I modified the code a little bit:

in UIRoot.cs:

public float scale = 1000;

protected virtual void Start ()
   {
      UIOrthoCamera oc = GetComponentInChildren<UIOrthoCamera>();

      if (oc != null)
      {
         Debug.LogWarning("UIRoot should not be active at the same time as UIOrthoCamera. Disabling UIOrthoCamera.", oc);
         Camera cam = oc.gameObject.GetComponent<Camera>();
         oc.enabled = false;
         if (cam != null) cam.orthographicSize = 1f * scale;
      }
      else Update();
   }

void Update ()
   {
#if UNITY_EDITOR
      if (!Application.isPlaying && gameObject.layer != 0)
         UnityEditor.EditorPrefs.SetInt("NGUI Layer", gameObject.layer);
#endif
      if (mTrans != null)
      {
         float calcActiveHeight = activeHeight;

         if (calcActiveHeight > 0f )
         {
            float size = 2f / calcActiveHeight;
            
            Vector3 ls = mTrans.localScale;
   
            if (!(Mathf.Abs(ls.x - size) <= float.Epsilon) ||
               !(Mathf.Abs(ls.y - size) <= float.Epsilon) ||
               !(Mathf.Abs(ls.z - size) <= float.Epsilon))
            {
               mTrans.localScale = new Vector3(size * scale, size * scale, size * scale);
            }
         }
      }
   }

I am not sure if it break the other code as now It work just fine to me. Hope to have this scale factor variable in the next version.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,154
  • Toronto, Canada
    • View Profile
Re: UIRoot
« Reply #2 on: December 20, 2013, 12:34:23 PM »
Don't use UIRoot in your case. You don't need it. Remove it, and set the ortho camera's size yourself.

thienhaflash

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 4
    • View Profile
Re: UIRoot
« Reply #3 on: January 07, 2014, 03:36:52 AM »
I think UIRoot should not scale the whole thing down by default, It's very weird to have a root GameObject at some 0.0000xx scale. I belive most of other people would like it better to see UIRoot at scale (1,1,1) - It's what we expect for the first time using a GUI library (and 2D Toolkit is using that). Scaling everything down 0.000xxx will make people confuse as they don't understand what is that value about (and they can't change it). Keeping Orthorgraphic size at 1 is not needed, just set it to Screen.height / 2 ... thanks god I found this post after several years using NGUI, I thought that scale can not be change and I even wrote a script / modify UIRoot's script to prevent the changes. I didn't know that NGUI can live without UIRoot as I belive UIRoot should be the root of all UI, and no UI could survive without UIRoot.

thanks, I got to remove all the UIRoot component now  ;D

sintua

  • Jr. Member
  • **
  • Thank You
  • -Given: 7
  • -Receive: 0
  • Posts: 63
    • View Profile
Re: UIRoot
« Reply #4 on: January 14, 2014, 08:39:49 PM »
Is there a reason there isn't a width property for Pixel Perfect or FixedSize? The setup works well for keeping everything in line vertically, but completely ignores the horizontal. As a result, shrinking a screen's resolution leaves a big blank part off to the side, or a larger resolution leaves content hanging off the right side of the screen.

A width setting that controls sizingin the same fashion would be very useful.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,154
  • Toronto, Canada
    • View Profile
Re: UIRoot
« Reply #5 on: January 14, 2014, 10:05:25 PM »
That's what anchors are for.

If you just have it be based on width AND height, then you will end up with skewed UIs. Think of how poor the UI will look like if you designed it with a 4:3 aspect ratio, then tried to display it stretched on a 25:9? All your squares and circles will be horribly stretched rectangles and ovals.

You need to use anchors instead. Check the very first example that comes with NGUI, then watch the video on the 3.0.7 anchoring system.

LaeusPF

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 3
    • View Profile
Re: UIRoot
« Reply #6 on: February 11, 2014, 12:20:28 PM »
I'm experiencing a significant problem where I can't work with NGUI widgets unless they're under a UIRoot. In previous versions, I could just have a UILabel in the world somewhere (on the ground, or attached to some object). Now, as soon as I add one to some prefab, it immediately creates a UIRoot hierarchy with a UICamera, then parents my prefab to the UI structure. I'm unable to remove the UIRoot in any way -- if I try to move my prefab back out of the hierarchy, I get a bunch of exceptions in the editor.

I tracked this down to the CreatePanel call, which eventually forces a CreateUI if there isn't one. As a test, I tried disabling this functionality, but then the widget doesn't render at all. Is there some new way of having free-floating UIWidgets in the scene? Or should I have dozens of mini UIRoots all over my scene if I want to have NGUI elements sprinkled around?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,154
  • Toronto, Canada
    • View Profile
Re: UIRoot
« Reply #7 on: February 11, 2014, 09:06:16 PM »
It doesn't need to be under a UIRoot.

As long as a widget finds a UIPanel on a parent, it's fine. So make sure you have a panel above your widgets.

Aithoneku

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 4
    • View Profile
Re: UIRoot
« Reply #8 on: April 09, 2014, 02:51:27 AM »
About setting width - I think I understand completely why there is no such thing, but shouldn't be there also a way to setup minimal width? My problem is that what if I change screen so it's width is small while height is big (screen will look like a pillar or something). The screen size would be configured according height, but because there wouldn't be much horizontal space, everything would break even when using anchors. I'm pretty much aware that in that case the enforcing minimal width could make height greater then maximal height (if we would still keep correct aspect ratio - which is IMHO priority number one) - but I think it's better solution then none at all...

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,154
  • Toronto, Canada
    • View Profile
Re: UIRoot
« Reply #9 on: April 09, 2014, 04:22:39 AM »
Set "Shrink Portrait UI" on the UIRoot, Aithoneku.

t_n

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 9
    • View Profile
Re: UIRoot
« Reply #10 on: June 24, 2014, 12:40:22 AM »
I have a hierarchy like the following,

A (UIRoot)
 - B
C (UIRoot)
 - D

When I destroy A, the D is resized (UIWidget size) automatically.
Why does this happen?

I checked anchor target of D, but it suggests that the target is C.

The only way I found to avoid this is separating the two UIRoot placing
on different layers.
« Last Edit: June 24, 2014, 01:10:56 AM by t_n »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,154
  • Toronto, Canada
    • View Profile
Re: UIRoot
« Reply #11 on: June 24, 2014, 05:03:05 AM »
You should be using different layers if you have different UIRoots. Otherwise organize your UI like this:

UIRoot
- B
- D

t_n

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 9
    • View Profile
Re: UIRoot
« Reply #12 on: June 24, 2014, 05:46:17 AM »
Ok, thank you Aren.

ArtemKoval

  • Newbie
  • *
  • Thank You
  • -Given: 4
  • -Receive: 0
  • Posts: 10
    • View Profile
Re: UIRoot
« Reply #13 on: August 28, 2014, 10:45:15 PM »
Hi!

This question is more like clarification.

I'm using Constraint option to preserve rations on different resolutions.

So 1st screenshot is from 22'' desktop, second one - from laptop. As we can see latter one is blurry.

So if I want my UI to be as crisp as possible I should forgo Constraint mode and use Flexible mode?

Thanks, Artem.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,154
  • Toronto, Canada
    • View Profile
Re: UIRoot
« Reply #14 on: August 30, 2014, 09:32:37 AM »
Yes. Flexible mode is the only way to always have crisp looking UIs on all devices.