unity实现文本打字机效果(支持富文本)

一.效果图:

二.代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;

public class CommonStoryText : BaseMeshEffect
{
    [SerializeField]
    private int textIndex;

    private UIVertex vertex = new UIVertex();

    //记录刷新时间
    private float m_TimeCount = 0;

    private float m_charTime = 0;

    //是否开始显示打字
    private int state = 0;

    //每个字的出现间隔
    private float m_TimeSpace = 0;

    //要显示的Text组件
    private Text m_Text;

    private int alphaIndex = 0;

    private float[] arrVertex;

    private int aniComplete = 0;
    private int m_charLen = 0;
    private int hasInit = 0;

    public override void ModifyMesh(VertexHelper vh)
    {
        if (!IsActive())
        {
            return;
        }
        if(state == 0)
        {
            return;
        }
        m_charLen = vh.currentVertCount/4;
        //文本长度
        if(state == 1)
        {
            for (var i = 0; i < vh.currentVertCount; i++)
            {
                vh.PopulateUIVertex(ref vertex, i);
                Color c = vertex.color;
                c.a = 0;
                vertex.color = c;
                vh.SetUIVertex(vertex, i);
            }
            state = 2;
            return;
        }
        int vCount = 4;
        int vertexIndex = 0;
        int charLen = m_charLen;
        for(int i=0; i<charLen; i++)
        {
            float alpha = arrVertex[i];
            for (int j = 0; j < vCount; j++)
            {
                if (vertexIndex < vh.currentVertCount)
                {
                    vh.PopulateUIVertex(ref vertex, vertexIndex);
                    Color c = vertex.color;
                    c.a = alpha;
                    vertex.color = c;
                    vh.SetUIVertex(vertex, vertexIndex);
                }
                vertexIndex++;
            }
        }
        if(alphaIndex >= charLen && state > 0)
        {
            state = 0;
            aniComplete = 1;
        }

    }
    protected override void Awake()
    {
        m_Text = gameObject.GetComponent<Text>();
        textIndex = 0;
        m_Text.text = "";
    }
    protected override  void Start()
    {
    }
    void Update ()
    {
        if (state == 2)
        {
            if(hasInit == 0)
            {
                hasInit = 1;
                arrVertex = new float[m_charLen];
                for(int i=0; i<m_charLen; i++)
                {
                    arrVertex[i] = 0;
                }
            }
            doText();
            doAlphaText();
        }
        if(aniComplete == 1)
        {
            aniComplete = 0;
            onTextAniComplete();
        }
    }
    private void doText()
    {
        int charLen = m_charLen;
        if(textIndex >= charLen)
        {
            return;
        }
        if (Time.time - m_charTime > 0.05)
        {
            m_charTime = Time.time;
            textIndex++;
        }
    }
    private void doAlphaText()
    {
        if (Time.time - m_TimeCount <= 0.01)
        {
            return;
        }
        m_TimeCount = Time.time;
        int charLen = m_charLen;
        bool needModify = false;
        for(int i=alphaIndex; i<textIndex && i<charLen; i++)
        {
            float alpha = arrVertex[i];
            alpha += 0.1f;
            needModify = true;
            if(alpha >= 1)
            {
                alphaIndex++;
                alpha = 1;
            }
            arrVertex[i] = alpha;
        }
        if(needModify)
        {
            graphic.SetVerticesDirty();
        }
    }
    public void playAni(string contents)
    {
        if(state > 0)
        {
            return;
        }
        m_Text.text = contents;
        hasInit = 0;
        alphaIndex = 0;
        state = 1;
        textIndex = 0;
        graphic.SetVerticesDirty();
    }
    public void stopAni()
    {
        state = 0;
    }
    public void showText()
    {
        if(hasInit == 0)
        {
            return;
        }
        alphaIndex = m_charLen;
        textIndex = m_charLen;
        for(int i=0; i<m_charLen; i++)
        {
            arrVertex[i] = 1.0f;
        }
        graphic.SetVerticesDirty();
    }
    private void onTextAniComplete()
    {

    }
    public void test()
    {
        playAni("这是一段剧情对话,<color=#FF0000>尽量长一点</color>方便测试.");
    }
}

三.新建一个unity工程 创建ui text节点 添加上面的脚本 代码里调用playAni接口.

posted @ 2021-01-14 15:55  wssw  阅读(1762)  评论(3编辑  收藏  举报