NGUI之图文混排

  大家好!我是小唐,最近比较忙没有写东西出来,最近在做游戏的过程中,游戏里面的一些公告面板啊,聊天的面板,都是文本和图片穿插的,开始的时候不知道怎么去搞这个东西,也是网上去逛了一下,然后看了一下网上的东西,感觉很难理解,有些地方不知道什么意思,所以干脆一点还是自己写了一套,然后里面的注释我写的很清楚,一看就明白什么意思啦!把代码分享给大家!

代码如下:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class TextExpression : MonoBehaviour 
{
    public Font UIFont;       
    public int FontSize;
    public int Depth;
    public int MaxWidth;        //显示文本的最大宽度
    public int PositionX;       //现实图文的X坐标
    public int LablePositionY;  //不同行文本排列的高度
    public int ImagePositionY;  //不同行图片排列的高度

    GameObject Prefab;          //显示的图片等待Prefab
    int ImageHeight;            //图片的高度
    float TextHeight;           //同一行文本排列时的高度
    List LableCaches;  //文字的缓存
    List ImageCaches; //图片的缓存
    int LastLineTextHeight;     //记录上一行文本的高度

    //每次截取之后剩下的字符串数据
    string NewStr=string.Empty;
    
    void Awake()
    {
        //初始化数据
        UIFont = Resources.Load("UI/Atlas/Font/FZY3JW") as Font;
        Prefab = Resources.Load("UI/UIData/Expression") as GameObject;
        FontSize = 20;
        UIPanel panel=gameObject.GetComponent();
        Depth = panel.depth + 1;
        MaxWidth = (int)panel.width;
        PositionX = 0;
        LablePositionY = 0;
        ImagePositionY = 0;
        ImageHeight = Prefab.GetComponent().height;

        LableCaches = new List();
        ImageCaches = new List();
    }

    void Start()
    {
        CreateAllInfo(strtest);
    }

    //test:

    string strtest= "Test:{01}{02}{03}{04}{05}这就是聊天记录,不知道有什么问题。嘿呀,哟呼。哈哈。嘿嘿!"+
                    "Test:{01}{02}{03}{04}{05}这就是聊天记录,不知道有什么问题。嘿呀,哟呼。哈哈。嘿嘿!"+
                    "Test:{01}{02}{03}{04}{05}这就是聊天记录,不知道有什么问题。嘿呀,哟呼。哈哈。嘿嘿!"+
                    "Test:{01}{02}{03}{04}{05}这就是聊天记录,不知道有什么问题。嘿呀,哟呼。哈哈。嘿嘿!"+
                    "Test:{01}{02}{03}{04}{05}这就是聊天记录,不知道有什么问题。嘿呀,哟呼。哈哈。嘿嘿!";
   
    /// 
    /// 创建文本中的Lable
    /// 
    /// 当前显示的字符串.
    /// 截取后新的字符串.
    void CreateTextLable(string currentStr)
    {
        GameObject obj = NGUITools.AddChild(gameObject);
        obj.name="Lable";
        UILabel lable=obj.AddComponent();
        lable.trueTypeFont = UIFont;
        lable.fontSize = FontSize;
        lable.overflowMethod = UILabel.Overflow.ResizeHeight;
        lable.depth = Depth;
        lable.maxLineCount = 1;
        lable.width = MaxWidth-PositionX;
        lable.pivot = UIWidget.Pivot.TopLeft;
        obj.transform.localPosition = new Vector3(PositionX,LablePositionY,0);
        lable.text = currentStr;
        string subStr = lable.processedText;
        lable.text = subStr;
        lable.width = (int)lable.printedSize.x;
        PositionX += lable.width;

        //临时的Lable缓存
        LableCaches.Add(lable);

        //文本中包含换行符/n的处理
        NewLineDeal(currentStr,lable);

        //如果当前的内容为空则直接返回CreateAllInfo()方法
        if (currentStr.Equals(""))
        {
            CreateAllInfo(NewStr);
        }

        //根据lable.processedText判断是否当前内容显示完整
        currentStr = currentStr.Remove(0,subStr.Length);

        //当前显示的字符串整好显示完整换行
        if (lable.width+FontSize>=MaxWidth && currentStr.Length==0)
        {
            LineSort();
        }

        //检测当前显示的字符串是否需要换行(当前字符串未显示完成换行)
        if (currentStr.Length > 0)
        {
            LineSort();
            //继续创建未完成的Lable
            CreateTextLable(currentStr);
        }

        NewStrDeal();
    }

    /// 
    /// 创建文本中的Image
    /// 
    /// 当前显示的字符串.
    /// 截取后新的字符串.
    void CreateTextImage(string currentStr)
    {
        GameObject obj = NGUITools.AddChild(gameObject,Prefab);
        obj.name = "Sprite";
        UISprite sprite=obj.GetComponent();
        sprite.pivot = UIWidget.Pivot.TopLeft;
        sprite.spriteName = currentStr;
        //生成这个图片之后的X的位置
        int LastPositionX = PositionX + sprite.width;

        //临时的图片缓存
        ImageCaches.Add(sprite);

        //检测图片到这一行末尾换行的情况
        if (LastPositionX + sprite.width > MaxWidth)
        {
            obj.transform.localPosition = new Vector3(PositionX,ImagePositionY,0);
            LineSort();
        }
        else
        {
            obj.transform.localPosition = new Vector3(PositionX,ImagePositionY,0);
            PositionX += sprite.width;
        }

        NewStrDeal();
    }

    /// 
    /// 创建图文信息
    /// 
    /// 需要创建的字符串
    void CreateAllInfo(string str)
    {
        if (string.IsNullOrEmpty(str))
            return;

        //记录特殊字符的开始和结束的位置(图片的特殊字符标识)
        int StartIndex = str.IndexOf("{");
        int EndIndex = str.IndexOf("}");

        //取得标识图片字符中图片的ID
        string ImageID = str.Substring(StartIndex+1,2);

        //检测字符串中是否含有Image,如果没有则返回-1
        if (StartIndex > -1)
        {
            string text = str.Substring(0,StartIndex);
            if (string.IsNullOrEmpty(text)) 
            {
                //获取当前截取的字符串代表的图片
                NewStr=str.Remove(StartIndex,EndIndex+1);
                CreateTextImage(ImageID);
            }
            else
            {
                //获取当前截取的字符串内容
                NewStr=str.Remove(0,StartIndex);
                CreateTextLable(text);
            }
        }
        else
        {
            //获取当前截取的字符串内容
            NewStr=str.Remove(0,str.Length);
            CreateTextLable(str);
        }
    }

    /// 
    /// 对文本和图片混合的行进行Y轴的对齐排序
    /// 
    void LineSort()
    {
        //当前这一行文本中图文混合排序的情况
        if (ImageCaches.Count > 0 && LableCaches.Count > 0)
        {
            for (int i = 0; i < LableCaches.Count; i++)
            {
                //当前文本的高度根绝图片对齐
                TextHeight = ImageCaches [0].transform.localPosition.y - (ImageHeight - FontSize);
                //坐标排列,这里只对文字进行排列,所有的排列都是以图片为标准的(因为大多数的情况都是图片的高度大于或者等于文字的高度)
                LableCaches [i].transform.localPosition = new Vector3(LableCaches [i].transform.localPosition.x, TextHeight, 0);
            }
            //记录下当前文本的高度
            LastLineTextHeight = (int)LableCaches [0].transform.localPosition.y;
            //排序完成后清空缓存数据
            LableCaches.Clear();
            ImageCaches.Clear();

            //设置下一行的文本和图片的高度
            PositionX = 0;
            LablePositionY = LastLineTextHeight - FontSize;
            ImagePositionY = LastLineTextHeight-FontSize;
        }
        else
        {
            //当前这一行文本中纯文字排序的情况
            if (LableCaches.Count>0)
            {
                //这里是第一行的特殊处理
                if (LablePositionY==0)
                {
                    TextHeight = LastLineTextHeight;
                }
                else
                {
                    TextHeight = LastLineTextHeight - FontSize;
                }
                //排序
                for (int i = 0; i < LableCaches.Count; i++)
                {
                    LableCaches [i].transform.localPosition = new Vector3(LableCaches [i].transform.localPosition.x, TextHeight, 0);
                }
                //设置下一行的文本和图片的高度
                LastLineTextHeight=(int)LableCaches [0].transform.localPosition.y;
                //清除Lable缓存
                LableCaches.Clear();
                //设置下一行的坐标
                PositionX = 0;
                LablePositionY = LastLineTextHeight - FontSize;
                ImagePositionY = LastLineTextHeight-FontSize;
            }
            //当前这一行文本中纯图片排序的情况
            if(ImageCaches.Count>0)
            {
                //这里是第一行的特殊处理
                if (ImagePositionY==0)
                {
                    TextHeight = LastLineTextHeight;
                }
                else
                {
                    TextHeight = LastLineTextHeight - ImageHeight;
                }
                //排序
                for (int i = 0; i < ImageCaches.Count; i++)
                {
                    ImageCaches [i].transform.localPosition = new Vector3(ImageCaches [i].transform.localPosition.x, TextHeight, 0);
                }
                //设置下一行的文本和图片的高度
                LastLineTextHeight=(int)ImageCaches [0].transform.localPosition.y;
                //清除Image缓存
                ImageCaches.Clear();
                //设置下一行的坐标
                PositionX = 0;
                LablePositionY = LastLineTextHeight - ImageHeight;
                ImagePositionY = LastLineTextHeight-ImageHeight;
            }
        }
    }

    /// 
    /// 新字符串的处理
    /// 
    void NewStrDeal()
    {
        //获取截取的字符串为空时,则说明字符串最后一行创建完成
        if (string.IsNullOrEmpty(NewStr))
        {
            LineSort();
            return;
        }
        //如果NewStr不为空,则说明还未创建完要继续创建
        if (NewStr.Length>0)
        {
            CreateAllInfo(NewStr);
        }
    }

    /// 
    /// 文本中包含换行符/n的处理
    /// 
    /// 当前显示的字符串
    /// 显示的Lable
    void NewLineDeal(string currentStr,UILabel lable)
    {
        if (currentStr.Contains("/n"))
        {
            int NewLineIndex=currentStr.IndexOf("/n");
            
            string CurrentLineText=currentStr.Substring(0,NewLineIndex+2);
            //替换/n为空
            CurrentLineText=CurrentLineText.Replace("/n","");
            //新一行的内容
            string NewLineText=currentStr.Remove(0,NewLineIndex+2);
            lable.text=CurrentLineText;
            LineSort();
            //当前的内容不为空时,创建新一行的内容
            if (!string.IsNullOrEmpty(CurrentLineText))
            {
                CreateTextLable(NewLineText);
            }
        }
    }
}

效果图如下:

NGUI之图文混排_第1张图片

看看吧,看着还可以!有什么不好的地方和值得优化的地方多多提宝贵意见,谢谢!

你可能感兴趣的:(Unity,UI)