【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宽度和高度。

相关推荐
在路上看风景2 分钟前
26. Mipmap
unity
咸鱼永不翻身2 小时前
Unity视频资源压缩详解
unity·游戏引擎·音视频
在路上看风景2 小时前
4.2 OverDraw
unity
在路上看风景3 小时前
1.10 CDN缓存
unity
ellis197012 小时前
Unity插件SafeArea Helper适配异形屏详解
unity
nnsix13 小时前
Unity Physics.Raycast的 QueryTriggerInteraction枚举作用
unity·游戏引擎
地狱为王14 小时前
Cesium for Unity叠加行政区划线
unity·gis·cesium
小贺儿开发1 天前
Unity3D 八大菜系连连看
游戏·unity·互动·传统文化
在路上看风景1 天前
25. 屏幕像素和纹理像素不匹配
unity
ۓ明哲ڪ1 天前
Unity功能——创建新脚本时自动添加自定义头注释
unity·游戏引擎