• UGUI性能优化


    http://www.cnblogs.com/suoluo/p/5417152.html

     http://blog.csdn.net/uwa4d/article/details/54344423

    http://blog.csdn.net/rhett_yuan/article/details/56695170

    https://blog.csdn.net/wetest_tencent/article/details/53525094

    目标能将UI消耗控制到2到3毫秒

    真机查看手机profile

    http://www.cnblogs.com/alps/p/7787060.html

    UGUI主要耗时需要注意的时间(具体unity版本不一样会不样)

    Profile-》CPU-》BehaviourUpdate-》EventSystem.Update   查看事件更新时间

     Profier-》CPU-》Canvas.BuildBatch    查看网格重建时间

     profile-》menory-》Detailed-》Not Saved-》Mesh-》BatchedMesh  查看每帧网格重建的网格

    1.图片尺寸最好是2次幂
    2.不要勾选Generate Mip Maps
    3.不要勾选Read/Write Enabled
    4.Image、Text组件不需要射线检测的将Raycast Target勾去掉

    5.尽量不要让元素有重叠的情况,不重叠可以网格合并批次处理,重叠后需要融合处理遮挡问题

    6.在需要一个只在逻辑上响应Raycast但是不参与绘制的组件时使用脚本,降低FillRate

    using UnityEngine;
    using System.Collections;
    
    namespace UnityEngine.UI
    {
        public class Empty4Raycast : MaskableGraphic
        {
            protected Empty4Raycast()
            {
                useLegacyMeshGeneration = false;
            }
    
            protected override void OnPopulateMesh(VertexHelper toFill)
            {
                toFill.Clear();
            }
        }
    }

    7.Polygon Mode Sprite(多边形模式)通过增加顶点减少空白区域的绘制,降低FillRate

    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);
            }
        }
    }

    8.对于网格重建最好的方法就是动静分离,当Canvas上的任何一个元素变化时会引起整个Canvas的重绘,将变化的元素单独出来。

    9.修改组件的Color属性时也会导致UI的重绘,可以生成修改材质的tint属性

    void Start()  

    {        

       image = this.GetComponent<Image>();       

      image.material = Instantiate(image.material) as Material;

    void LateUpdate()  

    {      

      image.material.SetColor("_Color", color);  

     

    10.谨慎使用文字特效 shadown/outline ,将产生翻倍的顶点

     

    UGUI会自动检测优化,如果多个材质间没有遮挡或只有小部分不影响的遮挡则会合并DrawCall为一个。如下图:

    1. 尽可能保证Text在Image的上方。字体的DrawCall就可能自动会优化,而不需要像NGUI那样让字体跟图片pack在一起来减少DrawCall。
    2. 尽可能保证Image之间不存在不必要的重叠。

    UI变色:修改材质和修改顶点色两种方式

    1. 合并DrawCall一定要是相同的材质,修改材质会将本来已合并的DrawCall分离开,就导致了DrawCall的增加及Canvas的重建。
    2. 修改顶点色(Button中Transition中的ColorTint方式)只会修改Canvas中的数据。

    UI边框:Sliced & Fill Center

    1. Sliced模式的Sprite更节省纹理尺寸。
    2. 中空的边框不应该勾选Fill Center,镂空留白区域,可减小Fill rate。

    Mask的代价,通过Stencil buffer实现

    1. 移动平台需要Use 24-bit Depth Buffer(Tegra GPU 2、3上不支持,4支持)。
    2. Mask中的UI元素无法与其他batch,从而增加DrawCall。
    3. 可以的话尝试用Filled Sprite代替。

    动画:Text vs Image

    1. 如果Image上做了动画则Canvas需要重建,Image的顶点数一般不会很多,开销不会很大。
    2. Text与文本内容(生成的网格数)相关,如果文字比较多则相比Image开销可能会翻倍。

    Canvas的重建主要就是为了合并DrawCall,可以将有动画的文字放在单独的Canvas中去,手动分离DrawCall(增加DrawCall)后就不会再要去跟别的文字作合并,该Canvas就不需要再重建故减少了重建开销。

    尽可能使用缓冲池。如人物身上的伤害数字,生成时会有较大的开销因为有Mesh的生成等过程。

    unity官网对性能优化的建议,干货,比较实用,建议都看一下:https://unity3d.com/cn/learn/tutorials/topics/best-practices/guide-optimizing-unity-ui?playlist=30089

    翻译:

    http://www.manew.com/home.php?mod=space&uid=105915&do=thread&view=me&from=space

    以上链接中的系列文章:UI 优化指南,UNITY UI 基本原理, Unity UI分析工具, 填充率,画布和输入, 优化UI控件, 其他的UI优化技术和技巧。

  • 相关阅读:
    maven基础依赖外部lib包(依赖钉钉sdk为例)
    JVM的内存区域划分
    EF6 根据数据库字段说明,生成字段注释
    js上传图片,js图片转换为Base64
    Jquery用append()方法新增加的元素事件失效
    MVC添加区域路由问题
    JObject获取JSON格式字符串数据
    百度地图WebApi根据地址解析经纬度和根据经纬度解析地址
    sqlserver函数根据经纬度计算两点之间的距离
    AdminLTE-2.4.0-rc文件添加到项目中报错 错误 1 “tsc.exe”已退出,代码为 1。 M.Website
  • 原文地址:https://www.cnblogs.com/alps/p/7773149.html
Copyright © 2020-2023  润新知