1
\$\begingroup\$

I have been working with Unity for some time, and I am trying to get a better understand of the UI system.

I am a mobile developer and am redesigning the UI but I am unable to achieve what I want.

My game is in portrait mode and I have a panel. I want the panel to have a maximum width of 1080 pixels. In cases where the panel doesn't fit on the screen because the aspect ratio is less (like the new iPhone X), I want it to shrink it a bit with a minimum width of 700 pixels. In the case that the screen is larger than 1080p (like the iPad Pro) I want the panel to have the maximum size.

Here are visuals of what I want to achieve:

Nexus 6P ( 1080x1920)

Layout on Nexus 6P

iPhone X(1125x2436)

Layout on iPhone X

iPad pro (2048x2732)

Layout on iPad Pro

I have been playing with Layout Element and Content Size Fitter components without success.

If I set the min width size to 700 pixels and preferred size to 1080 pixels nothing happens (even after setting flexible width.)

If I set the Content Size Fitter to the preferred size it just always reverts to the preferred size. The same thing happens with min.

How do these components work, and how I can achieve the desired effect?

Canvas configuration:

canvas confifuration in inspector

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

I don't believe this can be accomplished with the ContentSizeFitter and LayoutElement components. Instead, you will need a custom script that sniffs the device's screen size and computes the aspect ratio and adjusts the RectTransform accordingly.

Fortunately this is quite simple. Here is a demo to show how this can be done. For this example we have a Canvas gameobject with a Panel child. This panel will be the target of our scaling.

minimal setup

The canvas' CanvasScaler component can be set to any of the three UIScaleModes -- all work. The panel's RectTransform anchor preset should be set to stretch/stretch and the top, bottom, left and right values should all be set to zero to have the panel fill the canvas by default.

anchor presets panel values in inspector

For demo purposes, the script is attached to an empty gameobject. Also for demo purposes, the scaling routine runs in the Update loop -- something you would obviously never want to do in a real application. Here's the script:

using UnityEngine;

public class AspectRatioDemo : MonoBehaviour
{
    public RectTransform panel;
    public float maxAspectRatio = 1080f / 1920f; // example: Nexus 6P

    // routine shown in Update for demo purposes, obviously you would only do this once...
    void Update()
    {
        float currentAspectRatio = (float)Screen.width / (float)Screen.height;
        if(currentAspectRatio > maxAspectRatio)
        {
            float padding = (currentAspectRatio - maxAspectRatio)/2f;
            if(padding > .5f)
            {
                Debug.LogError("unsupported aspect ratio"); //addition logic required to support landscape mode
                return;
            }
            panel.anchorMax = new Vector2(1.0f - padding, 1.0f);
            panel.anchorMin = new Vector2(padding, 0);
        }
        else // this is only necessary if panel was previously resized
        {
            panel.anchorMax = Vector2.one;
            panel.anchorMin = Vector2.zero;
        }
    }
}

maxAspectRatio represents the widest aspect you'll allow before padding the panel's margins. By default I have it set to 1080/1920 (.5625). The routine checks whether the actual aspect ratio exceeds this by dividing Screen.width by Screen.Height. If not, it does nothing. If it does, it computes a padding value. (Note the if the computed padding value is greater than .5 we're talking about a device in landcape mode which is unexpected and unsupported here.) Finally the code adjusts the anchors to create the padding.

GIF Demo

\$\endgroup\$
0
\$\begingroup\$

I think you can solve this problem using Anchors. Set your anchor of parent panel to stretch.

below I attached a screenshot to make you understand what I am saying,

You can found this tool in Unity's Transform component

You can found this tool in Unity UI's Rect Transform component where you have to click on the icon and it pops up the attached screenshot.

Now press Alt + Shift (Alt to set position and Shift to set pivot of the object). You will achieve the result you wanted by pressing both alt and shift together and select right one on the downside (last one).

you can learn or read more about anchor point in this unity doc :

Setting UI for multiple screen resolution

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Thank you for the answer, however, this will make the RectTransform to scale always at the same ratio. I want to scale it with a maximum and a minimuim \$\endgroup\$
    – D4rWiNS
    Commented Oct 18, 2018 at 8:09
  • \$\begingroup\$ As per my understanding, it scales to your screen size, even i use this method to scale my UI according to screen size, i think you understand it in wrong manner. however, i will explain here again that when you press Alt with shift and holding both key when you click the last anchor preset it sets your anchors at the corner and it allows you to strecth your screen. \$\endgroup\$ Commented Oct 18, 2018 at 12:06
  • \$\begingroup\$ As you has stated it scales with screen size, but it don't limit the min size or max size, it just scale it, so If you have a panel with a width of 100. and you want to limit the width to a maximum of 200, if there is a screen 3x times larger the width will be 300, instead of 200. I want to give a maximum width \$\endgroup\$
    – D4rWiNS
    Commented Oct 19, 2018 at 11:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .