移动端性能预算
Assets/
Scripts/
Settings/
项目设置
你已经有的这一课新增
你在 tab 04 里已经让 Arena 达到了 batch 和三角形数量的预算 —— 但那是在桌面上。中档手机的 GPU 大概只有那股力的十分之一,而且发热之后还会自己降频,差不多五分钟就开始。
四个数要压下去,一个数要提上来。
移动端的预算
Draw call / batch:100 以下比较宽松,60 以下在低端机上也稳。
屏幕上的三角形数:100k–300k。再往上,中档 GPU 就开始冒汗了。
实时灯光:一个 directional,就这样。其余全部 bake 好。
贴图内存:200 MB 以内。别靠猜,去 Profiler 的 Memory 模块里看。
目标:稳定的 60 FPS;如果机器撑不住 60,就老老实实锁死 30。
1. URP 设置 —— 单项收益最大的地方
- 1
找到你的 URP Asset(在 里能看到当前生效的是哪一个)。
- 2
Shadows → Max Distance 设为 40,Cascade Count 设为 1,Shadow Resolution 设为 1024。
- 3
在移动端的 URP asset 上取消勾选 HDR 和 MSAA。基于 tile 的移动 GPU 上这两样都很贵。
- 4
低端机上把 Render Scale 设成 0.8 —— 分辨率降 20% 几乎看不出来,但提速非常明显。
- 5
每个画质等级各留一份 URP asset:Mobile Low、Mobile High、Desktop。
2. Texture——通常占掉你包体的一半
- 1
全选所有 texture,把 Max Size 设为 1024(道具用 512,2048 只留给主角级资源)。
- 2
Compression Format → Android 用 ASTC 6x6。这是现在的标准格式,同样大小下画质比 ETC2 好得多。
- 3
除非你真的在代码里读像素,否则把 Read/Write Enabled 取消勾选 —— 开着它内存会翻倍。
- 4
UI 的 sprite 关掉 mipmap;凡是在 3D 空间里的都保持开启。
3. Script —— 那些让你掉帧的错误
void Update()
{
// 1. searching the whole scene, 60 times a second
GameObject player = GameObject.Find("Player");
// 2. allocating a new object every frame
Enemy[] all = FindObjectsOfType<Enemy>();
// 3. building a string every frame — this is garbage
label.text = "Score: " + score;
// 4. a component lookup every frame
GetComponent<Rigidbody>().AddForce(Vector3.up);
}private Transform player;
private Rigidbody rb;
private int lastScore = -1;
void Awake()
{
player = GameObject.FindWithTag("Player").transform; // once
rb = GetComponent<Rigidbody>();
}
void Update()
{
rb.AddForce(Vector3.up);
if (score != lastScore) // only build the string when it changed
{
label.text = "Score: " + score;
lastScore = score;
}
}手机上每隔几秒卡一下,元凶就是垃圾回收。其中几乎全部来自 Update 里的字符串和新的内存分配。
不需要每帧跑的东西就交给定时器 —— 敌人 AI 改成每 0.2 秒判定一次,开销只有原来的十二分之一。
空的 Update() 照样会被 engine 调用一次。删掉。
4. 识别设备,然后降档
using UnityEngine;
public class QualityAutoSetter : MonoBehaviour
{
void Awake()
{
int ram = SystemInfo.systemMemorySize; // in MB
int cores = SystemInfo.processorCount;
if (ram < 3000 || cores <= 4)
{
QualitySettings.SetQualityLevel(0, true); // Mobile Low
Application.targetFrameRate = 30;
}
else if (ram < 6000)
{
QualitySettings.SetQualityLevel(1, true); // Mobile Medium
Application.targetFrameRate = 60;
}
else
{
QualitySettings.SetQualityLevel(2, true); // Mobile High
Application.targetFrameRate = 60;
}
Debug.Log($"Device: {SystemInfo.deviceModel}, RAM {ram}MB, quality {QualitySettings.GetQualityLevel()}");
}
}在真机上 profile,而不是在编辑器里
编辑器跑在你桌面机的 CPU 上。它给出的数字说明不了手机上会怎样。
在 Build Profiles 里勾上 Development Build 和 Autoconnect Profiler,构建到设备上,再打开 Profiler。
连续玩满五分钟。由于发热降频,第五分钟会比第一分钟慢 20–30% —— 这个才是你在意的数字。