LoginSignup
5
16

More than 5 years have passed since last update.

Unityシーン切り替えとファイル読み込み高速化手法その1

Last updated at Posted at 2018-12-15

概要

他の記事ではあまり記述されていない高速化手法を延々と並べていく
シーン切り替えやファイル読み込みが遅くて困っている人向けの記事
対象プラットフォームは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のロード」をそれぞれコルーチンで作成して同時に実行することにより、並列で処理が走りロードが高速化される。

CoroutineList.cs
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;
        }
    }
}
sample.cs
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を書きました。

5
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
16