【Unity3D游戏开发】基于NGUI的表情图文混排解决方案 (二二)
来源:互联网 发布:淘宝联盟怎么赚取佣金 编辑:程序博客网 时间:2024/05/24 05:16
使用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*30
- if (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);
- }
- }
- }
- }
原文链接:http://www.manew.com/blog-3649-2595.html
参考文章:NGUI研究院之有点坑爹的图文混排(十四)
0 0
- 【Unity3D游戏开发】基于NGUI的表情图文混排解决方案 (二二)
- 【Unity3D游戏开发】基于NGUI的表情图文混排解决方案 (二二)
- 【Unity3D游戏开发】基于NGUI的表情图文混排解决方案 (二二)
- 【Unity3D游戏开发】基于NGUI的表情图文混排解决方案 (二二)
- Unity3D NGUI图文混排聊天表情
- unity3D游戏开发十五之NGUI二
- unity3D游戏开发十五之NGUI二
- unity3D游戏开发十五之NGUI二
- Swift3.0 功能二 (表情键盘与图文混排)
- NGUI的图文混排
- 【Unity3D游戏开发】NGUI之不相对于Anchor的位移动画TweenPosition (上) (二)
- 【Unity3D游戏开发】NGUI制作字体的三种方法 (二一)
- NGUI图文混排
- Unity3D 基于UGUI的图文混排组件
- [Unity3D学习]NGUI UILabel 图文混排扩展
- NGUI之图文混排
- unity NGUI图文混排
- IOS总结_实现UIButton的图文混排(二)
- java中堆和栈详解
- 混淆打包
- java中InputStream转化为byte[]数组
- 一个由PROGUARD与FASTJSON引起的血案
- java对象与字符串之间的序列化和反序列化
- 【Unity3D游戏开发】基于NGUI的表情图文混排解决方案 (二二)
- 浅谈Linux下的五种I/O模型
- mybatis-generator自定义注释生成
- 关于分布式事务那点事
- iOS开发通知那些事
- 行为型模式11之4-Chain of Responsibility责任链模式例子理解
- 基础概念1
- 交叉销售功能介绍-功能
- 网络的理解