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);
}
}
图文混排
最新推荐文章于 2023-04-17 10:26:42 发布