++bibouroku

自分の知ったことは他の人の知りたいことかもしれない。Unityを中心とした備忘録。

ParticleSystemのstop actionで再生完了時の動作を指定する

ParcileSystemのstop actionではパーティクルの再生が完了したときの動作を指定することができます。
指定することができる動作は以下です。

  • None: 何も行わない
  • Disable: ゲームオブジェクトを非アクティブにする
  • Destroy: ゲームオブジェクトを削除する
  • Callback: OnParticleSystemStoppedコールバックが呼び出される

使い道

この指定があるおかげでオブジェクトプールでのエフェクト利用がやりやすくなります。
パーティクルの再生が完了したらオブジェクトプールへ返却する処理がグッと書きやすくなります。

Cinemachine Trigger Action で指定領域でのVirtual Cameraを指定する

トリガーコライダーにヒットしたら指定のVirtual Cameraを有効化する。 こういうことやりたいなぁと思っていたらCinemachineに最初から入っていました。

Cinemachine Trigger Actionというコンポーネントです。 このコンポーネントを使用すると以下のようにVirtual Cameraを有効化・無効化することができます。

f:id:y-ramen:20181124194653g:plain

Cinemachine Trigger ActionのActivateアクションでMoveToTopOfPrioritySubqueueを呼び出しています。
このメソッドを呼び出すと同じプライオリティのカメラが複数ある場合に自身が選択されるようになります。
つまり、非アクティブなVirtual Cameraをアクティブにしたときと同等の効果が得られます。
そのため、事前にVirtualCameraを非アクティブにしておく必要はありません。

さらに、以下のようなCinemachineでカメラを運用するにあたり必要になりそうな機能はあらかた入っている優れものです。

  • ヒットしたオブジェクトのタグでのフィルタリング
  • 初回は反応をスキップする

※文中のスクリーンショットFree Platform Game Assetsというアセットを使用しました。

同じプライオリティのVirtualCameraが複数ある場合の初期VirtualCamera選択ルール。そして、指定方法。

  • 同じプライオリティのVirtualCameraがシーン内に複数ある
  • そのプライオリティがシーン内の最高値である
  • VirutalCameraがすべてActiveな状態

このシチュエーションの場合、最後にOnEnableが実行されるVirtualCameraがCinemachineBrainが最初に見るVirtualCameraとなります。

CinemachineVirtualCameraBaseのOnEnableでMoveToTopOfPrioritySubqueueと同等の処理が実行されるためです。

初期選択されるVirtualCameraはスクリプトの実行順に依存するため、このような場合は初期選択させたいVirtualCameraのMoveToTopOfPrioritySubqueueを呼び出して初期選択されるVirtualCameraを指定するとよいです。

Audio ManagerのDSP Buffer SizeでAndroidの音再生遅延が改善されるかもしれない?

Unityで開発したアプリをAndroidで動作させると音の再生遅延が目立つ事が多いのですが、DSP Buffer Sizeで多少症状が改善されるかもしれません。

ちなみに、本格的にAndroidの再生遅延へ対応するには以下の2つの方法だと思います。

再生遅延をなんとかしたいが、いろいろ事情があってミドルウェア利用やネイティブプラグイン開発が難しい場合、
Buffer Sizeを変更するだけならすぐにできるので試してみると良さそうです。

Audio ToolkitのAudioControllerに指定されているオーディオクリップのデータをロードする

今日、Audio ToolkitというUnityでのサウンド管理アセットを触っていました。

Audio Toolkitで再生するオーディオクリップはAudioControllerというコンポーネントに関連付けられているのですが、AudioControlerに関連付けられているクリップのLoadAudioDataを呼び出すメソッドが用意されていなかったので作成しました。

/// <summary>
/// Audio ToolkitのAudioControllerに指定されているオーディオクリップのデータをロードする
/// </summary>
/// <param name="controller"></param>
static void LoadAudioData(AudioController controller)
{
    foreach (var category in controller.AudioCategories)
    {
        foreach (var item in category.AudioItems)
        {
            foreach (var subitem in item.subItems)
            {
                subitem.Clip.LoadAudioData();
            }
        }
    }
}

(...ただAPIを呼び出しただけ)

LoadAudioDataの必要性

AudioClipのPreload Audio Dataにチェックを入れない運用を想定しているためです。
チェックを入れるとゲーム起動時にサウンドデータを読み込みが行われます。また、確認したところUnloadAudioDataを実行しても破棄されない挙動となっていました。
なるべく必要ある時だけメモリにデータを乗せるようにするためPreload Audio Dataにチェックを入れない運用を考えています。

Preload Audio Dataにチェックを入れない場合、どこかでデータをロードする必要があります。
データロードはPlay系メソッドを呼び出すかLoadAudioDataを呼び出すと行われるのですが、再生遅延を考慮し事前にLoadAudioDataを呼び出す方針を取りました。

ただ、どちらも一長一短あるのでどちらが良いかはプロジェクト要件しだいかなという感じです。
前者の場合、本当に使用されるデータだけがメモリに乗るというメリットがありますが最初のSE再生時にロードが挟まるため再生遅延を招く可能性があるというデメリットがあります。
後者の場合、ロードされている状態でPlayを行うのですぐに再生できるメリットが、使用しないSEもメモリに乗ってしまうデメリットがあります。

ロードが早くなるかもしれないAsync Upload Pipeline(AUP)を忘れないようにメモ

  • Async Upload Pipelineというロードパイプラインがあり、2018.3からテクスチャとメッシュのロードがこのパイプラインで行われる。
    • ※例外があり、読み込み/書き込み有効のテクスチャとメッシュ。圧縮されたメッシュには使用されない。
  • Async Upload Pipelineの設定値がいじれる用になっており、推奨される設定がブログ記事で紹介されている。
  • 設定によりロード時間が2倍早くなった例もある。
  • Unity2018.3を導入した際に見直したい内容