Windowed Mode resize Max and Min

Hello

My application runs in windowed mode with with Free Aspect as my Aspect Ratio setting.

Is there a way to set a Maximum and Minimum resolution? Like how the Unity Editor, when scaled down, can lock after a certain width.

Bonus Round: Is there a way to listen to screen resize events?

Thanks in advance everyone.

Maybe taking a look at layout elements will help you, but I fear they won’t have the exact functionality you are wishing for. So I guess in the end you will need to write your own logic. And you are in luck, you can indeed listen to al necessary events if you derive from UIBehaviour. There you will find the method UIBehaviour.OnRectTransformDimensionsChange. If you want to see a simple implementation that uses UIBehaviour and UnityEngine.UI.ILayoutSelfController take a look at this script: RectTransformAnchorSetter (Project description).

Let me know when you finished the script I could need it as well :slight_smile:

Thank you Johannski, I did not know about “OnRectTransformDimensionsChange”, this led me to make some interesting changes which helped me lock panel size after a certain threshold. I have not figured out how to lock the Window size to a minimum unfortunately. Interestingly it looks like the Unity editor has min size functionality though. too bad its just for the editor! So I am still looking for a way to have a minimum Game Window Size.

Anyways, what I made was a way to lock panel size. So after a certain threshold it will maintain 300 pixels in Width.

So normally with Anchors you can lock your panels to just be a percentage of your Canvas, but since I can’t lock window size I made it so my right hand anchor was always at least 300 pixels wide. I did this with two scripts. One on the Canvas that broadcasts events depending on resolution in: OnRectTransformDimensionsChange().

using UnityEngine;
using UnityEngine.EventSystems;


public class WindowResizeController : UIBehaviour
{
    private const float WINDOW_MIN_WIDTH_THRESHOLD = 2400.0f;

    public delegate void OnWindowResize();
    public static WindowResizeController instance = null;
    public OnWindowResize windowMaxResizeEvent;
    public OnWindowResize windowMinResizeEvent;

    private RectTransform _container;
    public RectTransform Container
    {
        get
        {
            if (_container == null)
            {
                _container = (RectTransform)transform;
            }
            return _container;
        }
    }
    void Awake()
    {
        instance = this;
    }

    protected override void OnRectTransformDimensionsChange()
    {
        base.OnRectTransformDimensionsChange();
        if (Container.rect.width < WINDOW_MIN_WIDTH_THRESHOLD)
        {
            if (windowMinResizeEvent != null)
                windowMinResizeEvent();
        }
        else
        {
            if (windowMaxResizeEvent != null)
                windowMaxResizeEvent();
        }
    }
}

Then the second script I had was just on a GameObject in the scene that executed some anchor / width changes depending if we shrunk our Window Size enough. The main take away below is you can use the two events in the above class to change between two anchor presets.

void Start()
{
            WindowResizeController.instance.windowMaxResizeEvent += setMaxHorizontalForm;
            WindowResizeController.instance.windowMinResizeEvent += setMinHorizontalForm;
}

/// <summary>
    /// Sets our 4 Anchors to have a Stretchy style
    /// </summary>
    private void setMaxHorizontalForm()
    {
        UpdateIndentWidth();
        RightAnchor.sizeDelta = Vector2.zero;
        RightAnchor.anchorMin = new Vector2(SET_MAX_RIGHT_ANCHORMIN_X, SET_MAX_RIGHT_ANCHORMIN_Y);
        RightAnchor.anchorMax = new Vector2(SET_MAX_RIGHT_ANCHORMAX_X, SET_MAX_RIGHT_ANCHORMAX_Y);
        RightAnchor.anchoredPosition = Vector2.zero;

        BottomAnchor.sizeDelta = Vector2.zero;
        BottomAnchor.anchorMin = new Vector2(SET_MAX_BOTTOM_ANCHORMIN_X, SET_MAX_BOTTOM_ANCHORMIN_Y);
        BottomAnchor.anchorMax = new Vector2(SET_MAX_BOTTOM_ANCHORMAX_X, SET_MAX_BOTTOM_ANCHORMAX_Y);
        BottomAnchor.anchoredPosition = Vector2.zero;

        TopAnchor.sizeDelta = Vector2.zero;
        TopAnchor.anchorMin = new Vector2(SET_MAX_TOP_ANCHORMIN_X, SET_MAX_TOP_ANCHORMIN_Y);
        TopAnchor.anchorMax = new Vector2(SET_MAX_TOP_ANCHORMAX_X, SET_MAX_TOP_ANCHORMAX_Y);
        TopAnchor.anchoredPosition = Vector2.zero;
        DirtyLater();

    }
  

    /// <summary>
    /// Sets a minimum size for the Right Anchor and adjusts the other anchors
    /// </summary>
    private void setMinHorizontalForm()
    {
        UpdateIndentWidth();
        RightAnchor.sizeDelta = new Vector2(PANEL_MIN_SIZE, 0.0f);
        RightAnchor.anchorMin = new Vector2(SET_MIN_RIGHT_ANCHORMIN_X, SET_MIN_RIGHT_ANCHORMIN_Y);
        RightAnchor.anchorMax = new Vector2(SET_MIN_RIGHT_ANCHORMAX_X, SET_MIN_RIGHT_ANCHORMAX_Y);
        RightAnchor.anchoredPosition = new Vector2(indentWidth, 0.0f);

        BottomAnchor.sizeDelta = new Vector2(-(PANEL_MIN_SIZE + INDENT_PADDING), 0.0f);
        BottomAnchor.anchorMin = new Vector2(SET_MIN_BOTTOM_ANCHORMIN_X, SET_MIN_BOTTOM_ANCHORMIN_Y);
        BottomAnchor.anchorMax = new Vector2(SET_MIN_BOTTOM_ANCHORMAX_X, SET_MIN_BOTTOM_ANCHORMAX_Y);
        BottomAnchor.anchoredPosition = new Vector2(indentWidth, 0.0f);

        TopAnchor.sizeDelta = new Vector2(-(PANEL_MIN_SIZE + INDENT_PADDING), 0.0f);
        TopAnchor.anchorMin = new Vector2(SET_MIN_TOP_ANCHORMIN_X, SET_MIN_TOP_ANCHORMIN_Y);
        TopAnchor.anchorMax = new Vector2(SET_MIN_TOP_ANCHORMAX_X, SET_MIN_TOP_ANCHORMAX_Y);
        TopAnchor.anchoredPosition = new Vector2(indentWidth, 0.0f);
        DirtyLater();
    }

//Calling LayoutRebuilder.MarkLayoutForRebuild on the end frame of LateUpdate is best practice for UI getting accurate measurements.
    public void DirtyLater()
    {
        if (!doingDirtyLater)
            StartCoroutine(DoDirtyLater());
    }

    IEnumerator DoDirtyLater()
    {
        doingDirtyLater = true;
        yield return new WaitForEndOfFrame();
        doingDirtyLater = false;

        //Should I make a queue?
        LayoutRebuilder.MarkLayoutForRebuild(RightAnchor);
        LayoutRebuilder.MarkLayoutForRebuild(BottomAnchor);
        LayoutRebuilder.MarkLayoutForRebuild(TopAnchor);
        //At this time we don't need LeftAnchor to resize
        //LayoutRebuilder.MarkLayoutForRebuild(LeftAnchor);
    }

This stuff is tailored to specifically what i need but maybe it helps someone out there. Let me know if any of you figure out how to do a Game Window Minimum size!