设计思路
有一个背景,文字从背景图的最右边移动到最左边(移动距离就是背景图宽度+文本宽度)。
使用协程、DOTween实现动画。
前端UI
Hierarchy结构
设置Panel作为背景,任意宽度、高度要求至少完全展示文字(即与字体关联)。添加RectMask2D组件、并新建挂载脚本取名为Marquee。新建Text作为其子物体,并挂载ContentSizeFitter组件,HorizontalFit选择“PreferredSize”。
轴心Pivot设置,Panel的Pivot设置在其右边,如图
Text向右对齐并设置Pivot在左边,如图
解释
Pivot和锚点的设置是为了保证无论Panel和Text如何变化,都会保持Text在Panel的最右边,而且有利于最后计算移动距离。RectMask2D组件是为了形成遮罩效果。ContentSizeFitter是为了动态改变Text宽度。
Marquee脚本
public class MarqueeNew : MonoBehaviour
{
[SerializeField]
private Text msgText;
[SerializeField, LabelText("是否无限循环")]
private bool isLoop;
[SerializeField, LabelText("文字移动速度")]
private float speed;
[SerializeField, LabelText("循环次数")]
private int loopCount;
private RectTransform rect;
/// <summary>存放文字的队列 </summary>
private Queue<string> msgQueue=new Queue<string>();
private void OnValidate()
{
msgText = GetComponentInChildren<Text>();
rect = GetComponent<RectTransform>();
}
void Start()
{
AddMsg("andakda");
StartCoroutine(Scrolling());
}
#region 对外开放的接口(暂时)
public void ClearQueue()
{
msgQueue.Clear();
}
public void AddMsg(string msg)
{
msgQueue.Enqueue(msg);
}
#endregion
private IEnumerator Scrolling()
{
while (msgQueue.Count > 0)
{
msgText.text = "abndadanas";
float width = msgText.preferredWidth;
Vector3 pos = msgText.rectTransform.localPosition;
Debug.Log(pos);
float distance = (rect.rect.width + width);
float duration = distance / speed;
int count = loopCount;
while (isLoop|| count>0)
{
count--;
msgText.rectTransform.localPosition = pos;//new Vector3(0f, pos.y, pos.z);
msgText.rectTransform.DOLocalMoveX(-distance, duration).SetEase(Ease.Linear);
yield return new WaitForSeconds(duration);
}
yield return null;
}
yield break;
}
}
代码“msgText.text = "abndadanas";”需要修改为从msgQueue队列获取元素
拓展
为什么使用RectMask2D而不用Mask?
参考链接
一篇关于Pivot文章
一篇文字跑马灯
(明天再补)