700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Unity UGUI图文混排源码(二)

Unity UGUI图文混排源码(二)

时间:2020-03-10 15:16:48

相关推荐

Unity UGUI图文混排源码(二)

Unity UGUI图文混排源码(一):/qq992817263/article/details/51112304

Unity UGUI图文混排源码(二):/qq992817263/article/details/51112311

为了方便整理,申请了一个专栏,链接:Unity UGUI图文混排专栏

图文混排解决方案二:

通过继承Text组件来获取文字的UIVertex并得到他的位置,通过Text富文本的<quad />来为图片占位,这样来实现图文混排,这里参考了一篇博客:/akof1314/article/details/49028279

1.这里我们会使用到一个SpriteAsset,具体的创建方法:/qq992817263/article/details/50958025

2.自定义一个渲染组件,用来渲染图片,后面我会将他放在Text文本下,这里会用一个参数,就是上面的SpriteAsset文件,具体代码如下

usingUnityEngine;usingUnityEngine.UI;usingSystem.Collections;publicclassSpriteGraphic:MaskableGraphic{publicSpriteAssetm_spriteAsset;publicoverrideTexturemainTexture{get{if(m_spriteAsset==null)returns_WhiteTexture;if(m_spriteAsset.texSource==null)returns_WhiteTexture;elsereturnm_spriteAsset.texSource;}}#ifUNITY_EDITOR//在编辑器下protectedoverridevoidOnValidate(){base.OnValidate();//Debug.Log("TextureIDis"+this.texture.GetInstanceID());}#endifprotectedoverridevoidOnRectTransformDimensionsChange(){//base.OnRectTransformDimensionsChange();}///<summary>///绘制后需要更新材质///</summary>publicnewvoidUpdateMaterial(){base.UpdateMaterial();}}

3.自定义一个脚本用来继承Text,这里就是一个较为核心的代码,里面写了较为详细的注释

usingUnityEngine;usingUnityEngine.UI;usingSystem.Collections.Generic;usingSystem.Text.RegularExpressions;publicclassInlieText:Text{///<summary>///用正则取标签属性名称-大小-宽度比例///</summary>privatestaticreadonlyRegexm_spriteTagRegex=newRegex(@"<quadname=(.+?)size=(\d*\.?\d+%?)width=(\d*\.?\d+%?)/>",RegexOptions.Singleline);///<summary>///需要渲染的图片信息列表///</summary>privateList<InlineSpriteInfor>listSprite;///<summary>///图片资源///</summary>privateSpriteAssetm_spriteAsset;///<summary>///标签的信息列表///</summary>privateList<SpriteTagInfor>listTagInfor;///<summary>///图片渲染组件///</summary>privateSpriteGraphicm_spriteGraphic;///<summary>///CanvasRenderer///</summary>privateCanvasRendererm_spriteCanvasRenderer;///<summary>///初始化///</summary>protectedoverridevoidOnEnable(){base.OnEnable();if(m_spriteGraphic==null)m_spriteGraphic=GetComponentInChildren<SpriteGraphic>();if(m_spriteCanvasRenderer==null)m_spriteCanvasRenderer=m_spriteGraphic.GetComponentInChildren<CanvasRenderer>();m_spriteAsset=m_spriteGraphic.m_spriteAsset;}///<summary>///在设置顶点时调用///</summary>publicoverridevoidSetVerticesDirty(){base.SetVerticesDirty();//解析标签属性listTagInfor=newList<SpriteTagInfor>();foreach(Matchmatchinm_spriteTagRegex.Matches(text)){SpriteTagInfortempSpriteTag=newSpriteTagInfor();tempSpriteTag.name=match.Groups[1].Value;tempSpriteTag.index=match.Index;tempSpriteTag.size=newVector2(float.Parse(match.Groups[2].Value)*float.Parse(match.Groups[3].Value),float.Parse(match.Groups[2].Value));listTagInfor.Add(tempSpriteTag);}}///<summary>///绘制模型///</summary>///<paramname="toFill"></param>protectedoverridevoidOnPopulateMesh(VertexHelpertoFill){base.OnPopulateMesh(toFill);//获取所有的UIVertex,绘制一个字符对应6个UIVertex,绘制顺序为012203List<UIVertex>listUIVertex=newList<UIVertex>();toFill.GetUIVertexStream(listUIVertex);//通过标签信息来设置需要绘制的图片的信息listSprite=newList<InlineSpriteInfor>();for(inti=0;i<listTagInfor.Count;i++){//UGUIText不支持<quad/>标签,表现为乱码,我这里将他的uv全设置为0,清除乱码for(intm=listTagInfor[i].index*6;m<listTagInfor[i].index*6+6;m++){UIVertextempVertex=listUIVertex[m];tempVertex.uv0=Vector2.zero;listUIVertex[m]=tempVertex;}InlineSpriteInfortempSprite=newInlineSpriteInfor();//如果图片在第一个位置,则计算他的位置为文本的初始点位置//否,则返回上一个字符的第三个UIVertex的position,这是根据他的顶点的绘制顺序所获得的if(listTagInfor[i].index==0){Vector2anchorPivot=GetTextAnchorPivot(alignment);Vector2rectSize=rectTransform.sizeDelta;tempSprite.textpos=-rectSize/2.0f+newVector2(rectSize.x*anchorPivot.x,rectSize.y*anchorPivot.y-listTagInfor[i].size.y);}elsetempSprite.textpos=listUIVertex[listTagInfor[i].index*6-4].position;//设置图片的位置tempSprite.vertices=newVector3[4];tempSprite.vertices[0]=newVector3(0,0,0)+tempSprite.textpos;tempSprite.vertices[1]=newVector3(listTagInfor[i].size.x,listTagInfor[i].size.y,0)+tempSprite.textpos;tempSprite.vertices[2]=newVector3(listTagInfor[i].size.x,0,0)+tempSprite.textpos;tempSprite.vertices[3]=newVector3(0,listTagInfor[i].size.y,0)+tempSprite.textpos;//计算其uvRectspriteRect=m_spriteAsset.listSpriteInfor[0].rect;for(intj=0;j<m_spriteAsset.listSpriteInfor.Count;j++){//通过标签的名称去索引spriteAsset里所对应的sprite的名称if(listTagInfor[i].name==m_spriteAsset.listSpriteInfor[j].name)spriteRect=m_spriteAsset.listSpriteInfor[j].rect;}Vector2texSize=newVector2(m_spriteAsset.texSource.width,m_spriteAsset.texSource.height);tempSprite.uv=newVector2[4];tempSprite.uv[0]=newVector2(spriteRect.x/texSize.x,spriteRect.y/texSize.y);tempSprite.uv[1]=newVector2((spriteRect.x+spriteRect.width)/texSize.x,(spriteRect.y+spriteRect.height)/texSize.y);tempSprite.uv[2]=newVector2((spriteRect.x+spriteRect.width)/texSize.x,spriteRect.y/texSize.y);tempSprite.uv[3]=newVector2(spriteRect.x/texSize.x,(spriteRect.y+spriteRect.height)/texSize.y);//声明三角顶点所需要的数组tempSprite.triangles=newint[6];listSprite.Add(tempSprite);}//清除<quad/>标签的乱码重新绘制toFill.Clear();toFill.AddUIVertexTriangleStream(listUIVertex);DrawSprite();}///<summary>///绘制图片///</summary>voidDrawSprite(){Meshm_spriteMesh=newMesh();List<Vector3>tempVertices=newList<Vector3>();List<Vector2>tempUv=newList<Vector2>();List<int>tempTriangles=newList<int>();for(inti=0;i<listSprite.Count;i++){for(intj=0;j<listSprite[i].vertices.Length;j++){tempVertices.Add(listSprite[i].vertices[j]);}for(intj=0;j<listSprite[i].uv.Length;j++){tempUv.Add(listSprite[i].uv[j]);}for(intj=0;j<listSprite[i].triangles.Length;j++){tempTriangles.Add(listSprite[i].triangles[j]);}}//计算顶点绘制顺序for(inti=0;i<tempTriangles.Count;i++){if(i%6==0){intnum=i/6;tempTriangles[i]=0+4*num;tempTriangles[i+1]=1+4*num;tempTriangles[i+2]=2+4*num;tempTriangles[i+3]=1+4*num;tempTriangles[i+4]=0+4*num;tempTriangles[i+5]=3+4*num;}}m_spriteMesh.vertices=tempVertices.ToArray();m_spriteMesh.uv=tempUv.ToArray();m_spriteMesh.triangles=tempTriangles.ToArray();if(m_spriteMesh==null)return;m_spriteCanvasRenderer.SetMesh(m_spriteMesh);m_spriteGraphic.UpdateMaterial();}}[System.Serializable]publicclassSpriteTagInfor{///<summary>///sprite名称///</summary>publicstringname;///<summary>///对应的字符索引///</summary>publicintindex;///<summary>///大小///</summary>publicVector2size;}[System.Serializable]publicclassInlineSpriteInfor{//文字的最后的位置publicVector3textpos;//4顶点publicVector3[]vertices;//4uvpublicVector2[]uv;//6三角顶点顺序publicint[]triangles;}

4.开始测试效果,创建一个InlieText组件,并在其组件下,添加一个SpriteGraphic组件,输入文字加标签测试

InlieTex组件:

SpriteGraphic组件:

文字测试:

5.做了一个聊天测试:

6.同时在测试的时候就发现了些许bug,这里并不想写出来,有兴趣的可以一起修改讨论。

工程使用的unity版本为unity的版本为:5.3.1f1

最后给出工程链接:/qq992817263/uguitextpro/tree/master

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。