【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

相关文章

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

python 字典d[k]中key不存在的解决方案

《python字典d[k]中key不存在的解决方案》本文主要介绍了在Python中处理字典键不存在时获取默认值的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录defaultdict:处理找不到的键的一个选择特殊方法__missing__有时候为了方便起见,

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

Linux限制ip访问的解决方案

《Linux限制ip访问的解决方案》为了修复安全扫描中发现的漏洞,我们需要对某些服务设置访问限制,具体来说,就是要确保只有指定的内部IP地址能够访问这些服务,所以本文给大家介绍了Linux限制ip访问... 目录背景:解决方案:使用Firewalld防火墙规则验证方法深度了解防火墙逻辑应用场景与扩展背景:

SpringBoot嵌套事务详解及失效解决方案

《SpringBoot嵌套事务详解及失效解决方案》在复杂的业务场景中,嵌套事务可以帮助我们更加精细地控制数据的一致性,然而,在SpringBoot中,如果嵌套事务的配置不当,可能会导致事务不生效的问题... 目录什么是嵌套事务?嵌套事务失效的原因核心问题:嵌套事务的解决方案方案一:将嵌套事务方法提取到独立类

Spring Boot实现多数据源连接和切换的解决方案

《SpringBoot实现多数据源连接和切换的解决方案》文章介绍了在SpringBoot中实现多数据源连接和切换的几种方案,并详细描述了一个使用AbstractRoutingDataSource的实... 目录前言一、多数据源配置与切换方案二、实现步骤总结前言在 Spring Boot 中实现多数据源连接

MySQL的索引失效的原因实例及解决方案

《MySQL的索引失效的原因实例及解决方案》这篇文章主要讨论了MySQL索引失效的常见原因及其解决方案,它涵盖了数据类型不匹配、隐式转换、函数或表达式、范围查询、LIKE查询、OR条件、全表扫描、索引... 目录1. 数据类型不匹配2. 隐式转换3. 函数或表达式4. 范围查询之后的列5. like 查询6

使用Vue.js报错:ReferenceError: “Vue is not defined“ 的原因与解决方案

《使用Vue.js报错:ReferenceError:“Vueisnotdefined“的原因与解决方案》在前端开发中,ReferenceError:Vueisnotdefined是一个常见... 目录一、错误描述二、错误成因分析三、解决方案1. 检查 vue.js 的引入方式2. 验证 npm 安装3.

C#图表开发之Chart详解

《C#图表开发之Chart详解》C#中的Chart控件用于开发图表功能,具有Series和ChartArea两个重要属性,Series属性是SeriesCollection类型,包含多个Series对... 目录OverviChina编程ewSeries类总结OverviewC#中,开发图表功能的控件是Char

PHP执行php.exe -v命令报错的解决方案

《PHP执行php.exe-v命令报错的解决方案》:本文主要介绍PHP执行php.exe-v命令报错的解决方案,文中通过图文讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下... 目录执行phpandroid.exe -v命令报错解决方案执行php.exe -v命令报错-PHP War