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

来源:互联网 发布:java splitstring 编辑:程序博客网 时间:2024/05/22 08:07
 1.定义一个标准行宽度,以此作为基准对文字以及表情进行分行处理;
    2.使用特殊符号标记表情(例如:#e001),遍历字符串,凡遇到表情标记则将之与位置记录下来,并使用“ ”(空格,具体数量视表情大小而定)将特殊标记替换。
    3.使用Vector3记录以上信息,x为表情的横坐标,y为表情所在行数(即纵坐标),z为表情的ID,即刚才的001,以此确定是哪个表情。使用一个List将所有表情信息存放起来,显示时遍历List即可。
    有了以上基本思路,下面只要编码实现,但是在编码过程中还是不可避免的问题——如何得到一段文字的长度?这时,就需要用到一个NGUI封装的一个方法NGUIText.CalculatePrintedSize传入参数为string,返回一个Vector2,表示这段文字的长和宽。下面是核心代码。

[code]csharpcode:

[csharp] view plain copy
  1. protected void CalculateExpressionPos(ref string text)  
  2. {  
  3.    NGUIText.finalSize = m_chatInput.label.defaultFontSize;//设置当前使用字体大小  
  4.    lineList.Clear();  
  5.    int row = 0;  
  6.    int textWidth = 0;  
  7.    int lastStartIndex = 0;  
  8.    string curLine = "";  
  9.    int length = text.Length;  
  10.    for (int i = 0; i < length; i++)  
  11.    {   
  12.       if (text[i] == '#' && i + 4 < length && text[i + 1] == 'e')  
  13.       {  
  14.          string eName = text.Substring(i + 2, 3);  
  15.          int eIndex = 0;  
  16.          Vector3 ePos = Vector3.zero;  
  17.          if (int.TryParse(eName, out eIndex))  
  18.          {  
  19.             float fx = 0;  
  20.   
  21.             text = text.Remove(i, 5);  
  22.             text = text.Insert(i, space);//space = "       ";  
  23.             length = text.Length;  
  24.             //这里的CalculatePrintedSize是重载过的,  
  25.             //与原本方法相比多的一个参数自定义行款,替换原方法中的rectWidth即可  
  26.             textWidth = Mathf.RoundToInt(  
  27.                NGUIText.CalculatePrintedSize(  
  28.                text.Substring(lastStartIndex, i - lastStartIndex),  
  29.                BASELINEWIDTH + 30).x);  
  30.              //BASELINEWIDTH为标准行宽度,30是根据表情大小确定的,  
  31.              //这里的表情大小是30*30  
  32.              if (textWidth > BASELINEWIDTH - 30)           
  33.              {  
  34.                 curLine = text.Substring(lastStartIndex, i - lastStartIndex + 1);  
  35.                 lineList.Add(curLine);  
  36.   
  37.                 if (textWidth <= BASELINEWIDTH - 15 ||  
  38.                     textWidth >= BASELINEWIDTH)//行末尾不够需换行  
  39.                 {  
  40.                    fx = 0;  
  41.                    row++;  
  42.                    lastStartIndex = i;  
  43.                    ePos.x = fx - m_offsetX;  
  44.                    ePos.y = row;  
  45.                    ePos.z = eIndex;  
  46.                 }  
  47.                 else   //行末尾足够不需换行  
  48.                 {  
  49.                    fx = textWidth;  
  50.                    lastStartIndex = i + space.Length;  
  51.                    ePos.x = fx - m_offsetX;  
  52.                    ePos.y = row;  
  53.                    ePos.z = eIndex;  
  54.                    row++;  
  55.                 }  
  56.              }  
  57.              else  
  58.              {  
  59.                 fx = textWidth;  
  60.                 ePos.x = fx - m_offsetX;  
  61.                 ePos.y = row;  
  62.                 ePos.z = eIndex;  
  63.              }  
  64.          }  
  65.          if (eIndex != 0)  
  66.          {  
  67.             eList.Add(ePos);  
  68.          }  
  69.   
  70.          if (!expInLine.ContainsKey(row))        //有表情无表情行,以此确定行间距  
  71.          {  
  72.             expInLine.Add(row, true);  
  73.          }  
  74.       }  
  75.       else      //记录换行起始Index  
  76.       {  
  77.          if (i - lastStartIndex < 0) continue;  
  78.   
  79.          float curWidth = Mathf.RoundToInt(  
  80.             NGUIText.CalculatePrintedSize(  
  81.             text.Substring(lastStartIndex, i - lastStartIndex + 1),  
  82.             BASELINEWIDTH + 30).x);  
  83.          if (curWidth > BASELINEWIDTH)  
  84.          {  
  85.             curLine = text.Substring(lastStartIndex, i - lastStartIndex + 1);  
  86.             lineList.Add(curLine);  
  87.             lastStartIndex = i + 1;  
  88.             row++;  
  89.          }  
  90.   
  91.          if (i == length - 1)  
  92.          {  
  93.             if (i - lastStartIndex < 0) continue;  
  94.   
  95.             curLine = text.Substring(lastStartIndex, i - lastStartIndex + 1);  
  96.             lineList.Add(curLine);  
  97.          }  
  98.       }  
  99.    }  
  100. }  
      经过以上处理,输出的lineList即为聊天内容,eList为表情信息,expInLine字典存放每行是否存在表情信息。将表情图标打入一个图集,命名为001_1、001_2。。。在显示表情时使用UISpriteAnimation脚本可实现动态表情。最终效果如下:
                                                                                         
0 0
原创粉丝点击