モバイルの性能予算
Assets/
Scripts/
Settings/
プロジェクトの設定
すでにあるものこのレッスンで追加
tab 04 ですでに Arena の batch と三角形の予算はクリアしています——ただしデスクトップでの話です。ミドルレンジのスマホの GPU はその 10 分の 1 くらいの力で、しかも 5 分もすると熱くなって自分でクロックを落としていきます。
減らすべき数字が 4 つ、上げるべき数字が 1 つ。
モバイルの予算
draw call / batch:100 未満なら余裕、弱い端末では 60 未満なら安心です。
画面内の三角形:100k〜300k。超えるとミドルレンジの GPU は息が切れます。
リアルタイムのライトは directional 1 本だけ、それで終わり。残りはすべてベイクします。
texture のメモリ: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
mobile 用 URP asset では HDR と MSAA のチェックを外します。タイル方式のモバイル 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 内の文字列と新しい確保から来ています。
60 Hz で回す必要のない処理はタイマーで動かしましょう——敵 AI の判定を 0.2 秒ごとにすると、コストは 12 分の 1 です。
空の 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()}");
}
}エディタではなく実機でプロファイルする
エディタはデスクトップの CPU で動いています。そこで出た数値に、スマホの話はほとんど当てになりません。
Build Profiles で Development Build と Autoconnect Profiler にチェックを入れ、実機へビルドしてから Profiler を開きます。
5 分間しっかりプレイします。サーマルスロットリングのせいで 5 分目は 1 分目より 20〜30% 遅くなります——大事なのはそちらの数字です。