Last active
April 1, 2021 23:08
-
-
Save QuantumCalzone/ce5e6b1421203fdaa1a75b89afc39cbc to your computer and use it in GitHub Desktop.
An extension of Unity's LayoutElement script that enable more flexible adaptation such as matching another RecTransform's dimensions or setting maximum preferred values. Put the Inspector and Property Drawer scripts in an Editor folder. Also available as a package at https://github.com/QuantumCalzone/UnityLayoutElementExtended
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEngine.UI; | |
namespace QuantumCalzone | |
{ | |
[AddComponentMenu("Layout/Extended/Layout Element Extended")] | |
[RequireComponent(typeof(RectTransform))] | |
public class LayoutElementExtended : LayoutElement | |
{ | |
public LayoutElementExtendedValue MinWidthExtended = new LayoutElementExtendedValue(); | |
public LayoutElementExtendedValue MinHeightExtended = new LayoutElementExtendedValue(); | |
public LayoutElementExtendedValue PreferredWidthExtended = new LayoutElementExtendedValue(); | |
public LayoutElementExtendedValue PreferredHeightExtended = new LayoutElementExtendedValue(); | |
public LayoutElementExtendedValue FlexibleWidthExtended = new LayoutElementExtendedValue(); | |
public LayoutElementExtendedValue FlexibleHeightExtended = new LayoutElementExtendedValue(); | |
public LayoutElementExtendedValue MaxWidth = new LayoutElementExtendedValue(); | |
public LayoutElementExtendedValue MaxHeight = new LayoutElementExtendedValue(); | |
private RectTransform rectTransform = null; | |
public RectTransform GetRectTransform { | |
get { | |
if (!rectTransform) rectTransform = GetComponent<RectTransform>(); | |
return rectTransform; | |
} | |
} | |
public float Width { | |
get { | |
var valueToReturn = 0f; | |
if (MinWidthExtended.Enabled && !PreferredWidthExtended.Enabled) | |
{ | |
valueToReturn = MinWidth; | |
} | |
else if (!MinWidthExtended.Enabled && PreferredWidthExtended.Enabled) | |
{ | |
valueToReturn = PreferredWidth; | |
} | |
else if (MinWidthExtended.Enabled && PreferredWidthExtended.Enabled) | |
{ | |
valueToReturn = PreferredWidth > MinWidth ? PreferredWidth : MinWidth; | |
} | |
return valueToReturn; | |
} | |
} | |
public float Height { | |
get { | |
var valueToReturn = 0f; | |
if (MinHeightExtended.Enabled && !PreferredHeightExtended.Enabled) | |
{ | |
valueToReturn = MinHeight; | |
} | |
else if (!MinHeightExtended.Enabled && PreferredHeightExtended.Enabled) | |
{ | |
valueToReturn = PreferredHeight; | |
} | |
else if (MinHeightExtended.Enabled && PreferredHeightExtended.Enabled) | |
{ | |
valueToReturn = PreferredHeight > MinHeight ? PreferredHeight : MinHeight; | |
} | |
return valueToReturn; | |
} | |
} | |
#region Min | |
private float MinWidth { | |
get { | |
var valueToReturn = 0f; | |
if (MinWidthExtended.Enabled) | |
{ | |
MinWidthExtended.ProcessTargetValue(gameObject); | |
valueToReturn = MinWidthExtended.TargetValue; | |
if (MaxWidth.Enabled) | |
{ | |
MaxWidth.ProcessTargetValue(gameObject); | |
if (valueToReturn > MaxWidth.TargetValue) | |
valueToReturn = MaxWidth.TargetValue; | |
} | |
} | |
return valueToReturn; | |
} | |
} | |
private float MinHeight { | |
get { | |
var valueToReturn = 0f; | |
if (MinHeightExtended.Enabled) | |
{ | |
MinHeightExtended.ProcessTargetValue(gameObject); | |
valueToReturn = MinHeightExtended.TargetValue; | |
if (MaxHeight.Enabled) | |
{ | |
MaxHeight.ProcessTargetValue(gameObject); | |
if (valueToReturn > MaxHeight.TargetValue) | |
valueToReturn = MaxHeight.TargetValue; | |
} | |
} | |
return valueToReturn; | |
} | |
} | |
#endregion | |
#region Preferred | |
private float PreferredWidth { | |
get { | |
var preferredWidth = 0f; | |
if (PreferredWidthExtended.Enabled) | |
{ | |
PreferredWidthExtended.ProcessTargetValue(gameObject); | |
preferredWidth = PreferredWidthExtended.TargetValue; | |
if (MaxWidth.Enabled) | |
{ | |
MaxWidth.ProcessTargetValue(gameObject); | |
if (preferredWidth > MaxWidth.TargetValue) | |
preferredWidth = MaxWidth.TargetValue; | |
} | |
} | |
return preferredWidth; | |
} | |
} | |
private float PreferredHeight { | |
get { | |
var preferredHeight = 0f; | |
if (PreferredHeightExtended.Enabled) | |
{ | |
PreferredHeightExtended.ProcessTargetValue(gameObject); | |
preferredHeight = PreferredHeightExtended.TargetValue; | |
if (MaxHeight.Enabled) | |
{ | |
MaxHeight.ProcessTargetValue(gameObject); | |
if (preferredHeight > MaxHeight.TargetValue) | |
preferredHeight = MaxHeight.TargetValue; | |
} | |
} | |
return preferredHeight; | |
} | |
} | |
#endregion | |
#region Flexible | |
private float FlexibleWidth { | |
get { | |
var flexibleWidth = 0f; | |
if (FlexibleWidthExtended.Enabled) | |
{ | |
FlexibleWidthExtended.ProcessTargetValue(gameObject); | |
flexibleWidth = FlexibleWidthExtended.TargetValue; | |
} | |
return flexibleWidth; | |
} | |
} | |
private float FlexibleHeight { | |
get { | |
var flexibleHeight = 0f; | |
if (FlexibleHeightExtended.Enabled) | |
{ | |
FlexibleHeightExtended.ProcessTargetValue(gameObject); | |
flexibleHeight = FlexibleHeightExtended.TargetValue; | |
} | |
return flexibleHeight; | |
} | |
} | |
#endregion | |
#region Unity Methods | |
public override void CalculateLayoutInputHorizontal() | |
{ | |
minWidth = MinWidthExtended.Enabled ? MinWidth : -1; | |
preferredWidth = PreferredWidthExtended.Enabled ? PreferredWidth : -1; | |
flexibleWidth = FlexibleWidthExtended.Enabled ? FlexibleWidth : -1; | |
base.CalculateLayoutInputHorizontal(); | |
} | |
public override void CalculateLayoutInputVertical() | |
{ | |
minHeight = MinHeightExtended.Enabled ? MinHeight : -1; | |
preferredHeight = PreferredHeightExtended.Enabled ? PreferredHeight : -1; | |
flexibleHeight = FlexibleHeightExtended.Enabled ? FlexibleHeight : -1; | |
base.CalculateLayoutInputVertical(); | |
} | |
#if UNITY_EDITOR | |
private void Update() | |
{ | |
CalculateLayoutInputHorizontal(); | |
CalculateLayoutInputVertical(); | |
} | |
#endif | |
#endregion | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEditor; | |
using UnityEditor.UI; | |
namespace QuantumCalzone | |
{ | |
[CanEditMultipleObjects] | |
[CustomEditor(typeof(LayoutElementExtended), true)] | |
public class LayoutElementExtendedEditor : LayoutElementEditor | |
{ | |
private SerializedProperty m_IgnoreLayout = null; | |
private SerializedProperty m_LayoutPriority = null; | |
private SerializedProperty MinWidthExtended = null; | |
private SerializedProperty MinHeightExtended = null; | |
private SerializedProperty PreferredWidthExtended = null; | |
private SerializedProperty PreferredHeightExtended = null; | |
private SerializedProperty FlexibleWidthExtended = null; | |
private SerializedProperty FlexibleHeightExtended = null; | |
private SerializedProperty MaxWidth = null; | |
private SerializedProperty MaxHeight = null; | |
public override void OnInspectorGUI() | |
{ | |
serializedObject.Update(); | |
EditorGUILayout.PropertyField(m_IgnoreLayout); | |
if (!m_IgnoreLayout.boolValue) | |
{ | |
EditorGUILayout.BeginVertical("Box"); | |
EditorGUILayout.LabelField("Extended", EditorStyles.boldLabel); | |
DisplayPropertyFieldInBox(MinWidthExtended); | |
DisplayPropertyFieldInBox(MinHeightExtended); | |
DisplayPropertyFieldInBox(PreferredWidthExtended); | |
DisplayPropertyFieldInBox(PreferredHeightExtended); | |
DisplayPropertyFieldInBox(FlexibleWidthExtended); | |
DisplayPropertyFieldInBox(FlexibleHeightExtended); | |
DisplayPropertyFieldInBox(MaxWidth); | |
DisplayPropertyFieldInBox(MaxHeight); | |
EditorGUILayout.EndVertical(); | |
} | |
EditorGUILayout.PropertyField(m_LayoutPriority); | |
serializedObject.ApplyModifiedProperties(); | |
} | |
protected override void OnEnable() | |
{ | |
base.OnEnable(); | |
m_IgnoreLayout = serializedObject.FindProperty("m_IgnoreLayout"); | |
m_LayoutPriority = serializedObject.FindProperty("m_LayoutPriority"); | |
MinWidthExtended = serializedObject.FindProperty("MinWidthExtended"); | |
MinHeightExtended = serializedObject.FindProperty("MinHeightExtended"); | |
PreferredWidthExtended = serializedObject.FindProperty("PreferredWidthExtended"); | |
PreferredHeightExtended = serializedObject.FindProperty("PreferredHeightExtended"); | |
FlexibleWidthExtended = serializedObject.FindProperty("FlexibleWidthExtended"); | |
FlexibleHeightExtended = serializedObject.FindProperty("FlexibleHeightExtended"); | |
MaxWidth = serializedObject.FindProperty("MaxWidth"); | |
MaxHeight = serializedObject.FindProperty("MaxHeight"); | |
} | |
private void DisplayPropertyFieldInBox(SerializedProperty target) | |
{ | |
EditorGUILayout.BeginVertical("Box"); | |
EditorGUILayout.PropertyField(target); | |
EditorGUILayout.EndVertical(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEngine; | |
namespace QuantumCalzone | |
{ | |
[Serializable] | |
public class LayoutElementExtendedValue | |
{ | |
public enum ReferenceTypes { None, Width, Height } | |
public bool Enabled = false; | |
public ReferenceTypes ReferenceType = ReferenceTypes.None; | |
public RectTransform Reference = null; | |
public float ReferenceDelta = 0; | |
public float TargetValue = 0; | |
public void ProcessTargetValue(UnityEngine.Object context) | |
{ | |
if (!Reference && ReferenceType != ReferenceTypes.None) | |
{ | |
Debug.Log("This needs a reference to process your target Layout values", context); | |
return; | |
} | |
switch (ReferenceType) | |
{ | |
case ReferenceTypes.None: | |
break; | |
case ReferenceTypes.Width: | |
TargetValue = Reference.rect.width; | |
break; | |
case ReferenceTypes.Height: | |
TargetValue = Reference.rect.height; | |
break; | |
default: | |
Debug.LogError(string.Format("No support for a referenceType of: {0}", ReferenceType), context); | |
break; | |
} | |
TargetValue += ReferenceDelta; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEditor; | |
namespace QuantumCalzone | |
{ | |
[CustomPropertyDrawer(typeof(LayoutElementExtendedValue))] | |
public class LayoutElementExtendedValuePropertyDrawer : PropertyDrawer | |
{ | |
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | |
{ | |
EditorGUI.BeginProperty(position, label, property); | |
GUI.Label(position, label, EditorStyles.boldLabel); | |
var enabled = property.FindPropertyRelative("Enabled"); | |
EditorGUILayout.PropertyField(enabled); | |
if (enabled.boolValue) | |
{ | |
var referenceType = property.FindPropertyRelative("ReferenceType"); | |
var reference = property.FindPropertyRelative("Reference"); | |
var referenceDelta = property.FindPropertyRelative("ReferenceDelta"); | |
var targetValue = property.FindPropertyRelative("TargetValue"); | |
EditorGUILayout.PropertyField(referenceType); | |
if ((LayoutElementExtendedValue.ReferenceTypes)referenceType.enumValueIndex != LayoutElementExtendedValue.ReferenceTypes.None) | |
{ | |
EditorGUILayout.PropertyField(reference); | |
EditorGUILayout.PropertyField(referenceDelta); | |
GUI.enabled = false; | |
EditorGUILayout.PropertyField(targetValue); | |
GUI.enabled = true; | |
} | |
else EditorGUILayout.PropertyField(targetValue); | |
} | |
EditorGUI.EndProperty(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Is Flexible Height enabled and/or is Preferred Height enabled and its resulting value at something greater than the Max Height?