Skip to content

Instantly share code, notes, and snippets.

@VapidLinus
Last active January 25, 2024 18:35
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save VapidLinus/d6d5f7cd62e5a8b961b63a3c46dff443 to your computer and use it in GitHub Desktop.
Save VapidLinus/d6d5f7cd62e5a8b961b63a3c46dff443 to your computer and use it in GitHub Desktop.
using UnityEngine.UI;
[RequireComponent(typeof(RectTransform), typeof(LayoutElement))]
[ExecuteInEditMode]
public class LayoutElementFitParent : MonoBehaviour
{
[SerializeField] private float aspectRatio = 1;
[SerializeField] private bool updateMin = false;
[SerializeField] private bool updatePreferred = false;
private bool isDirty = false;
private Vector2 lastParentSize;
private new RectTransform transform;
private LayoutElement layoutElement;
public float AspectRatio
{
get { return aspectRatio; }
set
{
aspectRatio = value;
isDirty = true;
}
}
public bool UpdateMin
{
get { return updateMin; }
set
{
updateMin = value;
isDirty = true;
}
}
public bool UpdatePreferred
{
get { return updatePreferred; }
set
{
updatePreferred = value;
isDirty = true;
}
}
private void OnEnable()
{
transform = GetComponent<RectTransform>();
layoutElement = GetComponent<LayoutElement>();
isDirty = true;
}
private void Update()
{
Vector2 parentSize = GetParentSize();
// Mark as dirty if parent's size changes
if (lastParentSize != parentSize)
{
lastParentSize = parentSize;
isDirty = true;
}
// Only recalculate layout size if something has changed
if (!isDirty) return;
isDirty = false;
float neededWidth = parentSize.y * aspectRatio;
float neededHeight = parentSize.x / aspectRatio;
// Is height the limiting factor?
if (neededWidth <= parentSize.x)
{
// Scale to match parent's height
SetSizes(neededWidth, parentSize.y);
}
else
{
// Scale to match parent's width
SetSizes(parentSize.x, neededHeight);
}
}
#if UNITY_EDITOR
private void OnValidate()
{
// Inspector fields have changed, mark as dirty
isDirty = true;
}
#endif
private void SetSizes(float x, float y)
{
if (updateMin)
{
layoutElement.minWidth = x;
layoutElement.minHeight = y;
}
if (updatePreferred)
{
layoutElement.preferredWidth = x;
layoutElement.preferredHeight = y;
}
}
private Vector2 GetParentSize()
{
var parent = transform.parent as RectTransform;
return parent == null ? Vector2.zero : parent.rect.size;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment