推荐阅读

  • CSDN主页
  • GitHub开源地址
  • Unity3D插件分享
  • 简书地址
  • QQ群:398291828

大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。

一、前言

需求要实现Text的打字机效果,一看居然还没这类型的教程,遂补上。

二、实现

2-1、使用DOTween插件实现效果

using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

public class TextWriterDoTween : MonoBehaviour
{
    private void Start()
    {
        DoTweenText("123456", 6, () => 
        {
            Debug.Log("用6秒显示6个字");
        });
    }
    /// 
    /// 打字机效果显示文字
    /// 
    /// 文字内容
    /// 时间
    /// 结束后执行方法
    void DoTweenText(string text, float time, UnityAction action)
    {
        Text tmpText = transform.GetComponent<Text>();
        tmpText.text = string.Empty;
        try
        {
            tmpText.DOText(text, time, true, ScrambleMode.None, null).SetEase(Ease.Linear).OnComplete(() => { action(); });
        }
        catch (System.NullReferenceException)
        {
            Debug.LogError("该对象不存在Text组件");
        }
    }
}

效果图:
【Unity3D小功能】Unity3D中UGUI-Text实现打字机效果插图

2-2、实现Text的打字机效果

参考代码:

using System.Collections;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
/// 
/// 用于Text的打字机效果组件。
/// 
[RequireComponent(typeof(Text))]
public class TextWriter : MonoBehaviour
{
/// 
/// 打字机效果状态。
/// 
public enum TypewriterState
{
/// 
/// 已完成输出。
/// 
Completed,
/// 
/// 正在输出。
/// 
Outputting,
/// 
/// 输出被中断。
/// 
Interrupted
}
/// 
/// 打字机效果用时
/// 
private float useTime;
/// 
/// 打字机效果状态。
/// 
private TypewriterState state = TypewriterState.Completed;
/// 
/// Text组件。
/// 
private Text tmpText;
/// 
/// 文本内容。
/// 
string words;
/// 
/// 显示间隔。
/// 
int charsSecond;
/// 
/// 用于输出字符的协程。
/// 
private Coroutine outputCoroutine;
/// 
/// 字符输出结束时的回调。
/// 
private UnityAction outputEndCallback;
void Awake()
{
tmpText = GetComponent<Text>();
}
private void Start()
{
OutputText("123456", 12, () => {
Debug.Log("用12秒显示6个字");
});
}
void OnDisable()
{
// 中断输出
if (state == TypewriterState.Outputting)
{
state = TypewriterState.Interrupted;
StopCoroutine(outputCoroutine);
OnOutputEnd(true);
}
}
/// 
/// 输出文字。
/// 
/// 
/// 
public void OutputText(string text, float time, UnityAction onOutputEnd = null)
{
// 如果当前正在执行字符输出,将其中断
if (state == TypewriterState.Outputting)
{
StopCoroutine(outputCoroutine);
state = TypewriterState.Interrupted;
OnOutputEnd(false);
}
tmpText.text = text;
useTime = time;
outputEndCallback = onOutputEnd;
words = text;
// 如果对象未激活,直接完成输出
if (!isActiveAndEnabled)
{
state = TypewriterState.Completed;
OnOutputEnd(true);
return;
}
outputCoroutine = StartCoroutine(OutputText());
}
/// 
/// 以不带淡入效果输出字符的协程。
/// 
/// 
/// 
private IEnumerator OutputText()
{
state = TypewriterState.Outputting;
// 先隐藏所有字符
tmpText.text = "";
// 按时间逐个显示字符
float timer = 0f;
Text textInfo = tmpText;
float speed = useTime / words.Length;//计算出出现文字的间隔
while (charsSecond < words.Length)
{
timer += Time.deltaTime;
if (timer >= speed)
{
timer = 0;
charsSecond++;
tmpText.text = words.Substring(0, charsSecond);
}
yield return null;
}
// 输出过程结束
state = TypewriterState.Completed;
OnOutputEnd(false);
}
/// 
/// 完成正在进行的打字机效果,将所有文字显示出来。
/// 
public void CompleteOutput()
{
if (state == TypewriterState.Outputting)
{
state = TypewriterState.Completed;
StopCoroutine(outputCoroutine);
OnOutputEnd(true);
}
}
/// 
/// 处理输出结束逻辑。
/// 
/// 
private void OnOutputEnd(bool isShowAllCharacters)
{
// 清理协程
outputCoroutine = null;
// 将所有字符显示出来
if (isShowAllCharacters)
{
tmpText.text = words;
}
// 触发输出完成回调
if (outputEndCallback != null)
{
var temp = outputEndCallback;
outputEndCallback = null;
temp.Invoke();
}
}
}

效果图:
【Unity3D小功能】Unity3D中UGUI-Text实现打字机效果插图

2-3、使用TextMeshPro实现打字机效果

参考代码:

using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace Tools
{
/// 
/// 打字机效果状态。
/// 
public enum TypewriterState
{
/// 
/// 已完成输出。
/// 
Completed,
/// 
/// 正在输出。
/// 
Outputting,
/// 
/// 输出被中断。
/// 
Interrupted
}
/// 
/// 用于TextMeshPro的打字机效果组件。
/// 
[RequireComponent(typeof(TextMeshProUGUI))]
public class TextWriterTmp : MonoBehaviour
{
/// 
/// 打字机效果用时
/// 
private float useTime;
/// 
/// 打字机效果状态。
/// 
private TypewriterState state = TypewriterState.Completed;
/// 
/// TextMeshPro组件。
/// 
private TMP_Text tmpText;
/// 
/// 用于输出字符的协程。
/// 
private Coroutine outputCoroutine;
/// 
/// 字符输出结束时的回调。
/// 
private UnityAction outputEndCallback;
/// 
/// 输出文字。
/// 
/// 
/// 
public void OutputText(string text, float time, UnityAction onOutputEnd = null)
{
// 如果当前正在执行字符输出,将其中断
if (state == TypewriterState.Outputting)
{
StopCoroutine(outputCoroutine);
state = TypewriterState.Interrupted;
OnOutputEnd(false);
}
tmpText.text = text;
useTime = time;
outputEndCallback = onOutputEnd;
// 如果对象未激活,直接完成输出
if (!isActiveAndEnabled)
{
state = TypewriterState.Completed;
OnOutputEnd(true);
return;
}
outputCoroutine = StartCoroutine(OutputText());
}
/// 
/// 完成正在进行的打字机效果,将所有文字显示出来。
/// 
public void CompleteOutput()
{
if (state == TypewriterState.Outputting)
{
state = TypewriterState.Completed;
StopCoroutine(outputCoroutine);
OnOutputEnd(true);
}
}
private void Awake()
{
tmpText = GetComponent<TMP_Text>();
}
private void Start()
{
OutputText("123456", 6, () => 
{
Debug.Log("用6秒显示6个字");
});
}
private void OnDisable()
{
// 中断输出
if (state == TypewriterState.Outputting)
{
state = TypewriterState.Interrupted;
StopCoroutine(outputCoroutine);
OnOutputEnd(true);
}
}
/// 
/// 以不带淡入效果输出字符的协程。
/// 
/// 
/// 
private IEnumerator OutputText(bool skipFirstCharacter = false)
{
state = TypewriterState.Outputting;
// 先隐藏所有字符
tmpText.maxVisibleCharacters = skipFirstCharacter ? 1 : 0;
tmpText.ForceMeshUpdate();
// 按时间逐个显示字符
float timer = 0f;
TMP_TextInfo textInfo = tmpText.textInfo;
float speed = useTime / textInfo.characterCount;
while (tmpText.maxVisibleCharacters < textInfo.characterCount)
{
timer += Time.deltaTime;
if (timer >= speed)
{
timer = 0;
tmpText.maxVisibleCharacters++;
}
yield return null;
}
// 输出过程结束
state = TypewriterState.Completed;
OnOutputEnd(false);
}
/// 
/// 设置字符的顶点颜色Alpha值。
/// 
/// 
/// 
private void SetCharacterAlpha(int index, byte alpha)
{
var materialIndex = tmpText.textInfo.characterInfo[index].materialReferenceIndex;
var vertexColors = tmpText.textInfo.meshInfo[materialIndex].colors32;
var vertexIndex = tmpText.textInfo.characterInfo[index].vertexIndex;
vertexColors[vertexIndex + 0].a = alpha;
vertexColors[vertexIndex + 1].a = alpha;
vertexColors[vertexIndex + 2].a = alpha;
vertexColors[vertexIndex + 3].a = alpha;
}
/// 
/// 处理输出结束逻辑。
/// 
/// 
private void OnOutputEnd(bool isShowAllCharacters)
{
// 清理协程
outputCoroutine = null;
// 将所有字符显示出来
if (isShowAllCharacters)
{
var textInfo = tmpText.textInfo;
for (int i = 0; i < textInfo.characterCount; i++)
{
SetCharacterAlpha(i, 255);
}
tmpText.maxVisibleCharacters = textInfo.characterCount;
tmpText.ForceMeshUpdate();
}
// 触发输出完成回调
if (outputEndCallback != null)
{
var temp = outputEndCallback;
outputEndCallback = null;
temp.Invoke();
}
}
}
}

效果图:
【Unity3D小功能】Unity3D中UGUI-Text实现打字机效果插图

三、后记

如果觉得本篇文章有用别忘了点个关注,关注不迷路,持续分享更多Unity干货文章。


你的点赞就是对博主的支持,有问题记得留言:

博主主页有联系方式。

博主还有跟多宝藏文章等待你的发掘哦:

专栏方向简介
Unity3D开发小游戏小游戏开发教程分享一些使用Unity3D引擎开发的小游戏,分享一些制作小游戏的教程。
Unity3D从入门到进阶入门从自学Unity中获取灵感,总结从零开始学习Unity的路线,有C#和Unity的知识。
Unity3D之UGUIUGUIUnity的UI系统UGUI全解析,从UGUI的基础控件开始讲起,然后将UGUI的原理,UGUI的使用全面教学。
Unity3D之读取数据文件读取使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。
Unity3D之数据集合数据集合数组集合:数组、List、字典、堆栈、链表等数据集合知识分享。
Unity3D之VR/AR(虚拟仿真)开发虚拟仿真总结博主工作常见的虚拟仿真需求进行案例讲解。
Unity3D之插件插件主要分享在Unity开发中用到的一些插件使用方法,插件介绍等
Unity3D之日常开发日常记录主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等
Unity3D之日常BUG日常记录记录在使用Unity3D编辑器开发项目过程中,遇到的BUG和坑,让后来人可以有些参考。
本站无任何商业行为
个人在线分享 » 【Unity3D小功能】Unity3D中UGUI-Text实现打字机效果
E-->