Unity 优化总结

| 发布     | 分类 Unity  | 标签 Unity  优化 

UGUI 降低填充率技巧两则

UWA直播回顾| UGUI性能优化技巧



如果叠加层有另外的calldraw夹着,会使本来该合并的calldraw独立。从而让calldraw上升

(1)mask先往缓存里画一个区域,产生一个calldraw

(2)mask里面的物体与外面的calldraw独立,越复杂产生的calldraw越多

原理同1,Text可能会分割其他图片的calldraw。 好处是可以把相同字体的text合并calldraw

(1)叠加层数越多,overdraw显示的颜色越红。同一个像素在同一帧绘制的次数越多

(2)如果Image是Sliced类型,中间区域是完全透明(相当于9宫格的边框),那么尽量将 Fill Center的勾去掉

(3)如果是只要点击区域,不要显示内容的。可以把空白透明Image替换成qiankanglai提供的Empty4Raycast (http://blog.uwa4d.com/archives/fillrate.htmlhttp://blog.uwa4d.com/archives/fillrate.html)。只接收事件,清空顶点绘制。

using UnityEngine;
using System.Collections;

namespace UnityEngine.UI
{
    public class Empty4Raycast : MaskableGraphic
    {
        protected Empty4Raycast()
        {
            useLegacyMeshGeneration = false;
        }

        protected override void OnPopulateMesh(VertexHelper toFill)
        {
            toFill.Clear();
        }
    }
}

(4)和第(2)类似,如果一张图片有很多区域是空白的,默认情况下fill rate是矩形区域。用下下面qiankanglai提供的PolygonImage。可以减少透明区域的fill。

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

UGUI的 Text、Image两个组件有这个参数,主要用来事件监听的。如果不需要接受事件监听就去掉。因为在触摸屏幕的时候,Raycast Target勾选的会参与检测。数量多了就会耗时。

(1)先看看界面中不操作情况下,有哪些元素是会变化的。如果层级不是很耦合,那么可以把这些动的元素放到新的Canvas。如果大多数变化的在一个层级下,就在变化的最上游节点添加一个Canvas组件。

(2)如个是选中状态有变化的元素。可以用代码动态给他添加Canvas组件。

(3)如果Image、Text在动态改变Color的,做渐变动画之类的。也可以单独设置材质球用脚本修改材质球颜色。多1个calldraw。减少整体Mesh重建。直接修改Color是在修改他们的顶点颜色,所以Mesh会重建。

Text调用Outline等组件会多加很多的Mesh(三角数翻5倍)。可以自己创建字体,字体里的文字描好边。

上一篇: Unity加载Android里的StreamingAssets里的文件
下一篇: Flatbuffers 使用