03对话系统---中文字体的显示

在这个路径下找到字体素材

C:\Windows\Fonts

找到需要的字体放到unity中的这个路径下

要转换成字体资源

创建完之后默认为动态字体

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using System.Text.RegularExpressions;
using System;

public class RubyData
{
    public RubyData(int startIndex,string content)
    {
        StartIndex = startIndex;
        RubyContent = content;
        EndIndex = startIndex;
    }

    public int StartIndex { get; }
    public int EndIndex { get; set; }
    public string RubyContent { get; }
}



/// <summary>
/// 增加文本时间停顿功能
/// 增加文字渐出,(单个字符逐渐显现)
/// </summary>

//文本时间停顿功能

//效果:如果使用AdvancedTextPreprocessor的预处理器
//则先经过string ITextPreprocessor.PreprocessText(string text)该方法处理的返回值
//才能显示出来

public class AdvancedTextPreprocessor : ITextPreprocessor
{
    //字典类型,表示在第几个字后面停顿的时间
    public Dictionary<int, float> InterrvalDictionary;
    public List<RubyData> RubyList;

    public AdvancedTextPreprocessor()
    {
        InterrvalDictionary=new Dictionary<int, float>();
        RubyList = new List<RubyData> ();
    }
    public string PreprocessText(string text)
    {
        //清空字典
        InterrvalDictionary.Clear();
        //清空标注
        RubyList.Clear();
        string processingText=text;
        //.:任意字符,*:匹配前面的字符零次或者多次,?:匹配最近的结果
        //*?匹配零次或者多次的那个最短的结果
        string pattern = "<.*?>";
        //输入的字符串+以那种规则去匹配的字符串
       Match match= Regex.Match(processingText,pattern);
       //删掉所有标签
        //如果可以匹配到结果
        while(match.Success)
        {
            string label = match.Value.Substring(1,match.Length - 2);
            //如果能转换为浮点类型则进入if,结果存到 result中
            if (float.TryParse(label,out float result))
            {
                //因为<0.3>前面还有<占一个位置
                InterrvalDictionary[match.Index - 1] = result;
            }
            else if(Regex.IsMatch(label, "^r=.+"))
            {
                RubyList.Add(new RubyData(match.Index,label.Substring(2)));
            }
            else if(label=="/r")
            {
                if(RubyList.Count>0)
                {
                    RubyList[RubyList.Count-1].EndIndex=match.Index-1;
                }
                
            }
            //删掉标签   
            processingText = processingText.Remove(match.Index, match.Length);           
            //^表示必须从字符串的开头进行匹配
            if (Regex.IsMatch(label, "^sprite=.+"))
            {
              
                processingText = processingText.Insert(match.Index, "*");
               // processingText = processingText.Remove(match.Index, match.Length);
            }           
            match = Regex.Match(processingText,pattern);
        }
        //删掉数据标签
        processingText = text;
        //*     代表前一个字符出现零次或多次
        //+     代表前一个字符出现一次或多次
        //?     代表前一个字符出现零次或一次
        //.     代表任意字符
        pattern = @"(<(\d+)(\.\d+)?>)|(</r>)|(<r=.*?>)";
        //processingText中,把所有符合pattern规则的字符替换成"xxx"
        processingText = Regex.Replace(processingText, pattern, "");
        return processingText;
    }
}

public class AdvancedText : TextMeshProUGUI
{
    public AdvancedText()
    {
        //接口类型的预处理器textPreprocessor(可以自己定义预处理效果是什么样的)
        textPreprocessor = new AdvancedTextPreprocessor();
    }
    private AdvancedTextPreprocessor SelfPreprocessor => (AdvancedTextPreprocessor)textPreprocessor;
    public void ShowTextByTyping(string content)
    {
        SetText(content);
        StartCoroutine(Typing());
    }
    private int _typingIndex;
    private float _defaultInterval = 0.06f;

    IEnumerator Typing()
    {
        //强制网格更新
        ForceMeshUpdate();
        for (int i = 0; i < m_characterCount; i++)
        {
            //先把颜色设置成透明
            SetSingleCharacterAlpha(i, 0);
        }
        _typingIndex = 0;
        while (_typingIndex < m_characterCount)
        {
            if (textInfo.characterInfo[_typingIndex].isVisible)
            {
                StartCoroutine(FadeInCharacter(_typingIndex));
            }
            //SetSingleCharacterAlpha(_typingIndex, 255);           
            if (SelfPreprocessor.InterrvalDictionary.TryGetValue(_typingIndex, out float result))
            {
                yield return new WaitForSecondsRealtime(result);
            }
            else
            {
                yield return new WaitForSecondsRealtime(_defaultInterval);
            }
            _typingIndex++;
        }



        //yield return null;
    }
    //原理:改变单个文字的Alpha
    //newAlpha范围是0-255
    private void SetSingleCharacterAlpha(int index, byte newAlpha)
    {
        TMP_CharacterInfo charInfo = textInfo.characterInfo[index];
        //材质索引
        int matIndex = charInfo.materialReferenceIndex;
        //顶点索引
        int verIndex = charInfo.vertexIndex;
        for (int i = 0; i < 4; i++)
        {
            //color32表示所有的顶点颜色
            textInfo.meshInfo[matIndex].colors32[verIndex + i].a = newAlpha;
        }
        UpdateVertexData();
    }

    // 渐显角色函数,用于平滑地调整角色透明度
    IEnumerator FadeInCharacter(int index, float duration = 0.2f)
    {
        //瞬间显示
        if (duration <= 0)
        {
            SetSingleCharacterAlpha(index, 255);
        }
        else
        {
            float timer = 0;
            while(timer<duration)
            {
                //unscaledDeltaTime不考虑时间的放缩,游戏暂停的时候也不停止
                //timer不能超过duration
                timer = Mathf.Min(duration, timer + Time.unscaledDeltaTime);
                SetSingleCharacterAlpha(index, (byte)(255 * timer / duration));
                yield return null;
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值