簡體   English   中英

獲取UI文本元素的高度不正確Unity

[英]Get height of UI text element not correct Unity

我有一些代碼為文本元素設置自定義,然后自動調整高度,如下所示:

Title.SetTextContainerSize("autoH", 330);

public void SetTextContainerSize(string fit, float dimension = 0)
    {
        if (UIElement.GetComponent<ContentSizeFitter>() == null)
            UISizeFitterComponent = UIElement.AddComponent(typeof(ContentSizeFitter)) as ContentSizeFitter;

        if (fit == "autoWH")
        {
            UISizeFitterComponent.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
            UISizeFitterComponent.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
            base.SetDimensions( RectOptions.sizeDelta);
        }
        else if (fit == "autoW")
        {
            UISizeFitterComponent.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
            base.SetDimensions( new Vector2(RectOptions.rect.width, dimension));
        }
        else if (fit == "autoH")
        { //here is a problem.. 
            UISizeFitterComponent.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
            Canvas.ForceUpdateCanvases();
            Debug.Log(new Vector2(dimension, RectOptions.rect.height));
            base.SetDimensions( new Vector2(dimension, RectOptions.rect.height));
        }
    }

編輯添加了設置尺寸功能

public void SetDimensions(Vector2 dimensions)
    {
        RectOptions.sizeDelta = dimensions;
        Dimensions = dimensions; //this just sets the value of a property. 
    }

但是當我調用函數來更新文本時,我從Debug.Log()得到以下結果,它表示寬度= 330,高度是2077.在這種情況下,寬度是正確的,但高度甚至不接近。

在這里查看實際元素及其正確高度的屏幕截圖。 在此輸入圖像描述

編輯2我的統一版本是2018.1.3f1

更新元素的實際高度時我做錯了什么?

如果還有其他方法可以做到這一點,我也可以完全重寫當前函數,如果有的話:)

如果有什么不清楚讓我知道所以我可以澄清!

編輯3我決定添加使用函數的類的完整代碼和調用相應函數的代碼,可能存在導致錯誤的問題:

這是調用problametic函數的代碼:

var Title = new EasyText(new Vector2(390, -20), Vector2.zero, Data.title, 30, _color: new Color(0,0,0,1));
Title.SetTextContainerSize("autoH", 330);
Main.MainCanvas.Add(Title);

var titleBottom = (Title.Dimensions.y);
Debug.Log(titleBottom);

這是上面代碼調用的類:

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections.Generic;

namespace Easy.UI
{

    public static class EasyUISettings
    {
        public struct AnchorPoints
        {
            public static readonly Vector2 TopLeft = new Vector2(0, 1);
            public static readonly Vector2 Center = new Vector2(0.5f, 0.5f);
            public static readonly Vector2 CenterLeft = new Vector2(0, 0.5f);
            public static readonly Vector2 CenterRight = new Vector2(1, 0.5f);
            public static readonly Vector2 TopCenter = new Vector2(0.5f, 1);
            public static readonly Vector2 BottomCenter = new Vector2(0.5f, 0);
        }

        public struct CoordinateReference
        {
            private CoordinateReference(int minX, int maxX, int minY, int maxY)
            {
                AnchorMin = new Vector2(minX, minY);
                AnchorMax = new Vector2(maxX, maxY);
            }

            public Vector2 AnchorMin { get; set; }
            public Vector2 AnchorMax { get; set; }

            public static readonly CoordinateReference TopLeft = new CoordinateReference(0, 0, 1, 1);
            public static readonly CoordinateReference TopRight = new CoordinateReference(1, 1, 1, 1);
            public static readonly CoordinateReference BottomLeft = new CoordinateReference(0, 0, 0, 0);
            public static readonly CoordinateReference BottomRight = new CoordinateReference(1, 1, 0, 0);

        }

        public struct TextAlignment
        {
            public static readonly TextAnchor TopLeft = TextAnchor.UpperLeft;
            public static readonly TextAnchor TopRight = TextAnchor.UpperRight;
            public static readonly TextAnchor TopCenter = TextAnchor.UpperCenter;
            public static readonly TextAnchor CenterLeft = TextAnchor.MiddleLeft;
            public static readonly TextAnchor CenterRight = TextAnchor.MiddleRight;
            public static readonly TextAnchor CenterCenter = TextAnchor.MiddleCenter;
            public static readonly TextAnchor BottomLeft = TextAnchor.LowerLeft;
            public static readonly TextAnchor BottomCenter = TextAnchor.LowerCenter;
            public static readonly TextAnchor BottomRight = TextAnchor.LowerRight;
        }
    }

    public static class EasyUIHelpers
    {
        public static void DestroyUIElement(EasyUIELementFoundation element)
        {
            element.DestroyUIElement();
            element = null;
        }
    }

    public class EasyCanvas
    {

        private GameObject CanvasObject, Events;
        private RectTransform Rect;
        private Canvas CanvasScript;
        private CanvasScaler Scaler;
        private GraphicRaycaster Raycaster;
        private StandaloneInputModule Inputs;
        private List<EasyUIELementFoundation> CanvasElements;

        public EasyCanvas()
        {
            CanvasElements = new List<EasyUIELementFoundation>();

            CanvasObject = new GameObject();
            CanvasObject.name = "EasyCanvas";
            Rect = CanvasObject.AddComponent(typeof(RectTransform)) as RectTransform;
            CanvasScript = CanvasObject.AddComponent(typeof(Canvas)) as Canvas;
            Scaler = CanvasObject.AddComponent(typeof(CanvasScaler)) as CanvasScaler;
            Raycaster = CanvasObject.AddComponent(typeof(GraphicRaycaster)) as GraphicRaycaster;

            CanvasScript.pixelPerfect = true;

            Events = new GameObject();
            Events.name = "EasyEventsHandler";
            Events.AddComponent(typeof(EventSystem));
            Inputs = Events.AddComponent(typeof(StandaloneInputModule)) as StandaloneInputModule;
        }

        public EasyCanvas(string _type, Camera c) : this()
        {
            CanvasScript.worldCamera = c;
            CanvasScript.planeDistance = 0.15f;

            if (_type.Equals("Camera"))
            {
                CanvasScript.renderMode = RenderMode.ScreenSpaceCamera;
                Scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
                Scaler.referenceResolution = new Vector2(1920, 1080);
                Scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
            }
            else if(_type.Equals("World"))
                CanvasScript.renderMode = RenderMode.WorldSpace;
        }

        public void Add(EasyUIELementFoundation element)
        {
            element.AddToCanvas(CanvasScript);
            CanvasElements.Add(element);
        }

        public void EmptyCanvas()
        {
            for (int i = CanvasElements.Count - 1; i >= 0 ; i--)
            {
                CanvasElements[i].DestroyUIElement();
                CanvasElements[i] = null;
                CanvasElements.RemoveAt(i);
            }
        }

        public Vector2 GetCanvasDimensions()
        {
            return Rect.sizeDelta;
        }
    }

    public abstract class EasyUIELementFoundation
    {
        protected GameObject UIElement;
        protected RectTransform RectOptions;
        public Vector2 Position { get; private set; }
        public Vector2 Dimensions { get; private set; }
        public Vector2 PivotPoint { get; private set; }
        public EasyUISettings.CoordinateReference ReferenceCoordinates { get; private set; }

        protected EasyUIELementFoundation(Vector2 _position, Vector2 _dimensions)
        {
            UIElement = new GameObject();
            RectOptions = UIElement.AddComponent(typeof(RectTransform)) as RectTransform;
            SetPivotReference(EasyUISettings.AnchorPoints.TopLeft);
            SetCoordinateReference(EasyUISettings.CoordinateReference.TopLeft);
            SetPosition(_position);
            SetDimensions(_dimensions);
        }

        public void SetCoordinateReference(EasyUISettings.CoordinateReference reference)
        {
            RectOptions.anchorMin = reference.AnchorMin;
            RectOptions.anchorMax = reference.AnchorMax;
            ReferenceCoordinates = reference;
        }

        public void SetPivotReference(Vector2 reference)
        {
            RectOptions.pivot = reference;
            PivotPoint = reference;
        }

        public void SetPosition(Vector2 pos)
        {
            RectOptions.anchoredPosition = pos;
            Position = pos;
        }

        public void SetDimensions(Vector2 dimensions)
        {
            RectOptions.sizeDelta = dimensions;
            Dimensions = dimensions;
        }

        public void AddToCanvas(Canvas c)
        {
            UIElement.transform.SetParent(c.transform, false);
        }

        public void DestroyUIElement()
        {
            Object.Destroy(UIElement);
        }
    }

    public class EasyText : EasyUIELementFoundation
    {
        protected ContentSizeFitter UISizeFitterComponent;
        protected Text UITextComponent;
        public string Text { get; private set; }
        public Color TextColor { get; private set; }
        public Font TextFont { get; private set; }
        public int FontSize { get; private set; }
        public TextAnchor TextAlignment { get; private set; }

        public EasyText(Vector2 _position = default(Vector2), Vector2 _dimensions = default(Vector2), string _text = "Base Text", int _fontSize = 15, Font _font = null, Color _color = default(Color), TextAnchor _align = default(TextAnchor)) : base(_position, _dimensions)
        {
            UITextComponent = UIElement.AddComponent(typeof(Text)) as Text;
            SetText(_text);
            SetTextSize(_fontSize);
            SetFont(_font);
            SetTextColor(_color);
            SetTextAlignment(_align);
        }

        public void SetText(string text)
        {
            Text = text;
            UITextComponent.text = Text;
        }

        public void SetTextSize(int size)
        {
            FontSize = size;
            UITextComponent.fontSize = size;
        }

        public void SetFont(UnityEngine.Object font)
        {
            var ValidFont = (Font)font;
            if(ValidFont != null)
            {
                TextFont = ValidFont;
                UITextComponent.font = TextFont;
            }
            else
            {
                TextFont = Resources.GetBuiltinResource(typeof(Font), "Arial.ttf") as Font;
                UITextComponent.font = TextFont;
                Debug.LogWarning("No font was specified using default font");
            }
        }

        public void SetTextColor(Color color)
        {
            TextColor = color;
            UITextComponent.color = TextColor;
        }

        public void SetTextAlignment(TextAnchor alignment)
        {
            TextAlignment = alignment;
            UITextComponent.alignment = alignment;
        }

        public void SetTextContainerSize(string fit, float dimension = 0)
        {
            if (UIElement.GetComponent<ContentSizeFitter>() == null)
                UISizeFitterComponent = UIElement.AddComponent(typeof(ContentSizeFitter)) as ContentSizeFitter;

            if (fit == "autoWH")
            {
                UISizeFitterComponent.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
                UISizeFitterComponent.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
                base.SetDimensions( RectOptions.sizeDelta);
            }
            else if (fit == "autoW")
            {
                UISizeFitterComponent.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
                UISizeFitterComponent.verticalFit = ContentSizeFitter.FitMode.Unconstrained;
                base.SetDimensions( new Vector2(RectOptions.rect.width, dimension));
            }
            else if (fit == "autoH")
            {
                UISizeFitterComponent.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
                UISizeFitterComponent.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
                // THIS NEEDS A FIX OMG
                // LayoutRebuilder.ForceRebuildLayoutImmediate(RectOptions);
                Canvas.ForceUpdateCanvases();
                UISizeFitterComponent.SetLayoutVertical();
                base.SetDimensions( new Vector2(dimension, RectOptions.rect.height));
            }
        }

        public void RemoveContentSizeFitter()
        {
            var component = UIElement.GetComponent(typeof(ContentSizeFitter)) as ContentSizeFitter;
            if(component != null)
                Object.Destroy(component);
        }
    }
}

花了幾個小時試圖找到解決方案我終於找到了..

這實際上是一個非常愚蠢的錯誤。

這是一個解釋:

我通過以下方式啟動了自定義UIText類:

var Title = new EasyText(new Vector2(390, -20), Vector2.zero, Data.title, 30, _color: new Color(0,0,0,1));

注意Vector.zero的文本元素的尺寸? 是的,這會引起一些問題。

因為以下我做的是在剛剛創建的title元素上調用它:

Title.SetTextContainerSize("autoH", 330);

這會調用我的尺寸鉗工更新功能,見下圖:

public void SetTextContainerSize(string fit, float dimension = 0)
    {
        if (UIElement.GetComponent<ContentSizeFitter>() == null)
            UISizeFitterComponent = UIElement.AddComponent(typeof(ContentSizeFitter)) as ContentSizeFitter;

        if (fit == "autoWH")
        {
            UISizeFitterComponent.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
            UISizeFitterComponent.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
            base.SetDimensions( RectOptions.sizeDelta);
        }
        else if (fit == "autoW")
        {
            UISizeFitterComponent.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
            UISizeFitterComponent.verticalFit = ContentSizeFitter.FitMode.Unconstrained;
            Canvas.ForceUpdateCanvases();
            base.SetDimensions( new Vector2(RectOptions.rect.width, dimension));
        }
        else if (fit == "autoH")
        {
            UISizeFitterComponent.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
            UISizeFitterComponent.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
            Canvas.ForceUpdateCanvases();
            base.SetDimensions( new Vector2(dimension, RectOptions.rect.height));
        }
    }

在擬合值為autoW或autoH的情況下,程序將添加內容大小fitter,但由於初始化,因為元素的大小為0。 內容大小適配器將元素擴展到極端,因為另一個大小只是0.然后我更新畫布但這沒有做任何事情因為元素的寬度或高度為0.導致獲取值時的巨大數字背部。 那么如何解決這個問題呢?

在添加內容大小適配器之前,只需確保元素有一些寬度或高度,如下所示:

public void SetTextContainerSize(string fit, float dimension = 0)
    {
        if (UIElement.GetComponent<ContentSizeFitter>() == null)
            UISizeFitterComponent = UIElement.AddComponent(typeof(ContentSizeFitter)) as ContentSizeFitter;

        if (fit == "autoWH")
        {
            UISizeFitterComponent.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
            UISizeFitterComponent.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
        }
        else if (fit == "autoW")
        {
            base.SetDimensions(new Vector2(dimension, dimension));
            UISizeFitterComponent.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
            UISizeFitterComponent.verticalFit = ContentSizeFitter.FitMode.Unconstrained;
            Canvas.ForceUpdateCanvases();
            base.SetDimensions( new Vector2(RectOptions.rect.width, dimension));
        }
        else if (fit == "autoH")
        {
            base.SetDimensions(new Vector2(dimension, dimension));
            UISizeFitterComponent.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
            UISizeFitterComponent.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
            Canvas.ForceUpdateCanvases();
            base.SetDimensions( new Vector2(dimension, RectOptions.rect.height));
        }
    }

這解決了我的問題。 我真的希望這有助於將來的任何人!
如果你什么都不懂,請發表評論,以便澄清我的答案:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM