鏈接1:Unity 優(yōu)化之UGUI (2017年版【一】) - 簡書
視頻地址:https://v.qq.com/x/page/l0329fvbrfn.html
盡可能的讓UI元素合批
首先創(chuàng)建一個新的場景,攝像camera為Solod Color
可以看到場景中的Barches為1,這是因為camera在做Clear操作
?
然后創(chuàng)建兩個Button 去掉對應的Text,運行unity發(fā)現產生的Batches變?yōu)?
?
當兩個Button進行重疊的是時候蔬芥,Batches并沒有變化
?
但是對有Text的兩個Button進行上面的操作,就會出現不一樣的效果嗤放,重疊后的Batches和未重疊Batches不一致
?
?
按照公開課中的說法,這種重疊的做法會打破原有的拓撲排序(Text2 與Button2合并)舆乔,造成Draw Call的合并失斚A(Text -Button -Text - Button)颜武,當然在Hierarchy視圖中也要盡量按照這種拓撲排序的方式進行UI的層級擺放。
結論:在進行UI設計額時候盡量少使用來自不同Atlas的材質吊档,也盡量避免這種傾軋的情況(Scene視圖調節(jié)為Writeframe模式可以更容易查看)怠硼,盡可能把所有的文字放到圖片之上香璃,使用同種字體增显,更容易進行合批
?
接下來要說的就是Mask組件
在一個新的場景中放圖兩個Image同云,然后設置統(tǒng)一的Packing Tag
?
而且也要在Editor Settings開啟圖集選項
?
運行前后對應可發(fā)現兩張圖片進行了合批
?
?
然后在場景中添加一個對應的Mask旱易,發(fā)現Batches有所變化阀坏,兩個圖片也進行了合批
?
把其中一個圖片放到mask的遮罩中,發(fā)現圖片無法合批
?
結論: 首先一個Mask組件就會產生一個Draw Call士修,而且在Mask中的圖片無法與外界的圖片進行合批
減少Overdraw
?
根據上圖的顯示,調節(jié)到OverDraw模式矩桂,顏色越鮮亮的地方造成的OverDraw越大阔籽,隨之帶來的GPU壓力也是越大的
下面來說減少OverDraw的一些策略
在ImageType選項為Sliced的情況下笆制,不需要Fill Center 的時候去掉勾選
?
Code Empty4Raycast
using UnityEngine;
using System.Collections;
namespace UnityEngine.UI
{
public class Empty4Raycast : MaskableGraphic
{
protected Empty4Raycast()
{
useLegacyMeshGeneration = false;
}
protected override void OnPopulateMesh(VertexHelper toFill)
{
toFill.Clear();
}
}
}
Code Code PolygonImage
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);
}
}
}
減少Raycast Target
在對應的Text Image和Rawimage中都有Raycast Target選項,這個選項負責接收我們所點擊的事件鸦概,但是項目中我們有些UI元素是不需要這些東西甩骏,所有可以去掉饮笛,減少不必要的性能消耗摄狱,可以用RaycastTarget檢測小工具媒役,他可以在對應的editor模式下酣衷,把開啟Raycast Target選項的UI以藍色線框的形式顯示出來,方便大家檢查遺漏的關閉的UI元素
?
避免網格重建(Canvas.BuildBatch)
?
Canvas.BuildBatch
現在untiy2017版本中Canvas.BuildBatch的主要耗時已經放到了多線程中
網格重建的意思是把Canvas下所有的ui合成一個Mesh牡借,當有UI元素更改的時候就會重建這個Mesh,造成性能消耗碴里。 采取的對應策略就是【動靜分離】咬腋,在經常變動的UI元素(位置陵像、顏色、圖片等)上添加Canvas組件寇壳,就可以避免因為UI的改變造成整個Mesh全部重建醒颖。當然對于數量較多需要進行顏色漸變的UI元素都添加上canvas顯然不合適,因為添加canvas會增加DrawCall壳炎。所以我們需要采用另一個策略泞歉,在Image上添加一個自定義的material,然后更改這個material的Tint屬性匿辩,這樣既能滿足顏色漸變腰耙,又能避免網格頻繁重建造成的性能消耗(實質是避免修改網格上的頂點屬性,造成網格重建)
?
?
?
額外注意的地點
避免使用OutLine組件
避免使用Shadow組件
應對策略:使用Text Mesh Pro插件是一個不錯的選擇(現在已經免費)
避免頻繁使UI元素SetActive(開撒汉、關),會造成網格重建
減少Raycast Target
在對應的Text Image和Rawimage中都有Raycast Target選項,這個選項負責接收我們所點擊的事件,但是項目中我們有些UI元素是不需要這些東西寻歧,所有可以去掉噪珊,減少不必要的性能消耗,可以用RaycastTarget檢測小工具,他可以在對應的editor模式下,把開啟Raycast Target選項的UI以藍色線框的形式顯示出來椎工,方便大家檢查遺漏的關閉的UI元素
?
避免網格重建(Canvas.BuildBatch)
?
Canvas.BuildBatch
現在untiy2017版本中Canvas.BuildBatch的主要耗時已經放到了多線程中
網格重建的意思是把Canvas下所有的ui合成一個Mesh局待,當有UI元素更改的時候就會重建這個Mesh营罢,造成性能消耗缕溉。 采取的對應策略就是【動靜分離】败玉,在經常變動的UI元素(位置兴枯、顏色躺坟、圖片等)上添加Canvas組件美侦,就可以避免因為UI的改變造成整個Mesh全部重建准颓。當然對于數量較多需要進行顏色漸變的UI元素都添加上canvas顯然不合適贯被,因為添加canvas會增加DrawCall幌陕。所以我們需要采用另一個策略心例,在Image上添加一個自定義的material瓜喇,然后更改這個material的Tint屬性,這樣既能滿足顏色漸變刽酱,又能避免網格頻繁重建造成的性能消耗(實質是避免修改網格上的頂點屬性典蝌,造成網格重建)
?
?
?
額外注意的地點
避免使用OutLine組件
避免使用Shadow組件
應對策略:使用Text Mesh Pro插件是一個不錯的選擇(現在已經免費)
避免頻繁使UI元素SetActive(開鹉勒、關),會造成網格重建