【Unity3D游戏开发】基于NGUI的表情图文混排解决方案 (二二)

2024-03-24 19:32

本文主要是介绍【Unity3D游戏开发】基于NGUI的表情图文混排解决方案 (二二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

使用 unity3d也有两年时间了,最近比较闲,有功夫梳理一下去年一年来学到以及用到的知识,分享给大家,顺便方便自己查阅。如有错误以及不当的地方,欢迎各位指正。谢谢。
去年五月份的时候,刚加入项目不久,老大交给我一个关于聊天系统任务,期初觉得应该很容易,但是看了文档之后,瞬间头都大了_(:з」∠)_,因为需要支持表情!当时Unity3D版本4.3.x,NGUI版本3.5x,当时版本的NGUI已经支持动态字体,我们的项目也不例外,赶忙就用上了。但是,表情的 问题要怎么解决?总不能用颜文字吧(╯‵□′)╯︵┻━┻。如果不用动态字体而使用自己制作的图集字体,倒是可以将表情图片打进字库解决。但是既然我们已经用了动态字体,我就只能另想办法了。
经过两天的研究实践,最终找到一个能够实现的解决办法。主要思路是:
1.定义一个标准行宽度,以此作为基准对文字以及表情进行分行处理;
2.使用特殊符号标记表情(例如:#e001),遍历字符串,凡遇到表情标记则将之与位置记录下来,并使用“ ”(空格,具体数量视表情大小而定)将特殊标记替换。
3.使用Vector3记录以上信息,x为表情的横坐标,y为表情所在行数(即纵坐标),z为表情的ID,即刚才的001,以此确定是哪个表情。使用一个List将所有表情信息存放起来,显示时遍历List即可。
有了以上基本思路,下面只要编码实现,但是在编码过程中还是不可避免的问题——如何得到一段文字的长度?这时,就需要用到一个NGUI封装的一个方法NGUIText.CalculatePrintedSize传入参数为string,返回一个Vector2,表示这段文字的长和宽。下面是核心代码。

[code]csharpcode:

protected void CalculateExpressionPos(ref string text)
{NGUIText.finalSize = m_chatInput.label.defaultFontSize;//设置当前使用字体大小lineList.Clear();int row = 0;int textWidth = 0;int lastStartIndex = 0;string curLine = "";int length = text.Length;for (int i = 0; i < length; i++){ if (text[i] == '#' && i + 4 < length && text[i + 1] == 'e'){string eName = text.Substring(i + 2, 3);int eIndex = 0;Vector3 ePos = Vector3.zero;if (int.TryParse(eName, out eIndex)){float fx = 0;text = text.Remove(i, 5);text = text.Insert(i, space);//space = "       ";length = text.Length;//这里的CalculatePrintedSize是重载过的,//与原本方法相比多的一个参数自定义行款,替换原方法中的rectWidth即可textWidth = Mathf.RoundToInt(NGUIText.CalculatePrintedSize(text.Substring(lastStartIndex, i - lastStartIndex),BASELINEWIDTH + 30).x);//BASELINEWIDTH为标准行宽度,30是根据表情大小确定的,//这里的表情大小是30*30if (textWidth > BASELINEWIDTH - 30)         {curLine = text.Substring(lastStartIndex, i - lastStartIndex + 1);lineList.Add(curLine);if (textWidth <= BASELINEWIDTH - 15 ||textWidth >= BASELINEWIDTH)//行末尾不够需换行{fx = 0;row++;lastStartIndex = i;ePos.x = fx - m_offsetX;ePos.y = row;ePos.z = eIndex;}else   //行末尾足够不需换行{fx = textWidth;lastStartIndex = i + space.Length;ePos.x = fx - m_offsetX;ePos.y = row;ePos.z = eIndex;row++;}}else{fx = textWidth;ePos.x = fx - m_offsetX;ePos.y = row;ePos.z = eIndex;}}if (eIndex != 0){eList.Add(ePos);}if (!expInLine.ContainsKey(row))        //有表情无表情行,以此确定行间距{expInLine.Add(row, true);}}else      //记录换行起始Index{if (i - lastStartIndex < 0) continue;float curWidth = Mathf.RoundToInt(NGUIText.CalculatePrintedSize(text.Substring(lastStartIndex, i - lastStartIndex + 1),BASELINEWIDTH + 30).x);if (curWidth > BASELINEWIDTH){curLine = text.Substring(lastStartIndex, i - lastStartIndex + 1);lineList.Add(curLine);lastStartIndex = i + 1;row++;}if (i == length - 1){if (i - lastStartIndex < 0) continue;curLine = text.Substring(lastStartIndex, i - lastStartIndex + 1);lineList.Add(curLine);}}}
}
      经过以上处理,输出的lineList即为聊天内容,eList为表情信息,expInLine字典存放每行是否存在表情信息。将表情图标打入一个图集,命名为001_1、001_2。。。在显示表情时使用UISpriteAnimation脚本可实现动态表情。最终效果如下:

原文链接: http://www.manew.com/blog-3649-2595.html
参考文章: NGUI研究院之有点坑爹的图文混排(十四)

这篇关于【Unity3D游戏开发】基于NGUI的表情图文混排解决方案 (二二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/842564

相关文章

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

Java.lang.InterruptedException被中止异常的原因及解决方案

《Java.lang.InterruptedException被中止异常的原因及解决方案》Java.lang.InterruptedException是线程被中断时抛出的异常,用于协作停止执行,常见于... 目录报错问题报错原因解决方法Java.lang.InterruptedException 是 Jav

kkFileView在线预览office的常见问题以及解决方案

《kkFileView在线预览office的常见问题以及解决方案》kkFileView在线预览Office常见问题包括base64编码配置、Office组件安装、乱码处理及水印添加,解决方案涉及版本适... 目录kkFileView在线预览office的常见问题1.base642.提示找不到OFFICE组件

SpringBoot监控API请求耗时的6中解决解决方案

《SpringBoot监控API请求耗时的6中解决解决方案》本文介绍SpringBoot中记录API请求耗时的6种方案,包括手动埋点、AOP切面、拦截器、Filter、事件监听、Micrometer+... 目录1. 简介2.实战案例2.1 手动记录2.2 自定义AOP记录2.3 拦截器技术2.4 使用Fi

PyQt5 GUI 开发的基础知识

《PyQt5GUI开发的基础知识》Qt是一个跨平台的C++图形用户界面开发框架,支持GUI和非GUI程序开发,本文介绍了使用PyQt5进行界面开发的基础知识,包括创建简单窗口、常用控件、窗口属性设... 目录简介第一个PyQt程序最常用的三个功能模块控件QPushButton(按钮)控件QLable(纯文本

游戏闪退弹窗提示找不到storm.dll文件怎么办? Stormdll文件损坏修复技巧

《游戏闪退弹窗提示找不到storm.dll文件怎么办?Stormdll文件损坏修复技巧》DLL文件丢失或损坏会导致软件无法正常运行,例如我们在电脑上运行软件或游戏时会得到以下提示:storm.dll... 很多玩家在打开游戏时,突然弹出“找不到storm.dll文件”的提示框,随后游戏直接闪退,这通常是由于

WinForm跨线程访问UI及UI卡死的解决方案

《WinForm跨线程访问UI及UI卡死的解决方案》在WinForm开发过程中,跨线程访问UI控件和界面卡死是常见的技术难题,由于Windows窗体应用程序的UI控件默认只能在主线程(UI线程)上操作... 目录前言正文案例1:直接线程操作(无UI访问)案例2:BeginInvoke访问UI(错误用法)案例

Spring Security常见问题及解决方案

《SpringSecurity常见问题及解决方案》SpringSecurity是Spring生态的安全框架,提供认证、授权及攻击防护,支持JWT、OAuth2集成,适用于保护Spring应用,需配置... 目录Spring Security 简介Spring Security 核心概念1. ​Securit

基于Python开发一个图像水印批量添加工具

《基于Python开发一个图像水印批量添加工具》在当今数字化内容爆炸式增长的时代,图像版权保护已成为创作者和企业的核心需求,本方案将详细介绍一个基于PythonPIL库的工业级图像水印解决方案,有需要... 目录一、系统架构设计1.1 整体处理流程1.2 类结构设计(扩展版本)二、核心算法深入解析2.1 自