利用富文本,网上大多只是文字介绍,我把他实现出来了。当然这里都是基于我在游戏当中的实现,看看意思,原理就好。
using Scene;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;
namespace UIFW
{
public class InitUIFrm : INormalUserInterface
{
/// <summary>
/// 介绍的内容
/// </summary>
string[] _IntroContent = {
"来自普通山村的韩立,经过家中亲戚推荐进入当地的江湖门派七玄门,又被门派中的长老墨居仁看中成为其弟子,每日修炼名为《长春功》的口诀。" ,
"期间随着同伴的消失而发现师父的可疑之处,另外偶然得到了一瓶能催化药草,以及救下门派师兄厉飞雨并与其结为知己。",
"某日与师父摊牌对决,不慎战败,本想遭其毒手却侥幸存活下来,在其合作者余子童口中得知自己练就了一身修仙技能及墨居仁的真相后将其灭口。",
"心想重获自由,但读完师父的遗书后才发现自己被下的毒还没有解完,而且要远行找到其家人才可获得真正解药。得知此事的韩立决定完成师父的遗愿从而拯救自己,从此踏上了修仙之路。"
};
//每次透明度的增长值
int _AlphaSpan = 10;
//AlpheLine 当前字对应的alpha度,当为100的时候完全显示字体
Dictionary<int, int> _AlphaLine;
//当前迭代索引 txtIndex==intro[?].Length的时候则为print完成
int _txtIndex = 0;
//当前迭代开始索引,已经透明度为100的可以保存起来,避免遍历提高效率
int _BeginIndex = 0;
//当前Print索引
int _PrintIndex = 0;
//当前显示文本
string _NowText;
//Text组件的color颜色文本值
string txt_OriginColor;
//TimeSpan计时器
float _TimeSpan = .2f;
float _Timer = 0;
//是否Print
bool _IsPrint = false;
bool _IsEnd = false;
//组件 Text
Text txt_IntroValue;
//btn
Button btn_OK;
public InitUIFrm()
{
base.ResName = "InitUIFrm.prefab";
}
public override void SetObject(GameObject _gameObject)
{
base.TraParent = _UISystem.TraNormal;
base.SetObject(_gameObject);
}
public override void Initialize()
{
base.Initialize();
_AlphaLine = new Dictionary<int, int>();
//获得组件
txt_IntroValue = UITool.GetComponentFromChildNode<Text>(_GameObject.transform, "txtIntroValue");
btn_OK = UITool.GetComponentFromChildNode<Button>(_GameObject.transform, "btnOK");
//获得颜色值
txt_OriginColor = ColorUtility.ToHtmlStringRGB(txt_IntroValue.color);
//注册UI事件
btn_OK.onClick.AddListener(
() =>
{
//取消打印文本
_IsPrint = false;
});
//开启Print文本
_IsPrint = true;
}
public override void Update()
{
base.Update();
//开启Print文本
if (_IsPrint)
{
if (_PrintIndex == _IntroContent.Length)
{
_IsPrint = false;
return;
}
if (_txtIndex < _IntroContent[_PrintIndex].Length)
{
//等一段时间在继续打印下一个字
while (_Timer < _TimeSpan)
{
_Timer += Time.deltaTime;
return;
}
_Timer = 0;
//增加一个字
_txtIndex++;
}
else
{
//打印完一段
txt_IntroValue.color = new Color(txt_IntroValue.color.r, txt_IntroValue.color.g, txt_IntroValue.color.b, 0);
//清空text的值,等下一轮打印
_PrintIndex++;
//数据初始化
txt_IntroValue.text = "";
_BeginIndex = 0;
_txtIndex = 0;
_AlphaLine.Clear();
txt_IntroValue.color = new Color(txt_IntroValue.color.r, txt_IntroValue.color.g, txt_IntroValue.color.b, 1);
return;
}
for (int i = _BeginIndex; i < _txtIndex; i++)
{
if (!_AlphaLine.ContainsKey(i))
{
_AlphaLine.Add(i, 0);
}
int alpha = _AlphaLine[i];
//如果alpha已经大于100了,可以完全显示了,>100的没有标签,
if (alpha >= 100)
{
_BeginIndex = i + 1;
_NowText += _IntroContent[_PrintIndex].Substring(0, _BeginIndex);
}
else //小于100的每个字都有标签,大于txtIndex的甚至都还轮不到它们显示
{
//增加颜色标签,归一化为两位数
_NowText += $"<color=#{txt_OriginColor}";
if (_AlphaLine[i] < 10)
{
_NowText += $"0{_AlphaLine[i]}>";
}
else
{
_NowText += $"{_AlphaLine[i]}>";
}
_NowText += $"{_IntroContent[_PrintIndex].Substring(i, 1)}</color>"; //把i这个字加入
//插值增加
_AlphaLine[i] += _AlphaSpan;
}
}
//获得_NowText,文本赋值
txt_IntroValue.text = _NowText;
_NowText = "";
}
else if(!_IsEnd)
{
_IsEnd = true;
//关闭自身
GameManager.Instance.CloseUIFrm<InitUIFrm>();
//开始播放动画
Camera.main.GetComponent<VideoPlayer>().Play();
//跳转到开始场景
//GameManager.Instance.SetSceneState(new StartSceneState("StartScene", GameManager.Instance.SceneMgr));
}
}
public override void Release()
{
txt_IntroValue = null;
btn_OK = null;
base.Release();
}
}
}