The aspect ratioThe relationship of an image’s proportional dimensions, such as its width and height.
See in Glossary is the ratio between the width and height of the display. The aspect ratio is used to maintain the proportions of the display. For example, if you have a 4:3
aspect ratio, then the display is 4
pixelsThe smallest unit in a computer image. Pixel size depends on your screen resolution. Pixel lighting is calculated at every screen pixel. More info
See in Glossary wide for every 3
pixels in height. If you have a 16:9
aspect ratio, then the display is 16
pixels wide for every 9
pixels in height.
This example creates a custom control that maintains a specified aspect ratio of its child elements. For demonstration purposes, the custom control adds paddings to the left and right if the display ratio is wider, or the top and bottom if the display ratio is higher, pushing the “central” items to fit into the aspect ratio.
You can find the completed files that this example creates in this GitHub repository.
This guide is for developers familiar with the Unity Editor, UI(User Interface) Allows a user to interact with your application. Unity currently supports three UI systems. More info
See in Glossary Toolkit, and C# scripting. Before you start, get familiar with the following:
Create a C# class that inherits from VisualElement
with two attributes: width
and height
. The width
and height
attributes are used to calculate the aspect ratio.
Create a Unity project with any template.
Create a C# script named AspectRatio.cs
with the following content:
using UnityEngine;
using UnityEngine.UIElements;
// Custom element that lays out its contents following a specific aspect ratio.
[UxmlElement]
public partial class AspectRatioElement : VisualElement
{
// The ratio of width.
[UxmlAttribute("width")]
public int RatioWidth
{
get => _ratioWidth;
set
{
_ratioWidth = value;
UpdateAspect();
}
}
// The ratio of height.
[UxmlAttribute("height")]
public int RatioHeight
{
get => _ratioHeight;
set
{
_ratioHeight = value;
UpdateAspect();
}
}
// Padding elements to keep the aspect ratio.
private int _ratioWidth = 16;
private int _ratioHeight = 9;
public AspectRatioElement()
{
// Update the padding elements when the geometry changes.
RegisterCallback<GeometryChangedEvent>(UpdateAspectAfterEvent);
// Update the padding elements when the element is attached to a panel.
RegisterCallback<AttachToPanelEvent>(UpdateAspectAfterEvent);
}
static void UpdateAspectAfterEvent(EventBase evt)
{
var element = evt.target as AspectRatioElement;
element?.UpdateAspect();
}
private void ClearPadding()
{
style.paddingLeft = 0;
style.paddingRight = 0;
style.paddingBottom = 0;
style.paddingTop = 0;
}
// Update the padding.
private void UpdateAspect()
{
var designRatio = (float)RatioWidth / RatioHeight;
var currRatio = resolvedStyle.width / resolvedStyle.height;
var diff = currRatio - designRatio;
if (RatioWidth <= 0.0f || RatioHeight <= 0.0f)
{
ClearPadding();
Debug.LogError($"[AspectRatio] Invalid width:{RatioWidth} or height:{RatioHeight}");
return;
}
if (float.IsNaN(resolvedStyle.width) || float.IsNaN(resolvedStyle.height))
{
return;
}
if (diff > 0.01f)
{
var w = (resolvedStyle.width - (resolvedStyle.height * designRatio)) * 0.5f;
style.paddingLeft = w;
style.paddingRight = w;
style.paddingTop = 0;
style.paddingBottom = 0;
}
else if (diff < -0.01f)
{
var h = (resolvedStyle.height - (resolvedStyle.width * (1/designRatio))) * 0.5f;
style.paddingLeft= 0;
style.paddingRight = 0;
style.paddingTop = h;
style.paddingBottom = h;
}
else
{
ClearPadding();
}
}
}
Create a custom Editor window that uses the custom control. Test the custom control to see how it behaves when you change the aspect ratio.
Create a C# script named AspectRatioDemo.cs
with the following content:
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public class AspectRatioDemo : EditorWindow
{
[SerializeField]
private VisualTreeAsset m_VisualTreeAsset = default;
[MenuItem("Test/AspectRatioDemo")]
public static void ShowExample()
{
AspectRatioDemo wnd = GetWindow<AspectRatioDemo>();
wnd.titleContent = new GUIContent("AspectRatioDemo");
}
public void CreateGUI()
{
// Each editor window contains a root VisualElement object.
VisualElement root = rootVisualElement;
var aspectRatio = new AspectRatioElement();
aspectRatio.style.flexGrow = 1;
var widthField = new IntegerField() { value = aspectRatio.RatioWidth, label = "W"};
var heightField = new IntegerField() { value = aspectRatio.RatioHeight, label = "H" };
root.Add(widthField);
root.Add(heightField);
root.Add(aspectRatio);
var contents = new VisualElement();
aspectRatio.Add(contents);
aspectRatio.style.backgroundColor = Color.black;
contents.style.backgroundColor = Color.green;
widthField.RegisterValueChangedCallback((evt) =>aspectRatio.RatioWidth = evt.newValue);
heightField.RegisterValueChangedCallback((evt) => aspectRatio.RatioHeight = evt.newValue);
contents.style.width = new Length(100, LengthUnit.Percent);
contents.style.height = new Length(100, LengthUnit.Percent);
contents.RegisterCallback<GeometryChangedEvent>((evt) =>
{
Debug.Log($"Content ratio: {evt.newRect.width} x {evt.newRect.height} : {evt.newRect.width/evt.newRect.height}");
});
}
}
From the menu, select Test > Aspect Ratio Demo.
Change the aspect ratios to different values. The custom control adds padding to the left and right, or top and bottom depending on the size of your Editor window.