using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof(Text))]
public class TextScroller: MonoBehaviour
{
    [Header("基本设置")]
    [SerializeField] private float scrollSpeed = 30f;
    [SerializeField] private float padding = 20f;
    [SerializeField] private float pauseDuration = 1f;
    [SerializeField] private RectTransform parentContainer;
    
    [Header("调试信息")]
    [SerializeField] private bool isScrolling;
    [SerializeField] private bool isPaused;
    [SerializeField] private float scrollRange;
    [SerializeField] private float currentPosition;
    
    private Text textComponent;
    private RectTransform textRectTransform;
    private Vector3 initialPosition;
    private float scrollLimit;
    private float pauseTimer;
    private Direction currentDirection = Direction.Left; // 初始向左滚动

    private enum Direction { Left, Right }

    private void Awake()
    {
        textComponent = GetComponent<Text>();
        textRectTransform = textComponent.GetComponent<RectTransform>();
        initialPosition = textRectTransform.localPosition;
    }

    private void Start()
    {
        UpdateTextWidth();
        CalculateScrollRange();
    }

    private void Update()
    {
        if (!isScrolling) return;

        if (isPaused)
        {
            pauseTimer += Time.deltaTime;
            if (pauseTimer >= pauseDuration)
            {
                isPaused = false;
                ReverseDirection();
            }
            return;
        }

        // 根据方向滚动
        float movement = scrollSpeed * Time.deltaTime * (currentDirection == Direction.Left ? -1 : 1);
        currentPosition += movement;
        
        // 检查是否到达边界
        if (currentPosition <= -scrollLimit)
        {
            currentPosition = -scrollLimit;
            isPaused = true;
            pauseTimer = 0;
        }
        else if (currentPosition >= scrollLimit)
        {
            currentPosition = scrollLimit;
            isPaused = true;
            pauseTimer = 0;
        }

        // 更新位置
        textRectTransform.localPosition = initialPosition + Vector3.right * currentPosition;
    }

    private void UpdateTextWidth()
    {
        Canvas.ForceUpdateCanvases();
        float preferredWidth = textComponent.preferredWidth;
        textRectTransform.sizeDelta = new Vector2(preferredWidth + padding, textRectTransform.sizeDelta.y);
    }

    private void CalculateScrollRange()
    {
        if (parentContainer == null)
        {
            Debug.LogError("未设置父容器引用!", gameObject);
            return;
        }

        float textWidth = textRectTransform.rect.width;
        float containerWidth = parentContainer.rect.width;
        scrollRange = textWidth - containerWidth;

        // 判断是否需要滚动
        isScrolling = scrollRange > 0;
        
        if (isScrolling)
        {
            scrollLimit = scrollRange / 2f;
            currentPosition = scrollLimit; // 从最右侧开始向左滚动
            textRectTransform.localPosition = initialPosition + Vector3.right * currentPosition;
            Debug.Log($"开始滚动: 文本宽度={textWidth}, 容器宽度={containerWidth}, 滚动范围={scrollRange}", gameObject);
        }
        else
        {
            Debug.Log($"不需要滚动: 文本宽度={textWidth}, 容器宽度={containerWidth}", gameObject);
            textRectTransform.localPosition = initialPosition; // 居中显示
        }
    }

    private void ReverseDirection()
    {
        currentDirection = currentDirection == Direction.Left ? Direction.Right : Direction.Left;
    }

    public void SetText(string newText)
    {
        textComponent.text = newText;
        UpdateTextWidth();
        CalculateScrollRange();
    }

    public void SetScrollSpeed(float newSpeed)
    {
        scrollSpeed = newSpeed;
    }

    public void SetPauseDuration(float newDuration)
    {
        pauseDuration = newDuration;
    }

    public bool IsScrolling()
    {
        return isScrolling;
    }
}    
End

本文标题:Unity下实现Text滚动播放

本文链接:https://www.52unity.cn/archives/21.html

除非另有说明,本作品遵循CC 4.0 BY-SA 版权协议

声明:转载请注明文章来源。

最后修改:2025 年 07 月 28 日
如果觉得我的文章对你有用,请随意赞赏