項目中碰到文字超過顯示區(qū)域的情況,Unity UGUI沒有類似css的自動省略號,產(chǎn)品希望能展示全,考慮可以做個滾動文字的組件。
目前實現(xiàn)兩種滾動方式:來回滾動和從左到右再回到最左邊,都是循環(huán)滾動,邏輯不復雜,參考代碼。
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(Mask))]
[RequireComponent(typeof(Image))]
public class AutoRollText : MonoBehaviour
{
public enum RollType
{
Pingpong = 0,
Left = 1
}
public RollType rollType = RollType.Pingpong;
public Text m_text;
[Header("延遲時間")] public float delay = 5f;
[Header("移動速度")] public float speed = .1f;
[Header("邊界檢測允許差值")] public float limitDiff = 5f;
private float _textWidth;
private RectTransform _rect;
public string text
{
set
{
m_text.text = value;
CalcTextPos();
}
get { return m_text.text; }
}
private void Awake()
{
_rect = this.transform as RectTransform;
if (m_text == null)
{
m_text = this.GetComponentInChildren<Text>(true);
}
m_text.rectTransform.pivot = new Vector2(0, 0.5f);
// m_text.rectTransform.anchoredPosition = new Vector2(-_rect.sizeDelta.x / 2, 0);
CalcTextPos();
}
private void CalcTextPos()
{
// 根據(jù)字數(shù) 調(diào)整 view 寬度
TextGenerator generator = new TextGenerator();
TextGenerationSettings settings = m_text.GetGenerationSettings(Vector2.zero);
_textWidth = generator.GetPreferredWidth(text, settings);
Vector2 size = m_text.rectTransform.sizeDelta;
size.x = _textWidth;
m_text.rectTransform.sizeDelta = size;
Vector2 pos = new Vector2(-size.x / 2, 0);
pos.x += (_textWidth - _rect.sizeDelta.x) / 2f;
Debug.Log($"textWidth:{_textWidth}-----width:{_rect.sizeDelta.x}-----pos:{pos}");
m_text.rectTransform.anchoredPosition = pos;
StopCoroutine(nameof(RollCoroutine));
if (_textWidth > _rect.sizeDelta.x) //文字超出大小
{
StartCoroutine(nameof(RollCoroutine));
}
}
private IEnumerator RollCoroutine()
{
Vector2 pos = m_text.rectTransform.anchoredPosition;
Vector2 current = pos;
float offset = _textWidth - _rect.sizeDelta.x;
if (delay > 0)
{
yield return new WaitForSeconds(delay);
}
switch (rollType)
{
case RollType.Pingpong:
{
bool leftDir = true;
while (true)
{
if (leftDir)
{
current.x -= speed;
}
else
{
current.x += speed;
}
m_text.rectTransform.anchoredPosition = current;
if (current.x < (pos.x - offset - limitDiff))
{
leftDir = false;
}
else if (current.x >= pos.x + limitDiff)
{
leftDir = true;
}
yield return null;
}
}
break;
case RollType.Left:
{
while (true)
{
current.x -= speed;
m_text.rectTransform.anchoredPosition = current;
yield return null;
if (current.x < (pos.x - offset - limitDiff))
{
yield return new WaitForSeconds(delay);
current.x = pos.x;
m_text.rectTransform.anchoredPosition = current;
if (delay > 0)
{
yield return new WaitForSeconds(delay);
}
}
}
}
break;
}
}
}
組件分為兩層結(jié)構(gòu),父層是一個mask,移動出去的文字超出顯示區(qū)域不顯示,子層是文字,如下:
文字顯示的區(qū)域為父層RectTransform的Size。
參考工程:https://github.com/eangulee/CustomUGUI.git