12
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Unity】Crunch圧縮でロード時間は速くなるのか?

Last updated at Posted at 2019-11-02

はじめに

UnityにはCrunch圧縮という機能がありTextureのサイズを劇的に減らすことができます。
crunch.png

ビルドサイズを削減するという点では非常に有効だと思うのですがロード時間の短縮と言う点ではどうなのでしょうか?
ビルドサイズが小さくなれば当然読み込み時間は短くなるでしょうが圧縮しているため解凍する必要があります。IOの高速化により短縮できる時間と解凍にかかる時間のどちらの方が大きいのかを測定してみました。
結論から言うとCrunch圧縮した方がいいぜって話です。

環境

OS:Windows10 64bit
ビルドターゲット:Windows(スタンドアロン) LZ4圧縮は無し
Unityバージョン:2019.2.0f1
プロセッサ:Corei3-6100U
CrystalDiskMark:
crystaldiskmark.png

測定方法

こんな感じのシーンを作りました。
scene.png

フルHDから4Kまでのテクスチャが存在しておりメモリ上には1.3GBのテクスチャが載っています。

profiler.png

このシーンをAssetBundleに格納し、ロードします。

以下のスクリプトでロード時間を測定します。

StartTimer.cs
using UnityEngine;
using UnityEngine.SceneManagement;
using System.IO;
using System.Collections;

public class StartTimer : MonoBehaviour
{
	private void Update()
	{
		if (Input.GetButtonDown("Jump"))
		{
			StartCoroutine(Load());
		}
	}


	IEnumerator Load()
    {
		File.AppendAllText(Application.streamingAssetsPath + "/result.txt", "LoadStart..." + Time.time+"\n");
		var result = AssetBundle.LoadFromFileAsync(Application.streamingAssetsPath + "/sphere");

		yield return new WaitWhile(() => {
			return !result.isDone;
		});

		var assetbundle = result.assetBundle;

		File.AppendAllText(Application.streamingAssetsPath + "/result.txt", "ABLoadComplete..." + Time.time+"\n");
		string sceneName = Path.GetFileNameWithoutExtension(assetbundle.GetAllScenePaths()[0]);
		SceneManager.LoadScene(sceneName);
	}
}

CompleteTimer.cs
using UnityEngine;
using System.IO;

public class CompleteTimer : MonoBehaviour
{
    void Start()
    {
		File.AppendAllText(Application.streamingAssetsPath + "/result.txt", "LoadComplete..." + Time.time+"\n");
	}
}

(AssetBundleからのシーン読み込みの方法はこちらのブログを参考にさせていただきました。http://tsubakit1.hateblo.jp/entry/2016/08/23/233604)

開始時に読み込まれるシーンのGameObjectにStartTimer.csをアタッチし、CompleteTimer.csは先ほどのテクスチャいっぱいのシーンのGameObjectにアタッチしておきます。

この測定をCrunch圧縮なし/ありでそれぞれ行いロード時間を比較したいと思います。
なおCrunch圧縮のクオリティは50でやっていきます。

#結果
###Crunch圧縮無し

result.txt
LoadStart...0.9617942
ABLoadComplete...32.18606
LoadComplete...32.20223

アセットバンドルサイズ : 267,533KB(267.5MB)

アセットバンドルのロードにかかった時間 : 31.2242658秒
アセットバンドルロード完了後にシーンの読み込みにかかった時間 : 0.01617秒
###Crunch圧縮あり

result.txt
LoadStart...10.97006
ABLoadComplete...21.08436
LoadComplete...21.10166

アセットバンドルサイズ : 105,891KB(105.9MB)

アセットバンドルのロードにかかった時間 : 10.1143秒
アセットバンドルロード完了後にシーンの読み込みにかかった時間 : 0.0173秒

Crunch圧縮によりアセットバンドルのサイズは半分以下に、読み込み時間は3分の1ほどになりました。
シーンの読み込みにかかった時間はCrunch圧縮ありの方がほんのわずかに遅かったですが誤差レベル。人間には知覚できないでしょう。

#AssetBundle無し
それではアセットバンドルをビルドせずにシーンを直接組み込んだ場合はどうでしょうか。
環境及び計測方法は大体同じです。
###Crunch圧縮無し

result.txt
LoadStart...1.388524
LoadComplete...1.41218

ビルドサイズ:652 MB
シーンのロード時間:0.023656

###Crunch圧縮あり

result.txt
LoadStart...1.386678
LoadComplete...1.408058

ビルドサイズ:236 MB
シーンのロード時間:0.02138

ビルドサイズは3分の1ほどになりましたがシーンのロード時間はほぼ変わりませんでした。
またゲームの起動時間は測定方法が分からなかったので測定できませんでしたが体感には全く差は感じられませんでした。

#まとめ
Crunch圧縮をすることでビルドサイズが劇的に小さくなった上に解凍によるオーバーヘッドは全く感じられませんでした。特にアセットバンドルからのシーンロードの際にはCrunch圧縮した方が圧倒的にロードが速かったです。すべてのデータを毎度ネットワークからロードしてくるWebGLなどではさらに大きく差が開くことでしょうし、モバイルアプリにおいてもダウンロードサイズを抑えるための有効な手段になるはずです。
環境によっても変わってくるでしょうが基本的にはCrunch圧縮はしていく方向でいいのではないでしょうか。
ただしテクスチャの各辺の長さが4の倍数でなければ圧縮できませんし、Crunchは不可逆圧縮なので画像が劣化する可能性がある点は注意が必要です。

12
4
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
12
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?