推荐阅读
- 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个字");});}/// <summary>/// 打字机效果显示文字/// </summary>/// <param name="text">文字内容</param>/// <param name="time">时间</param>/// <param name="action">结束后执行方法</param>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组件");}}
}
效果图:
2-2、实现Text的打字机效果
参考代码:
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;/// <summary>
/// 用于Text的打字机效果组件。
/// </summary>
[RequireComponent(typeof(Text))]
public class TextWriter : MonoBehaviour
{/// <summary>/// 打字机效果状态。/// </summary>public enum TypewriterState{/// <summary>/// 已完成输出。/// </summary>Completed,/// <summary>/// 正在输出。/// </summary>Outputting,/// <summary>/// 输出被中断。/// </summary>Interrupted}/// <summary>/// 打字机效果用时/// </summary>private float useTime;/// <summary>/// 打字机效果状态。/// </summary>private TypewriterState state = TypewriterState.Completed;/// <summary>/// Text组件。/// </summary>private Text tmpText;/// <summary>/// 文本内容。/// </summary>string words;/// <summary>/// 显示间隔。/// </summary>int charsSecond;/// <summary>/// 用于输出字符的协程。/// </summary>private Coroutine outputCoroutine;/// <summary>/// 字符输出结束时的回调。/// </summary>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);}}/// <summary>/// 输出文字。/// </summary>/// <param name="text"></param>/// <param name="onOutputEnd"></param>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());}/// <summary>/// 以不带淡入效果输出字符的协程。/// </summary>/// <param name="skipFirstCharacter"></param>/// <returns></returns>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);}/// <summary>/// 完成正在进行的打字机效果,将所有文字显示出来。/// </summary>public void CompleteOutput(){if (state == TypewriterState.Outputting){state = TypewriterState.Completed;StopCoroutine(outputCoroutine);OnOutputEnd(true);}}/// <summary>/// 处理输出结束逻辑。/// </summary>/// <param name="isShowAllCharacters"></param>private void OnOutputEnd(bool isShowAllCharacters){// 清理协程outputCoroutine = null;// 将所有字符显示出来if (isShowAllCharacters){tmpText.text = words;}// 触发输出完成回调if (outputEndCallback != null){var temp = outputEndCallback;outputEndCallback = null;temp.Invoke();}}
}
效果图:
2-3、使用TextMeshPro实现打字机效果
参考代码:
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;namespace Tools
{/// <summary>/// 打字机效果状态。/// </summary>public enum TypewriterState{/// <summary>/// 已完成输出。/// </summary>Completed,/// <summary>/// 正在输出。/// </summary>Outputting,/// <summary>/// 输出被中断。/// </summary>Interrupted}/// <summary>/// 用于TextMeshPro的打字机效果组件。/// </summary>[RequireComponent(typeof(TextMeshProUGUI))]public class TextWriterTmp : MonoBehaviour{/// <summary>/// 打字机效果用时/// </summary>private float useTime;/// <summary>/// 打字机效果状态。/// </summary>private TypewriterState state = TypewriterState.Completed;/// <summary>/// TextMeshPro组件。/// </summary>private TMP_Text tmpText;/// <summary>/// 用于输出字符的协程。/// </summary>private Coroutine outputCoroutine;/// <summary>/// 字符输出结束时的回调。/// </summary>private UnityAction outputEndCallback;/// <summary>/// 输出文字。/// </summary>/// <param name="text"></param>/// <param name="onOutputEnd"></param>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());}/// <summary>/// 完成正在进行的打字机效果,将所有文字显示出来。/// </summary>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);}}/// <summary>/// 以不带淡入效果输出字符的协程。/// </summary>/// <param name="skipFirstCharacter"></param>/// <returns></returns>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);}/// <summary>/// 设置字符的顶点颜色Alpha值。/// </summary>/// <param name="index"></param>/// <param name="alpha"></param>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;}/// <summary>/// 处理输出结束逻辑。/// </summary>/// <param name="isShowAllCharacters"></param>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();}}}
}
效果图:
三、后记
如果觉得本篇文章有用别忘了点个关注,关注不迷路,持续分享更多Unity干货文章。
你的点赞就是对博主的支持,有问题记得留言:
博主主页有联系方式。
博主还有跟多宝藏文章等待你的发掘哦:
专栏 | 方向 | 简介 |
---|---|---|
Unity3D开发小游戏 | 小游戏开发教程 | 分享一些使用Unity3D引擎开发的小游戏,分享一些制作小游戏的教程。 |
Unity3D从入门到进阶 | 入门 | 从自学Unity中获取灵感,总结从零开始学习Unity的路线,有C#和Unity的知识。 |
Unity3D之UGUI | UGUI | Unity的UI系统UGUI全解析,从UGUI的基础控件开始讲起,然后将UGUI的原理,UGUI的使用全面教学。 |
Unity3D之读取数据 | 文件读取 | 使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。 |
Unity3D之数据集合 | 数据集合 | 数组集合:数组、List、字典、堆栈、链表等数据集合知识分享。 |
Unity3D之VR/AR(虚拟仿真)开发 | 虚拟仿真 | 总结博主工作常见的虚拟仿真需求进行案例讲解。 |
Unity3D之插件 | 插件 | 主要分享在Unity开发中用到的一些插件使用方法,插件介绍等 |
Unity3D之日常开发 | 日常记录 | 主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等 |
Unity3D之日常BUG | 日常记录 | 记录在使用Unity3D编辑器开发项目过程中,遇到的BUG和坑,让后来人可以有些参考。 |