尽量少用outline,tiled Sprite
如果用,尽量保证不会改变他的颜色大小之类的
减少其所在canvas重建
ugui为队列制,在队列才刷新,无改变不刷新
Ugui大量静态不改变的开销很低,对象池中对象用scale= 0或者alphaGroup = 0来控制更佳(伤害界面优化,改成alphaGroup,存到对象池中) Ugui scale = 0,顶点数也会变为0,ngui只是网格变为0,顶点数不变,所以要用color.a=0
写插件(动态设置图片层级,通过list保存index,setsibling)
慎用,容易增加drawCall
Canvas.BuildBatch 更新所有DrawCall
如果出现了WaitingForJob或PutGeometryJobFence,则说明合并网格开销很大
优化合理应该消失
一个Canvas一个网格,注意拆分Canvas,尽量动静分离
Z一定要调为0,除非有3DUI穿插。
Image为null或者alpha为0不能降低开销,Image为null还会不能合并
Item类型,如果当前图标和相邻图标(非当下图标)有重叠,那么则不会合并为2个drawcall;
这时尽量改hierarchy里面的排序,并可根据item内的层级(background,icon等)顺序,来添加父类,对每一个层级进行管理,而不是每一个item;(添加方法来进行管理,存储还是按照item的list来管理,//添加管理类)
当某一个item类型处于选中,播放动画等状态,并且所处canvas下内容比较多的情况下,可以单独添加方法,给他自己添加一个canvas,取消选中时则remove掉,(写到UIGameUtil里),用于动静分离,
借鉴
Mask是能少用就少用,等于一个跟其他合并不了的完全独立的,增加的远不止几个drawcall;
界面内(如背包)图标相互不要重叠,会增加不必要的drawcall
如背包等,如果前面图标能完全遮挡后面图标,且后面图标为sliced模式,可把fill Center改为true;目前项目大部分图标过小或中间有透明,无法优化,优先可优化类型(边框,中间镂空)
空image,去网页看
拆分canvas,,血条伤害等单给个canvas(如果当前canvas下其他东西也不少的话)
//血条等设置最小移动阈值,并且设定更新频率
增加小数值判断,不大于一个数值不做改变,降低消耗
TextMeshPro,适合静态(目前予以否认状态,字体库太大,不值,而且只适用于静态,并且不容易通过配置来改变)
动态文字尽量不用outLine
两个UI有一个需要隐藏的,可以在摄像机上设置一个层级,不渲染,当需要隐藏的时候,直接修改layer,
两层UI,可看见后面的时候,可直接把后面渲染成一个rendererTexture;(写个插件!!!)
思路1:截图截UI全屏,然后挂在image上,关闭时删除
思路2:单新建一个相机做渲染。
具体损耗等待测试来确定方案
//用于全屏遮挡检测,(tips等),降低overDraw,以下为代码
using UnityEngine;
using System.Collections;
namespace UnityEngine.UI
{
public classEmpty4Raycast : MaskableGraphic
{
protectedEmpty4Raycast()
{
useLegacyMeshGeneration = false;
}
protectedoverride void OnPopulateMesh(VertexHelper toFill)
{
toFill.Clear();
}
}
}
事件检测优化,会遍历canvas下所有image,text等组件,浪费,目前思路,重写raycast选项开启关闭,增加一个list管理,开启调用add,关闭则remove,只遍历list内组件
大量颜色渐变的时候,可以改变材质球的tintcolor来控制,个人认为一两个的没有必要单弄个材质球,若大量可用;更主要用途,通过动画来控制tintcolor的变化.
拆分一下现在的层级分类,其他还好,底层静态的,把joystick单独拆出去,太频繁变化了然后上面的金币,不过目前主城还好,毕竟只有两个比较小的界面,战斗目前基本都存在各种变化
摇杆(单拆);
伤害(单拆,并且颜色渐变等还可优化,借鉴上面)
技能(单拆)
连击(单拆)
血条等(单拆血条等有变化的,其他不变)
动画,播完没用就关,有用再开,增加父类控制(直接写到动画插件里)
然后增加一个用定点数换取渲染填充率的脚本,个人目前仅认为用于不规则按钮重叠问题比较实用,其他方面图集可用,需要实践,另用于很大的不规则图形,空白区域很多的情况下,脚本目前还未测试(准备与选关界面结合使用,完善选关界面的不规则图形检测规则来测试)
using System.Collections.Generic;
namespace UnityEngine.UI
{
[AddComponentMenu("UI/Effects/PolygonImage",16)]
[RequireComponent(typeof(Image))]
public classPolygonImage : BaseMeshEffect
{
protectedPolygonImage()
{ }
// GCFriendly
privatestatic Vector3[] fourCorners = new Vector3[4];
privatestatic UIVertex vertice = new UIVertex();
privateRectTransform rectTransform = null;
privateImage image = null;
publicoverride void ModifyMesh(VertexHelper vh)
{
if(!isActiveAndEnabled) return;
if(rectTransform == null)
{
rectTransform = GetComponent
}
if(image == null)
{
image = GetComponent
}
if(image.type != Image.Type.Simple)
{
return;
}
Spritesprite = image.overrideSprite;
if(sprite == null || sprite.triangles.Length == 6)
{
//only 2 triangles
return;
}
//Kanglai: at first I copy codes from Image.GetDrawingDimensions
// tocalculate Image's dimensions. But now for easy to read, I just take usage ofcorners.
if(vh.currentVertCount != 4)
{
return;
}
rectTransform.GetLocalCorners(fourCorners);
//Kanglai: recalculate vertices from Sprite!
int len= sprite.vertices.Length;
varvertices = new List
Vector2Center = sprite.bounds.center;
Vector2invExtend = 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;
vartriangles = new List
for(int i = 0; i < len; i++)
{
triangles.Add(sprite.triangles[i]);
}
vh.Clear();
vh.AddUIVertexStream(vertices,triangles);
}
}
}
Text的Best Fit选项能不用就不要用,自己来限制;
-Alpha:这个选项很多组件都有,用处也是一样的,在美术中,这个叫做Alpha通道的东东是用来控制透明度的,他的值从0到1.0是完全透明,1是完全不透明;
-Interactable确认该组件是否接受输入,当他被设置为false时,交互功能将被禁用;
-BlockRaycasts是否让该组件像collider一样接受射线检测?你需要在依赖于Canvas的图形射线检测者上唤醒射线检测方法。这个不会作用于Physics.Raycast;
-IgnoreParent Groups(忽略父级团)是否响应父级group的方法
细节:
CanvasGroup的经典使用:
-在窗口的GameObject上添加一个CanvasGroup,通过控制它的Alpha值来淡入或淡出整个窗口;
-通过给父级GameObject添加一个CanvasGroup并设置它的Interactable值为false来制作一整套没有交互(灰色)的控制;
-通过将元素或元素的一个父级添加CanvasGroup并设置BlockRaycasts值为false来制作一个或多个不阻止鼠标事件的UI元素
总结:
优化方向1:动态和静态分离,保证动态刷新时不去改变静态里面的内容;
优化方向2:界面重叠时,尽量消除在当前显示界面后面的那些渲染不到的界面的影响;
1:界面控制,把后面用不到的界面暂时隐藏(active或alphagroup,根据需求)2:在后面界面不会发生改变的情况下,(如弹出tips,tips后面的内容不会发生改变时),把后面的整个界面渲染成rendereTexture,然后隐藏界面,来降低损耗
优化方向3: 界面内子item类型避免重叠,如必须,降低其所造成的损耗(如分层管理等,看看是否可以用fillcenter),根据需求来优化,检查网格是否过高;
优化方向4:频率过高导致的损耗:1.设置频率
2.设置最小改变的阈值
优化方向5:事件检测优化(用一个空Text来检测目前用的不少,tips之类的),全部改为上面的方法;