【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

相关文章

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

C#文件复制异常:"未能找到文件"的解决方案与预防措施

《C#文件复制异常:未能找到文件的解决方案与预防措施》在C#开发中,文件操作是基础中的基础,但有时最基础的File.Copy()方法也会抛出令人困惑的异常,当targetFilePath设置为D:2... 目录一个看似简单的文件操作问题问题重现与错误分析错误代码示例错误信息根本原因分析全面解决方案1. 确保

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

基于Java开发一个极简版敏感词检测工具

《基于Java开发一个极简版敏感词检测工具》这篇文章主要为大家详细介绍了如何基于Java开发一个极简版敏感词检测工具,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录你是否还在为敏感词检测头疼一、极简版Java敏感词检测工具的3大核心优势1.1 优势1:DFA算法驱动,效率提升10

SpringBoot3匹配Mybatis3的错误与解决方案

《SpringBoot3匹配Mybatis3的错误与解决方案》文章指出SpringBoot3与MyBatis3兼容性问题,因未更新MyBatis-Plus依赖至SpringBoot3专用坐标,导致类冲... 目录SpringBoot3匹配MyBATis3的错误与解决mybatis在SpringBoot3如果

C++ vector越界问题的完整解决方案

《C++vector越界问题的完整解决方案》在C++开发中,std::vector作为最常用的动态数组容器,其便捷性与性能优势使其成为处理可变长度数据的首选,然而,数组越界访问始终是威胁程序稳定性的... 目录引言一、vector越界的底层原理与危害1.1 越界访问的本质原因1.2 越界访问的实际危害二、基

Python 字符串裁切与提取全面且实用的解决方案

《Python字符串裁切与提取全面且实用的解决方案》本文梳理了Python字符串处理方法,涵盖基础切片、split/partition分割、正则匹配及结构化数据解析(如BeautifulSoup、j... 目录python 字符串裁切与提取的完整指南 基础切片方法1. 使用切片操作符[start:end]2

Python开发简易网络服务器的示例详解(新手入门)

《Python开发简易网络服务器的示例详解(新手入门)》网络服务器是互联网基础设施的核心组件,它本质上是一个持续运行的程序,负责监听特定端口,本文将使用Python开发一个简单的网络服务器,感兴趣的小... 目录网络服务器基础概念python内置服务器模块1. HTTP服务器模块2. Socket服务器模块