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!