Unity 实现字幕打字效果

Text文本打字效果,TextMeshPro可以对应参考,差距不大,改改参数名就能用。改脚本原本被我集成到其他的程序集中,现在已经分离。

效果

请添加图片描述

实现功能

1.能够设置每行能够容纳的字数和允许的冗余
2.打字效果
3.每行打完上移
4.开头进入,结束弹出
5.行居中

脚本使用

请添加图片描述
请添加图片描述

属性解释
TypingSpeed打字速度(.s 每过多少时间打一个)
RowShowMax一行显示的最大值
AllowRedundancy每行能够允许的冗余
IsUpdateText更新文本,默认不启动,勾选点击运行就更新
Text挂载text文本
OffsetY对每行上移的补偿
SaveMarqueeoriginPosition保存字幕整体的初始位置
TextCloseDelayTime字幕消失的时间(Obsolete)
BottomShow需要挂载下方显示的整体
函数功能
UpdateText更新文本,需要再Update中调用
OnFinish更新完成,更新文本完成后调用的函数
OnTextUpdate(string)文本更新,在打字过程中如果发生文本更新需要调用的方法
OnTextReset文本重置


设置

** 1.物体设置 **
请添加图片描述

** 2.text文本设置 **
请添加图片描述
1.需要文字的size(如果有外描边的话)来计算字占据的行宽,来决定每行上移的距离
2.文本每行居中,但定格显示

代码

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;namespace YBZ {public class TypewriterEffect : MonoBehaviour {// 测试文本private readonly string text_test = "SVN中我需要维护的东西Scene; Scripts/Engine/WSC SteamingAsset/2DPivots.json Editor/WSCPivotEditor.cs \n 下方提示";[Header("文本显示"), Space(10)]public float typingSpeed = 0.2f; // 打字速度public int rowShowMax = 25; // 一行最大显示数量public int allowRedundancy = 6; // 允许的冗余数量public bool isUpdateText = false; // 是否播放public Text text; // 底部字幕[Range(-25, 25), Space(5)]public int offsetY = -3; // 第一行Y轴补偿public Vector3 saveMarqueeOriginPostion = new Vector3(0, -63, 0); // 下方字幕的原初位置private float textTimeCount = 0; // 更新用的计时器private string word = ""; //保存字幕private int currentPos = 0; // 打字字符索引private int LineBreakCount = 0; // 换行符计数private Vector3 saveTextLocatePostion;  // 用于保存TextUI位置private bool isOriginPosition = true;void Update() {UpdateText();if (Input.GetMouseButtonDown(0)) {OnTextUpdate(text_test);}}// 文本更新private void UpdateText() {if (!isUpdateText) {return;}// 检查字幕是否位于原初位置if (isOriginPosition) {isOriginPosition = !isOriginPosition;BottomShow.transform.DOLocalMove(Vector3.zero, 1.0f);}BottomShow.SetActive(true);if (saveTextLocatePostion == Vector3.zero) {saveTextLocatePostion = text.rectTransform.localPosition;}if (word == "") {word = text.text;}textTimeCount += Time.deltaTime;if (textTimeCount > typingSpeed) {textTimeCount = 0;currentPos++;if (currentPos >= word.Length) {Debug.Log("播放完成");OnFinish();return;}text.text = word[..currentPos];//刷新文本显示内容if (word[currentPos - 1] == '\n') {Debug.Log("发现换行符");LineBreakCount++;// 每次遇到一个换行符就上移25个单位if (LineBreakCount == 1) {text.rectTransform.DOLocalMoveY(text.rectTransform.localPosition.y + 25 + offsetY, 1f);} else if (LineBreakCount != 1) {text.rectTransform.DOLocalMoveY(text.rectTransform.localPosition.y + 25, 1f);}}// 每次处理行超限int lineCount;if (LineBreakCount == 0) {lineCount = text.text.Length;} else {lineCount = text.text[text.text.LastIndexOf('\n')..].Length;}// 行超限if (lineCount > rowShowMax + allowRedundancy) {word = text.text + '\n' + word[text.text.Length..];}}}[Header("下方显示延迟消失的所需要的时间")]public float textCloseDelayTime = 2.0f;/// <summary>/// 下方提示游戏物体,在使用前预加载/// </summary>public GameObject BottomShow;public IEnumerator IE_TextCloseDelayTime(float time) {yield return new WaitForSeconds(time);BottomShow.SetActive(false);Debug.Log("下方显示已关闭");}public IEnumerator IE_OnTextReset(float time) {yield return new WaitForSeconds(time);OnTextReset();Debug.Log("文本恢复默认");isOriginPosition = true;BottomShow.transform.DOLocalMove(saveMarqueeOriginPostion, 1.0f);}// 文本更新完成 , 一旦确认关闭就不要再更新文本, 否侧会出现逻辑错误,如若在播放完毕后更新文本一定要在下方显示关闭后, 字幕回滚的时候不能更新文本.private void OnFinish() {isUpdateText = false;// 完成之后下方显示 延迟关闭, 位置回调// StartCoroutine(IE_TextCloseDelayTime(textCloseDelayTime));// 延迟文本重置位置StartCoroutine(IE_OnTextReset(textCloseDelayTime));text.rectTransform.DOLocalMove(saveTextLocatePostion + new Vector3(0, offsetY, 0), textCloseDelayTime);}// 文本更新, 一旦更新就是确定要开始播放(╯‵□′)╯︵┻━┻(你更新不是为了播放?)private void OnTextUpdate(string newtext) {text ??= GameObject.Find("字幕文字").gameObject.GetComponent<Text>();OnTextReset();word = newtext;// StartCoroutine(IE_OnTextReset(0.5f));BottomShow.SetActive(true);isUpdateText = true;}// 文本恢復默认: 索引为0, 换行符统计为0, LocalPostion恢复, 文本置空private void OnTextReset() {if (saveTextLocatePostion == Vector3.zero) {saveTextLocatePostion = text.rectTransform.localPosition;}text.rectTransform.localPosition = saveTextLocatePostion;text.text = "";LineBreakCount = 0;currentPos = 0;}// 初始化public void Init() {Debug.Log("文本更新初始化完成");}public void UnInit() {Debug.Log("文本控制结束");}private void OnDestroy() {UnInit();}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/57171.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络安全进阶学习第十二课——SQL手工注入3(Access数据库)

文章目录 注入流程&#xff1a;1、判断数据库类型2、判断表名3、判断列名4、判断列数1&#xff09;判断显示位 5、判断数据长度6、爆破数据内容 注入流程&#xff1a; 判断数据库类型 ——> 判断表名 ——> 判断列名 ——> 判断列名长度 ——> 查出数据。 asp的网…

Java课题笔记~ AspectJ 对 AOP 的实现(掌握)

AspectJ 对 AOP 的实现(掌握) 对于 AOP 这种编程思想&#xff0c;很多框架都进行了实现。Spring 就是其中之一&#xff0c;可以完成面向切面编程。然而&#xff0c;AspectJ 也实现了 AOP 的功能&#xff0c;且其实现方式更为简捷&#xff0c;使用更为方便&#xff0c;而且还支…

Object Map 的相互转换

学生业务对象定义&#xff1a;Student Student student new Student(); student.setId(1L); student.setName("令狐冲") student.setAge(10) 第一种&#xff1a;通过Alibaba Fastjson实现 pom.xml 文件依赖 <dependency><groupId>com.alibaba</g…

PHP 前后端分离,运行配置

H5 WEB目录:安装 yarn install、npm install &#xff08;依赖包&#xff09; 在电脑&#xff1a;安装nodejs Composer下载 &#xff1a;https://getcomposer.org/

UNIX基础知识:UNIX体系结构、登录、文件和目录、输入和输出、程序和进程、出错处理、用户标识、信号、时间值、系统调用和库函数

引言&#xff1a; 所有的操作系统都为运行在其上的程序提供服务&#xff0c;比如&#xff1a;执行新程序、打开文件、读写文件、分配存储区、获得系统当前时间等等 1. UNIX体系结构 从严格意义上来说&#xff0c;操作系统可被定义为一种软件&#xff0c;它控制计算机硬件资源&…

【C++】异常exception

文章目录 1. C语言中传统的处理错误方法2. C中的异常3. 异常的使用3.1 异常的抛出和捕获3.2 异常的重新抛出3.3 异常安全3.4 异常规范 4. 自定义异常体系5. 异常的优缺点 &#x1f4dd; 个人主页 &#xff1a;超人不会飞)&#x1f4d1; 本文收录专栏&#xff1a;《C的修行之路》…

解释器模式-自定义语言的实现

有时&#xff0c;我们希望输入一串字符串&#xff0c;然后计算机能够按照预先定义的文法规则来对这个字符串进行解释&#xff0c;从而实现相应的功能。 例如&#xff0c;我们想实现简单的加减法接收器&#xff0c;只需输入一个表达式&#xff0c;它就能计算出表达式结果。比如…

性能测试jmeter连接数据库jdbc(sql server举例)

一、下载第三方工具包驱动数据库 1. 因为JMeter本身没有提供链接数据库的功能&#xff0c;所以我们需要借助第三方的工具包来实现。 &#xff08;有这个jar包之后&#xff0c;jmeter可以发起jdbc请求&#xff0c;没有这个jar包&#xff0c;也有jdbc取样器&#xff0c;但不能发起…

Metashape和PhotoScan中文版软件下载安装地址

Metashape的点云生成功能 Metashape具有强大的点云生成功能&#xff0c;可以将图像转换为精确的三维点云数据。点云数据是进行三维建模和地形分析的重要基础。 在使用Metashape时&#xff0c;用户可以通过使用图像对齐功能生成点云数据。软件根据对齐后的图像生成稠密的点云&a…

SpringBoot系列---【三种启动传参方式的区别】

三种启动传参方式的区别 1.三种方式分别是什么? idea中经常看到下面三种启动传参方式 优先级 Program arguments > VM options > Environment variable > 系统默认值 2.参数说明 2.1、VM options VM options其实就是我们在程序中需要的运行时环境变量&#xff0c;它需…

从C语言到C++_30(哈希)闭散列和开散列(哈希桶)的实现

目录 1. 哈希结构 1.1 哈希的概念 1.2 哈希冲突(碰撞) 1.3 哈希函数 2. 闭散列/开散列解决哈希冲突 2.1 闭散列概念和代码 2.1.1 闭散列线性探测&#xff08;实现&#xff09; 闭散列线性探测完整代码 2.1.2 闭散列二次探测&#xff08;了解&#xff09; 2.2 开散列(…

2023 RISC-V中国峰会 安全相关议题汇总

安全相关议题 1、The practical use cases of the RISC-V IOPMP 2、构建安全可信、稳定可靠的RISC-V安全体系 3、Enhancing RISC-V Debug Security with hardware-based isolation 4、Closing a side door: Designing high-performance RISC-V core resilient to branch pr…