[笔记]UGUI优化

本文探讨了UGUI系统的性能优化方法,包括减少组件重叠以降低DrawCall,慎用Mask组件,优化文字布局和合并DrawCall,调整Image类型以减少OverDraw,以及关闭不必要的Raycast事件和动态组件管理。此外,还提到了动画和UIEffect的使用策略,以及避免无效的网格重建和利用RenderTexture减少DrawCall的技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://v.qq.com/x/page/l0329fvbrfn.html
https://blog.uwa4d.com/archives/fillrate.html
https://v.qq.com/x/page/e0520qxtjox.html

  1. 重叠UGUI组件会增加DrawCall
    尽量减少UGUI组件重叠 尽量使用相同的材质
  2. mask组件会增加DrawCalll
    mask写模板缓存会增加一个DrawCall mask组件子节点下面原来可合并的材质也变得不可合并
  3. 尽可能把文字设置在图片以上
    合并文字DrawCall
  4. 边框Image的ImageType一般为Sliced 将FillCenter设置为为false可降低OverDrall
  5. Empty4Raycast 需要使用Image的Raycast事件又不想产生Image造成的OverDrall
using UnityEngine;
using System.Collections;

namespace UnityEngine.UI {
    public class Empty4Raycast : MaskableGraphic {
        protected Empty4Raycast()  {
            useLegacyMeshGeneration = false;
        }
        protected override void OnPopulateMesh(VertexHelper toFill) {
            toFill.Clear();
        }
    }
}
  1. PolygonImage 类似第四条 不仅个角 可以把Image的顶点挖出来 减少渲染面积 例圆形
using System.Collections.Generic;

namespace UnityEngine.UI {
    [AddComponentMenu("UI/Effects/PolygonImage", 16)]
    [RequireComponent(typeof(Image))]
    public class PolygonImage : BaseMeshEffect {
        protected PolygonImage() { }

        // GC Friendly
        private static Vector3[] fourCorners = new Vector3[4];
        private static UIVertex vertice = new UIVertex();
        private RectTransform rectTransform = null;
        private Image image = null;
        public override void ModifyMesh(VertexHelper vh) {
            if (!isActiveAndEnabled) return;

            if (rectTransform == null) {
                rectTransform = GetComponent<RectTransform>();
            }
            if (image == null) {
                image = GetComponent<Image>();
            }
            if (image.type != Image.Type.Simple) {
                return;
            }
            Sprite sprite = image.overrideSprite;
            if (sprite == null || sprite.triangles.Length == 6) {
                // only 2 triangles
                return;
            }

            // Kanglai: at first I copy codes from Image.GetDrawingDimensions
            // to calculate Image's dimensions. But now for easy to read, I just take usage of corners.
            if (vh.currentVertCount != 4) {
                return;
            }

            rectTransform.GetLocalCorners(fourCorners);

            // Kanglai: recalculate vertices from Sprite!
            int len = sprite.vertices.Length;
            var vertices = new List<UIVertex>(len);
            Vector2 Center = sprite.bounds.center;
            Vector2 invExtend = new Vector2(1 / sprite.bounds.size.x, 1 / sprite.bounds.size.y);
            for (int i = 0; i < len; i++) {
                // normalize
                float x = (sprite.vertices[i].x - Center.x) * invExtend.x + 0.5f;
                float y = (sprite.vertices[i].y - Center.y) * invExtend.y + 0.5f;
                // lerp to position
                vertice.position = new Vector2(Mathf.Lerp(fourCorners[0].x, fourCorners[2].x, x), Mathf.Lerp(fourCorners[0].y, fourCorners[2].y, y));
                vertice.color = image.color;
                vertice.uv0 = sprite.uv[i];
                vertices.Add(vertice);
            }

            len = sprite.triangles.Length;
            var triangles = new List<int>(len);
            for (int i = 0; i < len; i++) {
                triangles.Add(sprite.triangles[i]);
            }

            vh.Clear();
            vh.AddUIVertexStream(vertices, triangles);
        }
    }
}
  1. 事件检测优化 UI组件不需要事件检测时 关闭Ratcast选项
    修改Image组件源码 默认关闭Raycast
  2. 动态组件分离
    动态组建单独放在一个canvas下 防止合并顶点时对静态组件的重复操作
    对于一直处于运动的UGUI组件 合并增加canvas组件
    对于游戏过程中可能运动的组件 通过脚本动态添加canvas组件(记得销毁)
  3. Image组件中的color是顶点色 通过动画改变时也会对顶点产生影响
  4. 5.2以后 canvas.bulidbatch被分离到多线程(WaitingForJob PutGeometryJobFence BatchRenderer.Flush)里面 (所以profile里面可能看不出)
  5. 不需要的动画可禁用 减小开销
  6. 尽量少用UIEffect (Outline Shadow) 尤其是文字 会增加大量顶点
  7. z值不同将不会合并DrawCall
  8. ImageSprite为空或者Color.a=0时仍会渲染(scale=0将不渲染)
  9. position赋值 即使数值没有变化也会重建网格(增加阈值判断)
  10. 隐藏UI可以通过设置layermask 可以防止网格重建
  11. 可将部分UI渲染到rt 减少drawcall
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值