Scaling 2D app the right way?

Dear all,

I am building my first app with Unity and as I am learning I found that scaling is one of the hardest things to do and design around. I need some advice on how to commence with the app design.

The requirements are that the app should match 3 resolutions in window mode for PC - 1200x800 (default), 1440x960, 900x600. When switching between resolutions the app components must scale in size but remain relatively on the same position. Here are a few pictures of the app in progress.

the App itself consists of:
→ Canvas: (CanvasScaler options are:
6133925--668936--upload_2020-7-26_17-57-30.png
→ MainMenu pane ← includes the main 5 buttons that switch between panes.

Everything else is build by scripting and a couple of prefabs. Here are some pics in 1200x800.

But when the App is launched into new resolution - 1440x900 - objects scale change from 1.0 to 0.8333.

Why the game scales the objects 0.833 instead of keeping them 1.0?
This also interferes with my Hover action for the button images where OnHover they become 1.25 and OffHover they go to 1.00.

I do also tried to set Canvas gameojbect CanvasScaler to ConstantPixelSize and then use a global variable based on ratio difference between screen resolution and default resolution to adjust the localPosition and sizedelta for objects that are created by script.

static public float OrgX = 1200, OrgY = 800, ScaleX, ScaleY;
....
....
ScaleX = Screen.width / OrgX;
ScaleY = Screen.height / OrgY;

That works but it seems to me like not the proper method.
There is also the drawback that when Gameobjects are created from unity editor and not by scripting they are not part of the rescaling algorithm which is a bummer.

If possible please advise on how to approach this matter because it tears my mind apart :(.

Any luck? I’ve been hanging my head against canvas adjustment for different aspect ratios too.

Maybe it would help to post the settings for one of the UI elements, perhaps the upper left group of buttons, as well as a shot of the scene view for these elements so we can see the anchors?

1 Like

Hi SlimeProphet,

Sorry for the late response. After I opened this thread I decided to take a break.
I have not yet found out a standardized way to do this both for scripted and manually created gameojbects.

May be when I am back on the matter I will make a script that goes over all manually created objects and redefines them or create a mini script attached to each object that will use Update() to detect changes in resolution and update them on the go. I will let you know once I have such solution.

I figured it out.

On the main script where all static publics create one more like this:

static public void Rescale(Transform tr, int scale = 1, int position = 1)
    {
        RectTransform rt = tr.GetComponent<RectTransform>();

        if(scale == 1)      tr.GetComponent<RectTransform>().sizeDelta = new Vector2(rt.sizeDelta.x * ScaleX, rt.sizeDelta.y * ScaleY);
        if(position == 1)   tr.transform.localPosition = new Vector2(rt.localPosition.x * ScaleX, rt.localPosition.y * ScaleY);
        if (tr.gameObject.GetComponent<Text>() != null)
        {
            tr.GetComponent<Text>().fontSize = (int)((float)tr.GetComponent<Text>().fontSize * ScaleY);
        }

    }

Then on each prefab add the following script:

public class ScaleTree : MonoBehaviour
{

    void Start()
    {
        GameManager.Rescale(this.transform, position: 0); //change size but do not reposition the prefab holder
        foreach (Transform child in transform)
        {
            GameManager.Rescale(child);//change children size and local position based on scale
        }
    }

}

As you can see the code also checks for Text components and rescale the font size accordingly!

1 Like