最近公司有个项目正好要实现文字打字机的功能,按照惯例习惯性在网上搜索文字打字机是啥玩意,一般在显示游戏剧情文字内容的时候用到,然后发现大多数都是控制Text组件的字符串实现的。
所以我就尝试通过修改顶点数方法,来控制显示出来的字。
由于一个Unity里面的字,是由两个三角形组成的正方形,每个三角形各拥有3个顶点,那么一个字就拥有左三角形的3个顶点和右三角形的3个顶点,那么一个字的UIVertex个数就是6个,那么每次要显示的时候,要显示的字 = 要显示的字的个数 x 每个字的UIVertex个数(6个)。
这里引用此链接http://blog.sqstudio.com/?p=1270的一张图来解释三角形和UIVertex索引的对应关系。
每个字母 分为两个三角形,6个UIVertex,如下图 0和5位置相同 2和3位置相同
/**
* 5-0 ---- 1
* | \ |
* | \ |
* | \ |
* | \ |
* 4-----3-2
**/
原理是通过GetUIVertexStream来获取顶点,然后在SetTextVertex中修改获取到的顶点数,再刷新顶点。
在每次更新时调用SetVerticesDirty标记顶点为脏(即修改了顶点),来强制渲染,达到控制渲染时机的目的。
代码贴在这里,复制粘贴改个和文件名一样的类名,挂在带Text组件的GameObject上就能使用,测试环境是unity 5.6.2,如有错误请指正。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/*
* 功能:文字打字机
*/
public class TweenString : BaseMeshEffect
{
//用于记录当前到了哪个字
private int m_Num = 0;
//记录刷新时间
private float m_TimeCount = 0;
//是否开始显示打字
private bool isStartShow = false;
//要显示的字符串
private string m_ShowString = "";
//每个字的出现间隔
private float m_TimeSpace = 0;
//要显示的Text组件
private Text m_Text;
/*
初始化信息
*/
protected override void Awake()
{
InitTweenStringInfo();
m_Text = gameObject.GetComponent<Text>();
m_Text.text = m_ShowString;
}
/*
调用 StartTweenString开始显示"哈哈哈哈",每个文字间隔0.5s
*/
protected override void Start()
{
StartTweenString("哈哈哈哈",0.5f);
}
/*
在打字状态时,每个时间间隔更新一次
*/
void Update () {
if (isStartShow)
{
if (Time.time - m_TimeCount > m_TimeSpace)
{
m_TimeCount = Time.time;
if (m_Num < m_ShowString.Length)
{
m_Num++;
}
else
{
m_Num = m_ShowString.Length;
isStartShow = false;
}
graphic.SetVerticesDirty();
}
}
}
/*
重写ModifyMesh方法,更新文字顶点
*/
public override void ModifyMesh(VertexHelper vh)
{
if (!IsActive())
return;
List<UIVertex> vertexList = new List<UIVertex>();
vh.GetUIVertexStream(vertexList);
vertexList = SetTextVertex(vertexList);
vh.Clear();
vh.AddUIVertexTriangleStream(vertexList);
}
/*
设置要显示的文字的顶点
*/
private List<UIVertex> SetTextVertex(List<UIVertex> vertexList)
{
List<UIVertex> tmpVertexList = new List<UIVertex>();
int count = m_Num * 6;
count = Mathf.Min(vertexList.Count, count);
for (int i = 0; i < count; i++)
{
tmpVertexList.Add(vertexList[i]);
}
return tmpVertexList;
}
/*
初始化打字信息
*/
private void InitTweenStringInfo()
{
m_TimeCount = Time.time;
m_Num = 0;
m_ShowString = "";
}
/*
开始打字
参数:str:要显示的文字内容
time:要显示的时间间隔
*/
public void StartTweenString(string str,float time)
{
InitTweenStringInfo();
isStartShow = true;
m_TimeSpace = time;
m_ShowString = str;
m_Text.text = m_ShowString;
}
/*
停止打字
*/
public void StopTweenString()
{
isStartShow = false;
}
}
网友评论