はじめに
本記事は、サムザップ #1 AdventCalendar 2020の12/9の記事です。
昨日の記事は@kanasaki_kenjiの「最高の振動をデザインするための下準備〜UnityからCore Haptic FrameWorkを使ってみた〜」です。
導入きっかけ
私は、Unityを使ったゲーム開発をしております。
インゲームなどの60FPSをキープしたい、そしてプレー中にムービーを流したいなどの要望を受けました。
私が担当したプロジェクトでは、ムービーを再生するのに利用しているプラグインとして
CRI Manaを利用していました。
CRI Manaにはムービーをシームレスで再生するという機能などいくつかありますが、
低スペックの端末だとシームレスの再生の切り替えのタイミングでコマ落ちすることが調査して判明しました。
そこで今回どうやって工夫したかを説明したいと思います。
対処方法
いくつか試してみてので、その時のことを書きます
- アセットバンドルとして登録されているムービーを一つに連結してしまう
こちらであれば簡単だなと思って実際にやってみたのですが、
これだとファイルサイズのでかいムービーデータになってしまい
ダウンロードが遅すぎるという欠点がでました
- アセットバンドルとして登録されているムービーを分割した状態で並列ダウンロードさせて連結させる
/// <summary>
/// Save(デバイスで読み書きできるパスにセーブする)
/// </summary>
/// <param name="index">index</param>
/// <param name="totalbyte">分割されたファイルのトータルバイト数</param>
/// <param name="usmFileName">ムービーファイル</param>
/// <param name="outputFilePath">出力先ファイルパス</param>
/// <returns></returns>
private async UniTask Save(int index, long totalbyte, string usmFileName, string outputFilePath)
{
if(File.Exists(outputFilePath))
{
FileInfo fileInfo = new FileInfo(outputFilePath);
// 端末のファイルとコピー元のサイズをチェック
if(fileInfo.Length == totalbyte)
{
//同じなので終了
return;
}
// 初回のチェックの場合ファイルを削除しておく
if(index == 0)
{
File.Delete(outputFilePath);
}
}
TextAsset asset = assetLoader.LoadResource<TextAsset>(usmFileName);
byte[] bytes = asset.bytes;
// ファイル書き込み
using (var stream = new FileStream(outputFilePath, FileMode.Append, FileAccess.Write))
{
stream.Write(bytes, 0, bytes.Length);
}
}
こちらのSaveメソッドをusmFileNameの数だけ回し
それらをファイルごとに書き込むという手法をとりました。
更に端末にセーブした元を比較するのにファイルサイズを比較しないとアセットの差し替えに対応できないので
チェックし初回のチェックがついているときには、元のファイルを削除しておくという対応を加えました。
変更がなければ、生成しないという手法を採用しました。
これによりムービーが再生されてしまえば、シームレスで切り替えるという処理がなくなり
60FPSをキープすることが可能なりました。
まとめ
意外にこれするだけで、効果がかなりありました。もしも困っていたら試してみてください。
明日の記事は、@norimatsu_yusukeです。