概要
他の記事ではあまり記述されていない高速化手法を延々と並べていく
シーン切り替えやファイル読み込みが遅くて困っている人向けの記事
対象プラットフォームはiOS、Android
一覧
- シーン切り替えを行わずprefab読み替えをする
- GCやResources.UnloadUnusedAssetsのコールを限定する
- コルーチンリストを使って並列でコルーチンを回す
- AssetBundleを考慮したファイルパッキングと、どのパスからでもファイルを読めるLoaderを用意
- リソースのキャッシュと破棄を行う機能
- SpriteAtlasを使いまわす
シーン切り替えを行わない
SceneManager.LoadSceneを使用したシーン切り替えは遅いので、起動シーン以外は使わないようにする
ただし、ライティングがシーンに紐づくのでライティングが異なるステージなどはマルチシーンで読み込みを行う
各画面ごとにprefabを作成して読み替える作りにすると高速に画面切り替えを行うことが出来る
この時、GCやResources.UnloadUnusedAssetsを呼ぶと遅くなってしまうので呼ばないこと
GCやResources.UnloadUnusedAssetsはバトルなど大きな括りの画面に遷移する時にメモリ使用量をみて、危険域に達していたら呼ぶようにする
prefab読み替えと画面ごとの開発シーン
ゲーム中はシーン切り替えを基本行わないが、全くシーンを使わないと各画面の開発が面倒になってしまう。
この問題を解決するには、各画面ごとにシーンを作成してシーンにはcanvasオブジェクトを配置し、その下に画面として使うprefabを作成して画面を構築していく。
ゲームで使うシーンにも常時canvasを1つ常駐させるようにして、ゲーム中はそのcanvasの下に上記で作ったprefabを読み替えるようにする。
コルーチンリストを使って並列でコルーチンを回す
ある画面に入るときに「通信」「画面を構築するprefabのロード」をそれぞれコルーチンで作成して同時に実行することにより、並列で処理が走りロードが高速化される。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CoroutineList
{
List<IEnumerator> enumerators = new List<IEnumerator>();
List<Coroutine> coroutines = new List<Coroutine>();
public void Add(IEnumerator co)
{
enumerators.Add(co);
}
public void AddRange(IEnumerable<IEnumerator> cos)
{
enumerators.AddRange(cos);
}
public IEnumerator WaitForCoroutine(MonoBehaviour mb)
{
coroutines.Clear();
foreach (var e in enumerators)
{
coroutines.Add(mb.StartCoroutine(e));
}
enumerators.Clear();
foreach (var co in coroutines)
{
yield return co;
}
}
}
using UnityEngine;
public class Sample : MonoBehaviour
{
IEnumerator Start()
{
// ロード処理を並列で実行する
var cl = new CoroutineList();
cl.Add(APIConnect());
cl.Add(LoadPrefab());
cl.Add(LoadExtra());
yield return cl.WaitForCoroutine(this);
}
IEnumerator APIConnect()
{
// 通信処理をごにょごにょ
}
IEnumerator LoadPrefab()
{
// プレハブ読み込みをごにょごにょ
}
IEnumerator LoadExtra()
{
// その他並列で読み込みたいものをごにょごにょ
}
}
その2を書きました。