サウンドデータの波形をForceFeedBackEffectのキーに変換する方法

お世話になっております。

大変申し訳無いのですが、既にご確認頂いている通り ForceFeedBackEffect はサウンドアセットには対応していません。また、サウンドアセットを元にコントローラを振動させることができる HapticEffect という機能があるのですが、こちらはVR専用コントローラ向けでありゲームパッド用の実装は存在しないため非VR環境では動作しません(
詳しくは SetHapticFeedbackValues 関数でエンジンコード内を検索して頂けますと確認可能です ) 。

現時点で頂いた要望を実現する場合は以下の対応が考えられます。

  • ゲームパッド向けの SetHapticFeedbackValues 関数を実装する
  • HapticEffect の値を ForceFeedback に渡すことで振動させる
  • サウンドアセットからカーブアセットを作成するエディタ機能を実装する

ゲームパッド向けの SetHapticFeedbackValues 関数を実装する
ForceFeedBackとHapticsEffectは APlayerController::ProcessForceFeedbackAndHaptics 関数で更新・反映されています。

UpdateForceFeedback(InputInterface, ControllerId);

const bool bAreHapticsDisabled = (CVarDisableHaptics.GetValueOnGameThread() > 0) || bDisableHaptics;
if (!bAreHapticsDisabled)
{
	// Haptic Updates
	if (bLeftHapticsNeedUpdate)
	{
		InputInterface->SetHapticFeedbackValues(ControllerId, (int32)EControllerHand::Left, LeftHaptics);
	}
	if (bRightHapticsNeedUpdate)
	{
		InputInterface->SetHapticFeedbackValues(ControllerId, (int32)EControllerHand::Right, RightHaptics);
	}
	if (bGunHapticsNeedUpdate)
	{
		InputInterface->SetHapticFeedbackValues(ControllerId, (int32)EControllerHand::Gun, GunHaptics);
	}
}

そして、各プラットフォーム毎に実装された SetHapticFeedbackValues 関数が呼ばれます。例えばWindowsの場合は以下の関数が呼ばれます。

void FWindowsApplication::SetHapticFeedbackValues(int32 ControllerId, int32 Hand, const FHapticFeedbackValues& Values)
{
	if (FApp::UseVRFocus() && !FApp::HasVRFocus())
	{
		return; // do not proceed if the app uses VR focus but doesn't have it
	}

	for (auto DeviceIt = ExternalInputDevices.CreateIterator(); DeviceIt; ++DeviceIt)
	{
		IHapticDevice* HapticDevice = (*DeviceIt)->GetHapticDevice();
		if (HapticDevice)
		{
			HapticDevice->SetHapticFeedbackValues(ControllerId, Hand, Values);
		}
	}
}

上記の関数における ExternalInputDevices にはそのプラットフォームに対応したVR専用コントローラしか入っていないため、HapticeEffectではゲームパッドを振動させることができません。 そのため、この部分に Values の中身を元にゲームパッドを振動させる処理を追加することで実現可能です。 しかし、各プラットフォーム毎に同様の対応を入れる必要があるというデメリットがあります。


HapticEffect の値を ForceFeedback に渡すことで振動させる
APlayerController::ProcessForceFeedbackAndHaptics 関数における UpdateForceFeedback 関数の直前に以下のような対応を入れることで、HapticEffect の値を使ってForceFeedback経由でゲームパッドを振動させることが可能です。

ForceFeedbackValues.LeftLarge = LeftHaptics.Amplitude;
ForceFeedbackValues.RightLarge = RightHaptics.Amplitude;

(上記の対応でサウンドアセットを元にゲームパッドが振動することを確認しました。あくまで検証用の簡易実装であることにご注意ください)

こちらは非常に単純な対応な上に、既存のForceFeedbackを使用しているだけなのでプラットフォーム毎の対応を考慮する必要がありません。しかし、ゲーム内の実装にてForceFeedbackを使った振動処理とHapticEffectを使った振動処理が混在した場合、意図しない挙動が発生する可能性が出てくるかと思います。


サウンドアセットからカーブアセットを作成するエディタ機能を実装する
こちらは実行中にサウンドアセットから取得した結果を元に振動させる方法ではなく、エディタ上でサウンドデータからカーブアセットを作成することで現在手作業で行っている作業を効率化する方法です。実装する際は、 UHapticFeedbackEffect_SoundWave におけるサウンドアセットからデータを取得する処理やSound Visualizations Pluginを使って波形データを取得する処理を実装し、その結果を元にカーブアセットを作成する形になるはずです。この方法は作業フロー・効率を大きく改善するものではないかと思いますが、他の方法に比べて振動具合の微調整ができるというメリットはあるかと思います。

これらの情報を元に今後の対応方針について一度ご検討頂けますと幸いです。
よろしくお願いいたします。