在Unity UI中,LayoutElement具有min,prefered和flxible大小,但它没有max size属性。
例如,如果我有text1
和
layoutElement.flxibleWith = 1
layoutElement.minHeight = 19
text1
一行txt:
但是当我在text1
中加载文字时,它继续传播它的高度,没有任何限制:
我制作了一个剧本:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
[ExecuteInEditMode]
[RequireComponent(typeof(LayoutElement))]
public class LayoutElementMaxSize : MonoBehaviour
{
private LayoutElement layoutElement;
private ContentSizeFitter contentSizeFitter;
private RectTransform rectransform;
public bool controllWidth;
public bool controllHeight;
public float maxHight;
public float maxWidth;
void Start()
{
layoutElement = GetComponent<LayoutElement>();
rectransform = GetComponent<RectTransform>();
}
public void Update()
{
if(rectransform.hasChanged)
{
rectransform.hasChanged = false;
if (controllHeight)
{
layoutElement.preferredHeight = -1;
layoutElement.CalculateLayoutInputHorizontal();
layoutElement.CalculateLayoutInputVertical();
if (rectransform.rect.height >= maxHight)
{
layoutElement.preferredHeight = maxHight;
}
}
if (controllWidth)
{
if (rectransform.rect.height >= maxWidth)
{
layoutElement.preferredWidth = maxWidth;
}
else
{
layoutElement.preferredWidth = -1;
}
}
}
}}
但它不是完整的提交我的要求plz看看它..
答案 0 :(得分:3)
我知道这是一个老问题,但我一直在寻找类似的东西,我最终重写了你的课程,现在它对我来说很好。我没有再创建另一个MonoBehaviour而是覆盖了LayoutElement,而且还添加了一个自定义检查器,以便于编辑它。希望我的解决方案可以帮助你或任何想要这样的人。
using UnityEngine;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif
[RequireComponent(typeof(RectTransform))]
[System.Serializable]
public class LayoutMaxSize : LayoutElement
{
public float maxHeight = -1;
public float maxWidth = -1;
public override void CalculateLayoutInputHorizontal()
{
base.CalculateLayoutInputHorizontal();
UpdateMaxSizes();
}
public override void CalculateLayoutInputVertical()
{
base.CalculateLayoutInputVertical();
UpdateMaxSizes();
}
protected override void OnRectTransformDimensionsChange()
{
base.OnRectTransformDimensionsChange();
UpdateMaxSizes();
}
protected override void OnValidate()
{
base.OnValidate();
UpdateMaxSizes();
}
private void UpdateMaxSizes()
{
if (maxHeight != -1)
{
if (preferredHeight == -1 && maxHeight < GetComponent<RectTransform>().sizeDelta.y)
{
preferredHeight = maxHeight;
}
else if (preferredHeight != -1 && transform.childCount > 0)
{
bool first = true;
float biggestY = 0;
float lowestY = 0;
for (int i = 0; i < transform.childCount; i++)
{
var childrenTransform = transform.GetChild(i).GetComponent<RectTransform>();
if (childrenTransform == null) continue;
var childPos = childrenTransform.localPosition;
var childSize = childrenTransform.sizeDelta;
var childPivot = childrenTransform.pivot;
if(first)
{
biggestY = childPos.y + (childSize.y * (1f - childPivot.y));
lowestY = childPos.y - (childSize.y * childPivot.y);
}
else
{
biggestY = Mathf.Max(biggestY, childPos.y + (childSize.y * (1f - childPivot.y)));
lowestY = Mathf.Min(lowestY, childPos.y - (childSize.y * childPivot.y));
}
first = false;
}
if (first) return;
var childrenYSize = Mathf.Abs(biggestY - lowestY);
if(preferredHeight > childrenYSize)
{
preferredHeight = -1;
}
}
}
if (maxWidth != -1)
{
if (preferredWidth == -1 && maxWidth < GetComponent<RectTransform>().sizeDelta.x)
{
preferredWidth = maxWidth;
}
else if (preferredWidth != -1 && transform.childCount > 0)
{
bool first = true;
float biggestX = 0;
float lowestX = 0;
for (int i = 0; i < transform.childCount; i++)
{
var childrenTransform = transform.GetChild(i).GetComponent<RectTransform>();
if (childrenTransform == null) continue;
var childPos = childrenTransform.localPosition;
var childSize = childrenTransform.sizeDelta;
var childPivot = childrenTransform.pivot;
if (first)
{
biggestX = childPos.x + (childSize.x * (1f - childPivot.x));
lowestX = childPos.x - (childSize.x * childPivot.x);
}
else
{
biggestX = Mathf.Max(biggestX, childPos.x + (childSize.x * (1f - childPivot.x)));
lowestX = Mathf.Min(lowestX, childPos.x - (childSize.x * childPivot.x));
}
first = false;
}
if (first) return;
var childrenXSize = Mathf.Abs(biggestX - lowestX);
if (preferredWidth > childrenXSize)
{
preferredWidth = -1;
}
}
}
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(LayoutMaxSize))]
public class LayoutMaxSizeEditor : Editor
{
public override void OnInspectorGUI()
{
LayoutMaxSize layoutMax = target as LayoutMaxSize;
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Ignore Layout");
layoutMax.ignoreLayout = EditorGUILayout.Toggle(layoutMax.ignoreLayout);
EditorGUILayout.EndHorizontal();
if (!layoutMax.ignoreLayout)
{
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Min Width");
var allowMinWidth = EditorGUILayout.Toggle(layoutMax.minWidth != -1);
if (allowMinWidth)
{
if (layoutMax.minWidth == -1) layoutMax.minWidth = 0;
layoutMax.minWidth = EditorGUILayout.FloatField(layoutMax.minWidth);
}
else if (layoutMax.minWidth != -1)
{
layoutMax.minWidth = -1;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Min Height");
var allowMinHeight = EditorGUILayout.Toggle(layoutMax.minHeight != -1);
if (allowMinHeight)
{
if (layoutMax.minHeight == -1) layoutMax.minHeight = 0;
layoutMax.minHeight = EditorGUILayout.FloatField(layoutMax.minHeight);
}
else if (layoutMax.minHeight != -1)
{
layoutMax.minHeight = -1;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Max Width");
var allowMaxWidth = EditorGUILayout.Toggle(layoutMax.maxWidth != -1);
if (allowMaxWidth)
{
if (layoutMax.maxWidth == -1) layoutMax.maxWidth = Mathf.Max(0, layoutMax.minWidth);
layoutMax.maxWidth = Mathf.Max(EditorGUILayout.FloatField(layoutMax.maxWidth), layoutMax.minWidth);
}
else if(layoutMax.maxWidth != -1)
{
layoutMax.maxWidth = -1;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Max Height");
var allowMaxHeight = EditorGUILayout.Toggle(layoutMax.maxHeight != -1);
if (allowMaxHeight)
{
if (layoutMax.maxHeight == -1) layoutMax.maxHeight = Mathf.Max(0, layoutMax.minHeight);
layoutMax.maxHeight = Mathf.Max(EditorGUILayout.FloatField(layoutMax.maxHeight), layoutMax.minHeight);
}
else if (layoutMax.maxHeight != -1)
{
layoutMax.maxHeight = -1;
}
EditorGUILayout.EndHorizontal();
}
}
}
#endif
答案 1 :(得分:0)
我编写了一个新脚本,其中包括布局元素的maxheight和maxwidth字段,尚未经过充分测试,但是如果您愿意,可以使用它。
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.UI;
#endif
[RequireComponent(typeof(RectTransform))]
[System.Serializable]
public class LayoutElementWithMaxValues : LayoutElement {
public float maxHeight;
public float maxWidth;
public bool useMaxWidth;
public bool useMaxHeight;
bool ignoreOnGettingPreferedSize;
public override int layoutPriority {
get => ignoreOnGettingPreferedSize ? -1 : base.layoutPriority;
set => base.layoutPriority = value; }
public override float preferredHeight {
get {
if (useMaxHeight) {
var defaultIgnoreValue = ignoreOnGettingPreferedSize;
ignoreOnGettingPreferedSize = true;
var baseValue = LayoutUtility.GetPreferredHeight(transform as RectTransform);
ignoreOnGettingPreferedSize = defaultIgnoreValue;
return baseValue > maxHeight ? maxHeight : baseValue;
}
else
return base.preferredHeight;
}
set => base.preferredHeight = value;
}
public override float preferredWidth {
get {
if (useMaxWidth) {
var defaultIgnoreValue = ignoreOnGettingPreferedSize;
ignoreOnGettingPreferedSize = true;
var baseValue = LayoutUtility.GetPreferredWidth(transform as RectTransform);
ignoreOnGettingPreferedSize = defaultIgnoreValue;
return baseValue > maxWidth ? maxWidth : baseValue;
}
else
return base.preferredWidth;
}
set => base.preferredWidth = value;
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(LayoutElementWithMaxValues), true)]
[CanEditMultipleObjects]
public class LayoutMaxSizeEditor : LayoutElementEditor {
LayoutElementWithMaxValues layoutMax;
SerializedProperty maxHeightProperty;
SerializedProperty maxWidthProperty;
SerializedProperty useMaxHeightProperty;
SerializedProperty useMaxWidthProperty;
RectTransform myRectTransform;
protected override void OnEnable() {
base.OnEnable();
layoutMax = target as LayoutElementWithMaxValues;
myRectTransform = layoutMax.transform as RectTransform;
maxHeightProperty = serializedObject.FindProperty(nameof(layoutMax.maxHeight));
maxWidthProperty = serializedObject.FindProperty(nameof(layoutMax.maxWidth));
useMaxHeightProperty = serializedObject.FindProperty(nameof(layoutMax.useMaxHeight));
useMaxWidthProperty = serializedObject.FindProperty(nameof(layoutMax.useMaxWidth));
}
public override void OnInspectorGUI() {
Draw(maxWidthProperty, useMaxWidthProperty);
Draw(maxHeightProperty, useMaxHeightProperty);
serializedObject.ApplyModifiedProperties();
EditorGUILayout.Space();
base.OnInspectorGUI();
}
void Draw(SerializedProperty property, SerializedProperty useProperty) {
Rect position = EditorGUILayout.GetControlRect();
GUIContent label = EditorGUI.BeginProperty(position, null, property);
Rect fieldPosition = EditorGUI.PrefixLabel(position, label);
Rect toggleRect = fieldPosition;
toggleRect.width = 16;
Rect floatFieldRect = fieldPosition;
floatFieldRect.xMin += 16;
var use = EditorGUI.Toggle(toggleRect, useProperty.boolValue);
useProperty.boolValue = use;
if (use) {
EditorGUIUtility.labelWidth = 4;
property.floatValue = EditorGUI.FloatField(floatFieldRect, new GUIContent(" "), property.floatValue);
EditorGUIUtility.labelWidth = 0;
}
EditorGUI.EndProperty();
}
}
#endif