Skip to content

LoadFromStreamについて

mao-test-h edited this page Mar 16, 2019 · 1 revision

ここでは「AssetBundle.LoadFromStream」と「AssetBundle.LoadFromStreamAsync」についてのメモを纏めていく。
(ちなみに上記2点は2017.2ぐらいから入った機能らしい)

StreamからAssetBundleをロードできるAPI

  • その性質上、LZMAと言った形式はメモリに全展開されてしまうが、LZ4や非圧縮はStreamから直接ロードする事が可能。
    • → その為に読み込み時に余計なメモリを展開せずに済むので省メモリで済む。
    • 使い所としてはこのリポジトリの本題である暗号化済みのAssetBundleを復号しつつ読み込むと言った状況で使えるかと思われる。

制約について

但しStreamの実装については幾つかの制約がある。

  1. データのStreamの位置は0からである必要がある。
  2. データをロードする前にシークの位置を0に設定する必要がある。
  3. ストリーム内の位置は他のプロセスによって変更されないことが想定されている。
  4. Stream.CanReadは必ずtrueを返すこと
  5. Stream.CanSeekは必ずtrueを返すこと
    • ※上記の制約からCryptoStreamと言ったものは使えない。
  6. MainThread以外から呼び出される想定がある。
    • Seek()とRead()はUnityのNativeThreadから呼び出せる必要がある。
  7. 特定の状況に於いてUnityはAssetBundleデータのサイズを超えて読み込もうとする。
    • Streamの実装としては例外を投げずに処理する必要がある。
    • 実際に読み込まれたバイト数も返す必要がある。
      • ※AssetBundleデータの最後に渡されたバイトは含まれない
  8. データの最後から読み込もうとする場合、Streamの実装は0バイトを返して例外を投げないようにする必要がある。

managedReadBufferSize

引数で指定する項目。
こちらでロード中にUnityが使用する読み取り用のバッファのサイズを上書きすることが可能。
デフォルトは32KB。

  • ネイティブコードからマネージドコードへの呼び出し回数を減らすために、バッファのサイズがmanagedReadBufferSizeのバッファリーダーを使用してStreamからデータを読み取る。
    • managedReadBufferSizeを変更すると特にモバイルデバイスでのロードパフォーマンスに影響する可能性がある。
    • managedReadBufferSizeの最適値はプロジェクトによって様々。
    • 試すのに良い範囲としては、8KB16KB32KB64KB128KB
    • 以下の条件を満たす場合には値が大きいほど適している可能性がある。
      • 圧縮されたAssetBundle
      • 大きいサイズのデータを含んだAssetBundle
      • AssetBundleに多数のAssetが含まれて無く、順番にロードされる場合
    • 以下の条件を満たす場合には小さい値ほど適している可能性がある。
      • 圧縮されていないAssetBundle
      • 小さなAssetの読み込みが多い場合
      • AssetBundleに多数のAssetが含まれており、ランダムな順序でロードされる場合

Streamの破棄タイミングについて

  • AssetBundle.Unloadよりも前にStreamを破棄してはならない。