目次

Wwise SDK 2018.1.11
Wwiseモーションの統合

モーションは、コントロールインターフェースのハプティックフィードバックをユーザーがコントロールするための機能です。Wwiseでは、アプリケーションのオーディオを管理するために使用するのと同じ機能セットでモーションを管理できます。Wwiseにとって、モーションデータもオーディオデータも同じです。つまり、オーディオ用に提供された機能は、全てモーションでも使えます。Wwiseモーション機能を使って利用できるハプティックフィードバックは、2種類あります。プロジェクトのオーディオシグナルを使ってモーションに変換するか、Motion Generatorソースを使って専用のモーションシグナルを生成します。この機能は、対応するコントローラがあれば、WindowsのWwiseオーサリングツール上で直接テストできます。

モーションコンポーネント

モーション機能は、Wwiseサウンドエンジンのプラグインシステムによってアプリケーション内で作動しますが、2つのモジュールに分けることができ、それがMotion Generatorというオーディオソースと、Wwise Motionというオーディオデバイスです。Motion Generatorはオプションですが、正確で柔軟なモーションデザインを作成するための、高い性能のツールです。

Motion シンクプラグイン

Motionシンクプラグインは、サウンドエンジンとモーション対応のデバイスの間のリンクとして考えることができます。ほかのシンクプラグインと同様に、リスナーのセットからデータを受信して、このデータをデバイスに「見せる」役割を担います。このプラグインは別のライブラリの中にあり、オーサリングツールとアプリケーションの両方に入れる必要があります。詳細は、 ファイルロケーションの解決 のセクションを参照してください。

Motion Generatorソースプラグイン

Motion Generatorソースプラグインは、ハプティックフィードバック用のエフェクト動作をデザインするための、非常に便利で正確な方法です。ほかのオーディオソースと同様に、Motion GeneratorをWwiseプロジェクトのSound SFXノードに追加すれば、カーブ形状のハプティックフィードバックを生成できます。Sound SFXノードに、モーション対応バスに設定されたアウトプットバスがあることを確認してください。

モーションの設定

あなたのアプリケーションでモーションを使うには、全てのコンポーネントを正しく設定する必要があります。なお、オーディオワークフローに該当するコンセプトは、全てモーションにも該当します。同じバス、リスナー、エミッタを利用します( リスナーの統合 を参照)。

Wwise Authoringの設定

デバイスにサウンドデータやモーションデータを送信するには、ライセンス取得済みのWwise MotionシェアセットをWwiseプロジェクトのAudio Deviceフォルダに追加します。Audio Deviceフォルダは、Project ExplorerのShareSetsタブにあります。Wwise Motionシェアセットは、サウンドエンジンがモーション対応デバイスとのインターフェースとして利用するAudio Deviceプラグインです。Wwise Motionシェアセットを最上位のオーディオバスにアサインすることも、重要です。モーションバスという用語は、簡略化すると、Wwise Motionシェアセットをアサインした最上位のオーディオバスのことです。プロジェクトでモーションバス階層を1つだけ設定する習慣にすると、トラブルシューティングやモニタリングのときに便利です。これで、どのサウンドSFXのアウトプットバスでも、モーションバスに設定して、ハプティックフィードバックを作成できます。一般的に、モーションバスを使用するサウンドSFXエレメントは、Motion Generatorソースも使用します。オーディオとモーションを同時に使うには、サウンドSFXに少なくともモーションバスが1つと、アウトプットバスまたはAuxバスのオーディオバスが1つ、必要です。

ゲームのセットアップ

ゲーム側では、まず別のライブラリである AkMotionSink とのリンクを確実に設定します。このライブラリは、対応プラットフォームの標準コントローラのサポートを提供します。また、 SDK\include\AK\pluginの下にある、AkMotionSinkFactory.hファイルも、含める必要があります。このファイルを含めることでプラグインが自動的に登録されるので、非常に重要です。

Note: Unityは、プラグインライブラリを自動的に管理します。マニュアルで AkMotionSink を追加する必要がありません。

対応するコントローラ一覧と追加要件については、下表を参照してください。

プラットフォーム デバイス 追加要件
Android バイブレーション対応のAndroidデバイス
iOS 非対応。iOSデバイスの様々なハプティックフィードバックAPIは、Apple®の仕様制限のため、AudiokineticのMotion機能対応の要件を満たしていません。
Linux 非対応。
Mac 非対応。
PlayStation 4 DUALSHOCK 4
PlayStation Move
Switch Joy-Con
Windows Xbox One コントローラー
Xbox 360コントローラー
DirectInput コントローラー
XInput.lib
Dinput8.lib
Winmm.lib
Xbox One Xbox One コントローラー

あなたのアプリケーションでモーションを使うデバイスごとに、専用アウトプットを追加する必要があります。例えば、分割画面のゲームで4人のプレイヤーが参加する場合、コントローラでハプティックフィードバックを受信するには、4つのアウトプットを追加する必要があります。アウトプットデバイスを追加するには、Wwise APIファンクションの AK::SoundEngine::AddOutputを使い、シェアセット名(Wwiseプロジェクトで設定済み)を、 AkOutputSettings パラメータで指定します。さらに、複数のデバイスを接続することもあるので、デバイスIDを提供する必要があります。デバイスIDの詳細については、下表を参照してください。1つのコントローラを使うときの設定を簡単にするために、デフォルトデバイスIDがあります。"0"を使うと、Motionシンクが、モーション対応の最初の接続済みデバイスをターゲットにします。

プラットフォーム デバイス 情報
Android バイブレーション対応のAndroidデバイス 0を使います。
iOS 非対応。 -
Linux 非対応。 -
Mac 非対応。 -
Windows XboxOne controller
Xbox360コントローラ
0から3までのプレイヤインデックスを使います。
Windows DirectInputコントローラ DIDEVICEINSTANCEに保存されたguidProductを使います。guidProductをハッシュするには、 AK::FNVHash32を使います。
PlayStation 4 DUALSHOCK 4 UscePadOpen、またはscePadGetHandleが返却したデバイスのハンドルを使います。 </r>
PlayStation 4 PlayStation Move scePadOpen、またはscePadGetHandleが返却したデバイスのハンドルを使います。
XboxOne XboxOne コントローラー IGamepadオブジェクトに保存されたIDを使います。
Switch Joy-Con 希望するインデックスのnn::hid::NpadIdを使います。

なお、ゲームコントローラーは物理的に切断されたり、接続問題で切断されたりすることがあります。リソースを無駄に使用していない限り、これがサウンドエンジンに悪影響を及ぼすことはありません。デバイスが長時間、接続が切れた状態だと考えられる場合は、 AK::SoundEngine::RemoveOutputをコールして、対応する AddOutput()ファンクションコールが返却するAkOutputDeviceIDを提供してください。これでリソースが解放されます。

マルチプレイヤーの場合の検討事項

モーションアウトプットは、ほかのセカンダリアウトプットと同じで、制約事項や要件も同じです。作成中のゲームがシングルプレイヤーで、ローカルでゲームをコントロールしているプレイヤーが1人だけの場合は、Listener/Game Object の設定が非常に簡単です。通常は新しいモーションアウトプットに、メインのオーディオアウトプットと同じデフォルトのリスナーを再利用します。つまり、シングルプレイヤー設定でリスナーを管理する必要はほとんどありません。 

マルチプレイヤーゲームの場合はモーションアウトプット1つに対して、Listener/Game Objectを1つ作成する必要があります。それぞれのプレイヤーが、自分のゲーム状況によって、自分用のハプティックフィードバックのミックスをもつために必要なのです。デバイスに関連付けられたリスナーの初期化を、アウトプットが \c AK::SoundEngine::AddOutput()で初期化されるのと同時に行う必要があります。特定のリスナーがあれば、サウンドやモーションのルーティングのレイヤが1つ増えます。特定のプレイヤーのリスナーに限定して関連付けられているゲームオブジェクトに対してイベントを再生する場合は、そのプレイヤーをターゲットとすることができます。関連付けは、 \c AK::SoundEngine::SetListenersをコールして行います。リスナーやゲームオブジェクトの詳細は、 \ref soundengine_listeners を参照してください。なお、同じゲームオブジェクトに複数のリスナーを関連付けることもでき、その結果、全てのリスナーに対するブロードキャスト(配信)のような効果となります。

<table border="0" cellspacing="0" cellpadding="2"><tr><td valign="top"><img src="images/Note.gif"></td><td><b>Note:</b> エミッタがリスナーとしてモーションアウトプットに設定されている場合も、サウンドをモーションバス階層にルーティングする必要があります。</td></tr></table> 

以下は、モーションが使えるようにアプリケーションを設定する方法について、例を通して説明します。また、SDKサンプルに含まれるIntegration Demo (DemoMotion.cpp) のDemo Motionも参照してください。全ての対応プラットフォーム用に、それぞれ動かせるデモを提供しています。

シングルプレイヤーの設定

最初に一般的なプラグイン管理のルールとして、ほかのプラグインと同様に、該当するファイルを含めて、ライブラリにリンクする必要があります。(Wwiseネイティブデプロイメントに限った設定です。Unityでは不要です。)

#include "AkMotionSinkFactory.h" //Link to AkMotionSink.lib, implements the output to ga
#include "AkMotionGeneratorSourceFactory.h" //Link to AkMotionGenerator.lib, implements the Motion Generator source.

次に、あなたがWwiseプロジェクトで指定したモーションシェアセット名を使って追加アウトプットを追加しますが、今回の名前は"Wwise_Motion"です。最初に接続されたゲームコントローラを使いたいので、アウトプットIDは0にします。

AkOutputSettings outputSettings("Wwise_Motion", 0);
AK::SoundEngine::AddOutput(outputSettings);

次に、通常通りにイベントを再生します。Wwiseプロジェクト内で、"Play_Explosion"イベントがポイントするのは、"Wwise_Motion"シェアセットをAudio DeviceにアサインしてあるバスにルーティングされたサウンドSFXです。

AkGameObjectID explosionGO = 100;
AK::SoundEngine::RegisterGameObj(explosionGO, "Explosion");
AK::SoundEngine::PostEvent("Play_Explosion", explosionGO);

マルチプレイヤーの設定

念のための確認ですが、マルチプレイヤーゲームとは、「同じコンソールで複数のプレイヤー」を意味するのであって、「ネットワーク接続のマルチプレイヤーゲーム」ではありません。マルチプレイヤーのシナリオで、モーションなど、そのプレイヤー専用のアウトプットのミックスは、プレイヤーのゲーム内の視点を表現できるように、変える必要があります。そのためには、プレイヤーごとのリスナーが必要です。

int NUM_PLAYERS = 4;
const AkGameObjectID OBJ_FOR_PLAYER[MAX_PLAYERS] = {100 ,200, 300, 400}; // Game Object IDs are arbitrary.
for(int i = 0; i < NUM_PLAYERS; i++)
{
AK::SoundEngine::RegisterGameObj(OBJ_FOR_PLAYER[i]); // Register a GameObject to use as Listener.
AK::SoundEngine::SetListeners(OBJ_FOR_PLAYER[i], &OBJ_FOR_PLAYER[i], 1); // Make the Game Object listen to itself.
}

次に、プレイヤー別にそれぞれアウトプットを追加します。複数のシェアセットは不要で、どのシェアセットでも何回も使えます。コントローラ別に、本当のデバイスIDを提供する必要があります。これは、Windowsで、Xboxコントローラのレイです。それぞれのプラットフォームでデバイスIDを取得する方法については、 ゲームのセットアップ の表を参照してください。

const AkUInt32 DEVICE_SPECIFIC_ID[MAX_PLAYERS] = {0, 1, 2, 3}; // Windowsで、Xboxコントローラの場合は、デバイスIDは単純に0から3までです。ほかのプラットフォームは、要件が異なります。
for(i = 0; i < NUM_PLAYERS; i++)
{
AkOutputSettings settings("Wwise_Motion", DEVICE_SPECIFIC_ID[i]); // "Wwise_Motion" シェアセットを使い、デバイスDEVICE_SPECIFIC_ID[i]を実行します。
res = AK::SoundEngine::AddOutput(settings, &motionOutputIDs[i], &OBJ_FOR_PLAYER[i], 1); // アウトプットを追加して、適切なリスナーをリンクします。
}

次に、通常通りにイベントを再生します。Wwiseプロジェクト内で、"Play_GunFire"イベントがポイントするのは、"Wwise_Motion"シェアセットをAudio DeviceにアサインしてあるバスにルーティングされたサウンドSFXです。

AK::SoundEngine::PostEvent("Play_GunFire", OBJ_FOR_PLAYER[0]); // これが再生されるのは、プレイヤー0のコントローラだけで、それはゲームオブジェクトとリスナーの関係のためです。

複数のデバイスに影響するイベントを再生するには、新しいゲームオブジェクトを設定して、それぞれのプレイヤーのリスナーがそれを聞くように、設定する必要があります。

AK::SoundEngine::RegisterGameObj(explosionGO, "Explosion"); // エクスプロージョンを再生するゲームオブジェクトを登録します。
AK::SoundEngine::SetListeners(explosionGO, OBJ_FOR_PLAYER, 4); // このゲームオブジェクトにプレイヤー達の4つのリスナーを全て接続して、全員がモーションエフェクトを受信できるようにします。
AK::SoundEngine::PostEvent("Play_Explosion",explosionGO ); // 4つのリスナーが全てexplosionGOに紐づいているので、Play_Explosionイベントが、全員にブロードキャストされます。

また、IntegrationDemoサンプルの中の DemoMotion クラスも、参照してください。マルチレイヤ設定の例を提供しています。

チェックリストと、トラブルシューティング

特定のデバイスが、1つのデバイスでモーションを受信するには以下を実行する必要があります:

  • あなたのWwiseプロジェクトのオーディオデバイスに、Wwise Motionシェアセットを追加します。
  • 最上位のオーディオバスを作成して、そのシェアセットとして、今追加したWwise Motionを設定します。
  • サウンドSFXを作成して、モーションバス階層にルーティングします。
  • ゲーム内で、AkMotionSinkFactory.hを含めることで AkMotionSink ライブラリにリンクして、AkMotionSinkライブラリにリンクしてください。
  • モーションイベントをコールしたり受信したりするためのゲームオブジェクトを、AK::SoundEngine::RegisterGameObjを使って作成します。
  • Wwise MotionシェアセットとデバイスIDを使い、 Ak::SoundEngine::AddOutputをコールします。マルチプレイヤーの場合は、それぞれのプレイヤー用にリスナーオブジェクトを提供します。
  • あなたのイベントを、オーディオイベントの場合と同様にトリガーします。

WwiseプロジェクトでMotionを使うには

  • あなたのWwiseプロジェクトのオーディオデバイスに、Wwise Motionシェアセットを追加します。
  • 最上位のオーディオバスを作成して、そのシェアセットとして、今追加したWwise Motionを設定します。
  • サウンドSFXを作成して、モーションバス階層にルーティングします。
  • Audio Preferencesで、モーションを使うバスに移動して、そのデバイスに設定するモーションデバイスを、リストから選びます。

プロファイリング

問題のトラブルシューティングをする場合は、あなたのアプリケーションをプロファイリングすることを推奨します。オーサリングツール内でアプリケーションをプロファイリングするには、接続してから、Profilerレイアウト(F6)を開きます。問題の根源を理解するために、役立つツールがいくつかあります。Capture Logビューで、赤字で表示されるエラーコードを確認できます。Graphビューで、サウンドエンジンのパイプラインのイメージ図を確認できます。パイプラインの最後に、モーションデバイスが表示されるはずです。なければ、指定したデバイスをサウンドエンジンが見つけられなかったということです。Emitter/Listenerタブも、非常に便利なビューです。エミッタとリスナーのペアが、全て表示されます。モーションエフェクトが作動しない場合は、あなたがモーションデバイスに指定したリスナーが、エミッタに関連付いていない可能性があります。

モーションエフェクトをトリガーしても実行されない場合は、以下を行います:

  • Capture Logを見て、プラグインの登録エラーがないか、確認します。あれば、AkMotionSinkFactory.hが含まれているか、またAkMotionSinkライブラリにリンクしているかを、確認してください。
  • サウンドエンジンがデバイスの初期化に成功したか、確認します。していなければ、ゲームが AddOutput をコールしたときにエラーが表示されます。
  • 再生したサウンドSFXが、モーションデバイスにつながったバスにルーティングされているか、確認します。確認するには、サウンドSFXのAudio Busプロパティや、バスのAudio Deviceプロパティを見ます。
  • Voices Graphタブで、どのエミッタがトリガーされたのかを探します。Emitter-Listenerタブで、関連付けされたリスナーがあることを確認します。同じゲームオブジェクトがエミッタでありリスナーであることも、可能です。それ以外の場合は RegisterGameObj、 SetListeners、そして AddOutput へ出したコールを確認してください。
  • 希望するアウトプットデバイスに関連付けされたリスナーが、リスナーとして設定されていることを確認します。
  • また、今まで出したAPIコールの結果にも注目してください。エラーが返されていないことを確認します。

Androidデバイスの場合は忘れずに、アプリケーションのAndroidManifest.xmlファイルに、パーミッションを以下の通りに追加してください:

<uses-permission android:name="android.permission.VIBRATE"/>