Unity UGUI通过修改顶点实现文字打字机

2018-11-18  本文已影响0人  狐度计算

最近公司有个项目正好要实现文字打字机的功能,按照惯例习惯性在网上搜索文字打字机是啥玩意,一般在显示游戏剧情文字内容的时候用到,然后发现大多数都是控制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;

    }

}
上一篇 下一篇

猜你喜欢

热点阅读