【Unity3D】UGUI获取图片网格、文本网格大小、位置(Rect)

cs 复制代码
   public static void CalcualteGraphicRect(Graphic graphic, ref Rect rect)
        {
            Vector2 size = Vector2.zero;
 
            Text textComponent = graphic as Text;
            if (textComponent != null)
            {
                List<UIVertex> textUIVertexList = new List<UIVertex>();
                textUIVertexList = textComponent.cachedTextGenerator.verts as List<UIVertex>;
                //textComponent.cachedTextGenerator.GetVertices(textUIVertexList);                
                float minX = float.MaxValue;
                float maxX = float.MinValue;
                float minY = float.MaxValue;
                float maxY = float.MinValue;
 
                //使用center计算出中心点后,你还需要转空间,这个转空间一直出问题,所以不采用这种办法
                //Vector3 center = Vector3.zero;
 
                Vector3 minPos = Vector3.zero;
                Vector3 maxPos = Vector3.zero;
 
                string str = "";
                for (int i = 0; i < textUIVertexList.Count; i++)
                {
                    Vector3 pos = textUIVertexList[i].position;
                    minX = Mathf.Min(minX, pos.x);
                    maxX = Mathf.Max(maxX, pos.x);
                    minY = Mathf.Min(minY, pos.y);
                    maxY = Mathf.Max(maxY, pos.y);
 
                    minPos = Vector3.Min(minPos, pos);
                    maxPos = Vector3.Max(maxPos, pos);
 
                    //center += pos;
                    str += pos + " ";
                }
                size.x = maxX - minX;
                size.y = maxY - minY;
                //center /= textUIVertexList.Count; 
 
                //转空间会有问题 不采用计算中心点 而是直接算出以文本空间(中心点是文本坐标点rect.position)的网格中心点。
                //转空间就是直接用 网格中心点 + 文本坐标点,将网格中心点转到 文本所在空间(Canvas空间系下) 将其作为Rect区域的中心点去计算网格相交
 
                Vector2 rawPos = rect.position;
                //解决偏移问题,根据MinX MaxX  MinY MaxY 求出局部中心点, 用文本中心点rect.position加上局部中心点就能得到真正的文本网格中心点
                Vector2 offset = new Vector2(((minX + maxX) / 2.0f), ((minY + maxY) / 2.0f));
                rect.position += offset;
                Debug.Log("rawPos:" + rawPos + " afterPos:" + rect.position + "offset:" + offset);
                Debug.Log(graphic.gameObject.name + " " + size + "\n" + str);
            }
            else
            {
                Image imageComponent = graphic as Image;
                RectTransform r = imageComponent.GetComponent<RectTransform>();
 
                //只能编辑器读资源来获取MeshType,其他方式都试过不行...
                string path = AssetDatabase.GetAssetPath(imageComponent.sprite);
                TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
                TextureImporterSettings settings = new TextureImporterSettings();
                textureImporter.ReadTextureSettings(settings);
 
                //if (imageComponent.overrideSprite.packingMode == SpritePackingMode.Tight) //不能用这个packingMode判断, 会严格按照Sprite的MeshType和图集的Tight Packing决定。
                if (settings.spriteMeshType == SpriteMeshType.Tight)
                {                    
                    Vector3[] worldPosArr = new Vector3[4];
                    r.GetWorldCorners(worldPosArr);
 
                    float minX = float.MaxValue;
                    float maxX = float.MinValue;
                    float minY = float.MaxValue;
                    float maxY = float.MinValue;
                    string str = "";
                    for (int i = 0; i < worldPosArr.Length; i++)
                    {
                        Vector3 pos = worldPosArr[i];
                        minX = Mathf.Min(minX, pos.x);
                        maxX = Mathf.Max(maxX, pos.x);
                        minY = Mathf.Min(minY, pos.y);
                        maxY = Mathf.Max(maxY, pos.y);
                        str += pos + " ";
                    }
                    size.x = (maxX - minX) * 100;
                    size.y = (maxY - minY) * 100;
                    Debug.Log("[Tight] " + graphic.gameObject.name + " " + size + "\n" + str);
                }
                else
                {
                    size = r.rect.size;
                    Debug.Log("[FullRect]" + graphic.gameObject.name + " " + size);
                }
            }
 
            rect.size = size;
        }
 

传入组件的Graphic组件(Image和Text都继承于Graphic)可改写脚本直接传你对应的组件也可以,第二个参数是一个Rect类型数据,由外部创建传入。

Rect(rectTransform.localPosition.x, rectTransform.localPosition.y, rectTransform.rect.width, rectTransform.height)构成。

注意这个API最后得到的Rect,并不是rectTransform.rect,它的(x,y)是网格中心点(Canvas空间),它的(z,w)是网格宽度和高度。区别于rectTransform.rect,它的(x,y)是左下角局部坐标点,(z,w)是RectTransform宽度和高度。

相关推荐
小李也疯狂20 小时前
Unity 中的立方体贴图(Cubemaps)
unity·游戏引擎·贴图·cubemap
牛掰是怎么形成的20 小时前
Unity材质贴图引用陷阱:包体暴涨真相
unity·材质·贴图
呆呆敲代码的小Y20 小时前
【Unity工具篇】| 超实用工具LuBan,快速上手使用
游戏·unity·游戏引擎·unity插件·luban·免费游戏·游戏配置表
EQ-雪梨蛋花汤20 小时前
【Unity优化】Unity多场景加载优化与资源释放完整指南:解决Additive加载卡顿、预热、卸载与内存释放问题
unity·游戏引擎
我的offer在哪里20 小时前
用 Unity 从 0 做一个「可以玩的」游戏,需要哪些步骤和流程
游戏·unity·游戏引擎
泡泡茶壶ᐇ21 小时前
Unity游戏开发入门指南:从零开始理解游戏引擎核心概念
unity·游戏引擎
YigAin1 天前
Unity中的Lock,到底在锁什么,什么时候该用?
unity
Var_al1 天前
抖小Unity WebGL分包命令行工具实践指南
unity·游戏引擎·webgl
天人合一peng1 天前
unity 通过代码修改button及其名字字体的属性
unity·游戏引擎
GLDbalala1 天前
Unity基于自定义管线实现经典经验光照模型
unity·游戏引擎