图文混排

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

using System.Text.RegularExpressions;

using UnityEngine.UI;

public enum WidgetType{
    Text,
    Image
}

public class WidgetRow : System.Object{
    public List<WidgetInfo> widgetList = new List<WidgetInfo>();
}

public class WidgetInfo : System.Object {
    public WidgetType type;
    public int rowIndex;
    public Vector2 size; 
    public Vector2 anchorPos;
}

public class TextInfo : WidgetInfo {
    public Font font;
    public string text;
}

public class SpriteInfo : WidgetInfo {
    public string spriteName;
    public Sprite sprite;
}

public class GraphicMixed : MonoBehaviour {

    public Text copyText;
    public Image copyImage;

    public RectTransform mBackground;

    public List<WidgetInfo> widgetList = new List<WidgetInfo>();

    public List<WidgetRow> widgetRows = new List<WidgetRow>();

    Regex textureRegex = new Regex(@"{Texture([^:{}]*):([^{}]*)}");

    //{[^}]*}   大括号及大括号里
    //(?<={)[^{}]+(?=})  大括号里的

    private string testString = "sssssada{Texture:ico_utility_gold}sssssssssssssssss{Texture:ico_common_slsbtb3_press}abcdefghijklm{Texture:ico_utility_gold}nopqrstuvwxyzsssssssssssssssssssss{Texture:ico_utility_gold}";


    private float BACK_WIDTH;
    private Vector2 TRXT_PER_PIXELS_UNIT;

    // Use this for initialization
    void Start () {
        BACK_WIDTH = mBackground.sizeDelta.x;

        TRXT_PER_PIXELS_UNIT = GetTextSize("x");

        SetContent(testString);
    }

    // Update is called once per frame
    void Update () {

    }

    public void SetContent(string str){
        SplitMessage(str);

        InitList();

        UpdateWidgetRow();

        UpdateAnchorPosition();

        UpdateWidget();
    }

    private List<string> msgList = new List<string>();

    private void SplitMessage(string msg){
        Match match = textureRegex.Match(msg);

        if(!match.Success){
            msgList.Add(msg);
            return;
        }

        int startIndex = msg.IndexOf(match.Value);

        if(startIndex > 0){
            string text = msg.Substring(0, msg.IndexOf(match.Value));
            msgList.Add(text);
        }

        msgList.Add(match.Value);

        if(!string.IsNullOrEmpty( msg.Substring(startIndex + match.Value.Length)) ){
            SplitMessage( msg.Substring(startIndex + match.Value.Length) );
        }
    }

    private void InitList(){
        int rowIndex =0;
        float width = 0;

        foreach(string str in msgList){ 
            Match match = textureRegex.Match(str);
            if(!match.Success){
                InitText(str, ref width, ref rowIndex);
            }else{
                string name = match.Value.Remove(match.Value.Length -1 ).Substring(9);
                InitSprite(name, ref width , ref rowIndex);
            }
        }
    }

    private void InitSprite(string name, ref float width, ref int index){
        SpriteInfo spriteInfo = new SpriteInfo();

        Sprite sp = AssetManager.Instance.LoadSprite(AssetManager.AssetSprite(name));

        if(width + sp.rect.width > BACK_WIDTH){
            index ++;
            spriteInfo.type = WidgetType.Image;
            spriteInfo.rowIndex = index;
            spriteInfo.spriteName = name;
            spriteInfo.sprite = sp;
            spriteInfo.size = new Vector2(sp.rect.width, sp.rect.height);

            width = sp.rect.width;
        }else{
            spriteInfo.type = WidgetType.Image;
            spriteInfo.rowIndex = index;
            spriteInfo.spriteName = name;
            spriteInfo.sprite = sp;
            spriteInfo.size = new Vector2(sp.rect.width, sp.rect.height);

            width += sp.rect.width;

        }
        widgetList.Add(spriteInfo);
    }

    private void InitText(string str, ref float width, ref int index){


        Vector2 txtSize = GetTextSize(str);

        TextInfo txtInfo = new TextInfo();

        if(width + txtSize.x > BACK_WIDTH){
            float lastWidth = BACK_WIDTH - width;
            int charNum = CharNum4Width(str, lastWidth);

            txtInfo.type = WidgetType.Text;
            txtInfo.rowIndex = index;
            txtInfo.text = charNum > 0 ? str.Substring(0, charNum) : str;
            txtInfo.size = new Vector2(lastWidth, txtSize.y);

            widgetList.Add(txtInfo);

            index++;
            width = 0;  

            InitText(str.Substring(charNum), ref width, ref index);
        }else{
            txtInfo.type = WidgetType.Text;
            txtInfo.rowIndex = index;
            txtInfo.text = str;
            txtInfo.size = txtSize;

            width += txtSize.x;

            widgetList.Add(txtInfo);
        }
    }

    private int CharNum4Width(string str, float width){
        int num = 0;
        float _width = 0;
        foreach(char ch in str){
            _width += GetTextSize(ch.ToString()).x;

            if(_width > width){
                break;
            }
            num++;
        }
        return num;
    }

    private void UpdateWidgetRow(){
        int _rowdex = -1;

        WidgetRow row = new WidgetRow();
        for(int i = 0; i < widgetList.Count; i ++){
            if(widgetList[i].rowIndex != _rowdex){
                if(row.widgetList.Count > 0){
                    widgetRows.Add(row);
                    row = new WidgetRow();
                    row.widgetList.Clear();
                }
                row.widgetList.Add(widgetList[i]);
                _rowdex = widgetList[i].rowIndex;
            }else{
                row.widgetList.Add(widgetList[i]);
            }
        }
        widgetRows.Add(row);
    }

    private void UpdateAnchorPosition(){
        float anchorPosY = 0;
        foreach(WidgetRow row in widgetRows){
            float anchorPosX = 0;
            float maxY = 0;
            foreach(WidgetInfo widget in row.widgetList){
                if(widget.size.y > maxY){
                    maxY = widget.size.y;
                }
            }

            anchorPosY -= maxY;

            foreach(WidgetInfo widget in row.widgetList){
                widget.anchorPos.x = anchorPosX + widget.size.x*0.5f;
                widget.anchorPos.y = anchorPosY + maxY*0.5f;

                anchorPosX += widget.size.x;
            }
        }
    }

    private void UpdateWidget(){

        foreach(WidgetRow row in widgetRows){
            foreach(WidgetInfo widget in row.widgetList){
                if(widget.type == WidgetType.Text){
                    GameObject go = Instantiate(copyText.gameObject) as GameObject;
                    go.SetActive(true);
                    go.transform.SetParent(mBackground);
                    go.transform.localScale = Vector3.one;
                    go.transform.localPosition = Vector3.zero;

                    TextInfo tInfo = widget as TextInfo;

                    Text txt = go.GetComponent<Text>();

                    txt.text = tInfo.text;

                    txt.rectTransform.sizeDelta = tInfo.size;
                    txt.rectTransform.anchorMin = new Vector2(0, 1); 
                    txt.rectTransform.anchorMax = new Vector2(0, 1); 

                    txt.rectTransform.anchoredPosition = widget.anchorPos;

                }else if (widget.type == WidgetType.Image){
                    GameObject go = Instantiate(copyImage.gameObject) as GameObject;
                    go.SetActive(true);
                    go.transform.SetParent(mBackground);
                    go.transform.localScale = Vector3.one;
                    go.transform.localPosition = Vector3.zero;

                    SpriteInfo sInfo = widget as SpriteInfo;

                    Image sprite = go.GetComponent<Image>();

                    sprite.sprite = sInfo.sprite;

                    sprite.rectTransform.sizeDelta = sInfo.size;
                    sprite.rectTransform.anchorMin = new Vector2(0, 1); 
                    sprite.rectTransform.anchorMax = new Vector2(0, 1); 

                    sprite.rectTransform.anchoredPosition = widget.anchorPos;
                }
            }
        }
    }

    private Vector2 GetTextSize(string text){
        TextGenerator  tg = new TextGenerator (); 
        TextGenerationSettings settingsW = copyText.GetGenerationSettings (Vector2.zero);//txt是用来显示Text组件 
        float width = tg.GetPreferredWidth (text, settingsW);   //获得文本的宽度

        return new Vector2(width/copyText.pixelsPerUnit, 30);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值