C++コードでモーションを再生する

UnrealEngine

はじめに

※確認UEバージョン5.0.3

C++からモーションを再生する方法を解説します。

厳密にはUE側で何かしらいじらないと再生できない場合も含めていますので、その点ご了承ください。

私の知らないC++での再生方法もあるかと思います。

以下の方法以外で再生する方法がありましたらアドバイスいただけると嬉しいです!

UAnimSequence アセットを再生

AnimSequenceアセットはアニメーションデータを格納するアセットの中で一番基本的なアセットになります。

アニメーションデータ(FBXデータなど)をUE内でインポートする際に出力されるのがこのアセットになります。

UAnimSequence アセットを再生する方法は以下の2通りがあります。

PlaySlotAnimationAsDynamicMontage 関数を呼び出す

UAnimInstance::PlaySlotAnimationAsDynamicMontage 関数を使用してアニメーションアセットを再生する方法です。

この方法はアニメーションスロットを使用しますので、以下のようにABPで使用するスロットノードを接続してください。

DefaultSlotは標準で用意されているスロットになります。 とりあえず再生したい方は”DefaultSlot”を接続しましょう。

アニメーションを再生したい箇所で以下の関数を呼び出します。

UAnimMontage* UAnimInstance::PlaySlotAnimationAsDynamicMontage(UAnimSequenceBase* Asset, FName SlotNodeName, float BlendInTime, float BlendOutTime, float InPlayRate, int32 LoopCount, float BlendOutTriggerTime, float InTimeToStartMontageAt)

引数は以下の通りです。

引数名内容
Asset再生するアニメーションシーケンスアセットを指定します。nullにしたり、Montageアセットや対応していないスケルトンの場合は再生できません。(警告ログも出ます。)
SlotNodeName再生するスロット名を指定します。未入力では再生できません。デフォルトスロット(初期から用意されているスロット)を使用する場合は”DefaultSlot”と入力してください。
BlendInTime再生し始めてからウェイトが1になるまでの時間(秒)です。
BlendOutTimeウェイトを下げ始めてから再生終了時にウェイトが0になるまでの時間(秒)です。
InPlayRate再生速度です。1.0で等倍再生、2.0では倍速再生になる…はずなのですが、UE5.0.3時点でこのパラメータは使用されておらず、1.0(等倍)固定になっています
LoopCountアニメーションシーケンスを何回繰り返すか指定します。1回のみの再生であれば1を指定します。
2147483647を設定すれば(21億回も再生する前に別のアニメーションが再生される前提ですが)疑似的なループにすることはできます。が、現状このパラメータで永遠ループの設定はできません。また再生処理で小数点の誤差が顕著に出るのでお勧めしません。永遠ループさせたい場合はこの関数を呼び出した後に細工する必要があります。
BlendOutTriggerTimeブレンドアウトを開始するタイミングをずらせるパラメータです。
0未満を指定すると再生終了時のBlendOutTime前からブレンドアウトが開始されますが、0以上を指定すると再生終了時のBlendOutTriggerTime前からブレンドアウトが開始されるようになります。
InTimeToStartMontageAtアニメーションの再生開始位置を指定できます。最初から再生したい場合は0.fを指定します。

この関数では UAnimMontage::CreateSlotAnimationAsDynamicMontage_WithBlendSettings 関数を使用して指定したアニメーションアセットのみを再生するアニメーションモンタージュを作成した後、モンタージュを再生する処理を行います。

また、似たような関数に

UAnimMontage* UAnimInstance::PlaySlotAnimationAsDynamicMontage_WithBlendArgs(UAnimSequenceBase* Asset, FName SlotNodeName, const FAlphaBlendArgs& BlendIn, const FAlphaBlendArgs& BlendOut, float InPlayRate, int32 LoopCount, float BlendOutTriggerTime, float InTimeToStartMontageAt)
UAnimMontage* UAnimInstance::PlaySlotAnimationAsDynamicMontage_WithBlendSettings(UAnimSequenceBase* Asset, FName SlotNodeName, const FMontageBlendSettings& BlendInSettings, const FMontageBlendSettings& BlendOutSettings, float InPlayRate, int32 LoopCount, float BlendOutTriggerTime, float InTimeToStartMontageAt)

がありますが、これはブレンドインとブレンドアウトの補間方法などのパラメータを細かく設定できるものになります。

ABPにノードを追加してアセットの設定をAnimInstanceで行う

シーケンスプレイヤーABPに追加してアセットの設定をAnimInstanceで行う方法です。

UAnimInstanceを継承したクラスを作成してください。

作成した後、下記関数で再生するアニメーションシーケンスアセットを設定できるように関数と変数を追加します。

public:
	/**
	 * @brief 再生するアニメーションシーケンスを設定する
	 */
	void SetAnimSequence(UAnimSequence* InAnimSequence) { AnimSeqToPlay = (InAnimSequence != nullptr) ? InAnimSequence : AnimSeqToPlay; }
private:
	/* 再生するアニメーションシーケンス */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MyAnimInstance, DisplayName = "再生するアニメーションシーケンス", meta=(AllowPrivateAccess = true))
	TObjectPtr<UAnimSequence> AnimSeqToPlay;

SetAnimSequenceで設定したアニメーションシーケンスが再生されるようにABP側を編集します。

シーケンスプレイヤーノードをABPに追加してください。

デフォルトだと再生するシーケンスアセットを変更することはできないので、詳細タブからアニメーションシーケンスをピンとして公開するように変更します。

再生したいシーケンスプレイヤーメンバーをシーケンスプレイヤーノードに接続してください。

これで再生したいアニメーションシーケンスアセットで自由に再生することができます。

ただ、今の実装ですとアニメーションシーケンスを切り替える際にブレンドが行われないので、ブレンドを行いたい場合はさらに変更が必要になります。

そのため、簡単に再生しつつブレンドも行いたい場合は、PlaySlotAnimationAsDynamicMontage 関数での再生方法を推奨します。

UAnimMontage アセットを再生

AnimMontageアセットは複数のアニメーションシーケンスアセットをまとめてアニメーションアセット化したり、シーケンスアセットに依存しない高度な再生を行えたり等万能なアセットになります。

AnimMontageアセットを再生するには下記の方法があります。

GamePlayAbilityなどでもモンタージュ再生を行えますが、内部処理で同じ関数を呼んでいます。

Montage_Play 関数を呼び出す

UAnimInstance::Montage_Play 関数を使用してアニメーションアセットを再生する方法です。

この方法はアニメーションスロットを使用しますので、以下のようにABPで使用するスロットノードを接続してください。

DefaultSlotは標準で用意されているスロットになります。 とりあえず再生したい方は”DefaultSlot”を接続しましょう。

アニメーションを再生したい箇所で以下の関数を呼び出します。

float UAnimInstance::Montage_Play(UAnimMontage* MontageToPlay, float InPlayRate/*= 1.f*/, EMontagePlayReturnType ReturnValueType, float InTimeToStartMontageAt, bool bStopAllMontages /*= true*/)

引数は以下の通りです。

引数名内容
MontageToPlay再生するモンタージュアセットを指定します。
InPlayRate再生速度です。1.0で等倍再生、2.0では倍速再生になります。モンタージュアセットエディタで設定できる RateScale とは別の値になります。 (実際の再生速度はInPlayRate * RateScale です。)
ReturnValueType再生に成功した場合に戻り値として返すfloatの値を選択します。失敗した場合は0が返ります。
InTimeToStartMontageAtアニメーションの再生開始位置を指定できます。最初から再生したい場合は0.fを指定します。
bStopAllMontages同じスロットグループに所属している他のモンタージュアセットの再生を停止します。
他のモンタージュアセットの停止時に使用されるブレンドアウト時間は再生するモンタージュアセットのブレンドイン時間と同じです。
このフラグをfalseにすると再生したいモンタージュ以外のモンタージュが同時に再生されるので、ブレンドイン時間が終了しても意図しないポーズが表示されてしまう可能性があります。
厳密にモンタージュ再生を管理していないのであれば、falseにするのは危険です。

また、似たような関数に

float UAnimInstance::Montage_PlayWithBlendIn(UAnimMontage* MontageToPlay, const FAlphaBlendArgs& BlendIn, float InPlayRate /*= 1.f*/, EMontagePlayReturnType ReturnValueType /*= EMontagePlayReturnType::MontageLength*/, float InTimeToStartMontageAt/*=0.f*/, bool bStopAllMontages /*= true*/)
float UAnimInstance::Montage_PlayWithBlendSettings(UAnimMontage* MontageToPlay, const FMontageBlendSettings& BlendInSettings, float InPlayRate /*= 1.f*/, EMontagePlayReturnType ReturnValueType /*= EMontagePlayReturnType::MontageLength*/, float InTimeToStartMontageAt/*=0.f*/, bool bStopAllMontages /*= true*/)

がありますが、これはモンタージュに設定されているBlendInパラメータを無視して新たにブレンドインパラメータを適用しつつ再生する関数になります。

UBlendSpace アセットを再生

BlendSpaceアセットは少ないアニメーションシーケンスアセットを使用して、ブレンドウェイトを調整することで間のアニメーションシーケンスアセットを複数用意しなくてもそれらしいポーズを出力することができるアセットになります。

再生方法は現状以下になります。

ABPにノードを追加してアセットの設定をAnimInstanceで行う

Montage_Play 関数や PlaySlotAnimationAsDynamicMontage 関数などのようにBlendSpaceアセットを直接再生する関数は現状存在しないため、ABP側にブレンドスペースプレイヤーを置いて、AnimInstance側でブレンドスペースを設定できるようにする方法になります。

UAnimInstanceを継承したクラスを作成してください。

作成した後、下記関数で再生するブレンドスペースアセットと再生したいサンプリング座標を設定できるように関数と変数を追加します。


public:
	/**
	 * @brief 再生するブレンドスペースを設定する
	 */
	void SetBlendSpace(UBlendSpace* InBlendSpace) { BlendSpaceToPlay = (InBlendSpace != nullptr) ? InBlendSpace : BlendSpaceToPlay; }

	/**
	 * @brief ブレンドスペースのサンプリング位置を設定する
	 */
	void SetBlendSpaceSamplingCoordinate(const FVector2D& InCoordinate){ BlendSpaceSamplingCoordinate = InCoordinate; }
private:
	/* 再生するブレンドスペース */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MyAnimInstance, DisplayName = "再生するブレンドスペース", meta=(AllowPrivateAccess = true))
	TObjectPtr<UBlendSpace> BlendSpaceToPlay;

	/* ブレンドスペースのサンプリングを行う座標 */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MyAnimInstance, DisplayName = "ブレンドスペースのサンプリングを行う座標", meta=(AllowPrivateAccess = true))
	FVector2D BlendSpaceSamplingCoordinate;

SetBlendSpaceで設定したアニメーションシーケンスが再生されるようにABP側を編集します。

ブレンドスペースプレイヤーノードをABPに追加してください。

デフォルトだと再生するブレンドスペースを変更することはできないので、詳細タブからブレンドスペースをピンとして公開するように変更します。

先ほどC++側で追加したUPROPERTYをブレンドスペースプレイヤーノートに接続します。

これで再生したいブレンドスペースアセットで自由に再生することができます。

タイトルとURLをコピーしました