概要
いくつかのプラグインを組み合わせると発生する特有の問題。
今回はADX2とZenjectを使っていて起きた問題とその対処法を紹介します。
結論
解決方法は2択
- ScriptExecutionOrderの値をいじってZenjectより早く実行させてしまう(脳筋)
- ProjectContext 内にCriWare ErrorHandler とCriWareInitializerコンポーネントを配置(多分こちらがスマート)
前提
UnityのサウンドミドルウェアといえばADX2 とWwiseだと思います。(FMODくん…ごめんな)
UnityのDIコンテナといえば「Extenject Zenject *1 」ですね。
特にADX2と自分のアプリケーションの橋渡しとなる「オレオレAudioManager/SoundManager」。
このオレオレSoundManagerはアプリのどこからでもアクセス出来るようにSingletonパターン(俗にいうSingletonMonoBehaviour)で作ることが多いです。
Singletonパターンで作ると依存性や参照がいたるところにあって保守性や拡張性で問題が出てくる為、DIコンテナを導入して極力Singletonパターンをものを減らすのはよくあると思います。
そこで「プロジェクト全体でアクセスされる」要素であるオレオレSoundManagerをProjectContextでBindするのは至極当然の流れかと思います。
問題
ProjectContext以下でBindしたオレオレSoundManager。
このオレオレSoundManagerがADXを利用していて、ADXの初期化を行おうとすると以下のエラーが出ます。

ざっくり説明すると「ADX2のプラグインが初期化されてません」ということです。
ちゃんとHierarchyには初期化のオブジェクトもありますが、このエラーは発生します。
解決方法
ScriptExecutionOrder
そこでUnityのスクリプトの実行順であるScriptExecutionOrderを見てみると
初期設定は以下のようになっています。
よくあるプラグイン同士の初期化順の取り合いによる問題です。
ADXの 初期化 に関しては別に早ければ早いほど良いので Zenject の初期化より早く 設定します。
ただ、通常動作に関してはそのままで良いので変更しないことをお勧めします。
ProjectContext で頑張る
結局のところ初期化さえしてしまえばいいので、いっそのことProjectContextにCRIWAREの初期化コンポーネントを配置してしまう戦法です。
最後に
外部のプラグインやミドルウェアを入れると開発効率が上がったり、車輪の再発明をしなくて良かったり恩恵は大きいです。
しかし、このようなプラグインの組み合わせ依存の問題は「やってみないとわからない」のが現実です。
このような現象に起きた時は「まずエラー文を正しく読む」ことが非常に重要です(初心者さんとかは英語読まないことが結構多いです)。
また、どうしても解決できない場合は、そのプラグインの提供者さんに質問やIssueをあげると良いかと思います。
参考
*1 Extenject は2020年1月現在、依然として裁判中のため、元であるZenjectを使うのが無難です(本家は全く更新されてませんが)
https://github.com/svermeulen/Extenject