こんにちは!こんばんわ!
情熱開発部プログラム課の若尾です。
早いもので11月ですね。ゲーム開発の話題に事欠かない季節ですが、今日はUE4での開発でなるべくC++で作りたい…を記事にしました。
今回はAnimInstance(AnimationBlueprint)について触れていきます。
実施開発環境
ver: UE4.26.1
OS:Windows10
Editor:VisualStudio2019
AnimInstance(AnimationBlueprint)について
AnimInstanceとは、キャラクターのアニメーションを管理・再生を司るC++クラスです。そしてこれを継承してUE4EditorでBlueprintとして、ノードベースで管理できるように作成されたのがAnimationBlueprintとなります。(以降はAnimationBlueprintをABPと表記します。)
ABPについては下の画像を見れば、ピンと来るかなと思います。
UE4 ThirdPersonSampleのThirdPerson_AnimBPから抜粋
画像のAnimgraphのように、ゲームのキャラクターの状況に応じてアニメーションの再生切替などを管理するクラスです。
AnimInstance(C++)で作るメリット
まずはUE4全体的に見たうえでのBlueprintではなくC++で作るメリットです。
- 処理負荷を軽減できる
- 履歴や競合時の見分けがしやすく、マージがしやすい
- C++の記法が使える、C++に慣れている人だと書きやすい
などがあると思います。
さらにアニメーション管理クラスであるAnimInstace(C++)で作るメリットです。
- 各モデルのアニメーションで使い回したい処理をひとつにまとめられる
ずばり、この一点です。
実はABPは、スケルトンが異なると流用できず、別のクラスファイルとして作成するしかないのです。(親子クラスの関係にして共通の処理をひとつにまとめておく…ができない)
共通の処理…例えば以下のような状態は、どのスケルトンのアニメーションでも利用できると考えられます。
- 移動速度
- 接地状態(地上にいるか空中にいるか)
これら共通の処理を、ABPを追加作成するたびに記述するのは面倒だし変更するとなると全てのクラスを書き換えるので大変ですよね。というわけで、今回は上記の処理をAnimInstace(C++)で作ってみたいと思います。
作成例
AnimInstanceの子クラス作成
UE4エディタから ファイル→新規C++クラスを選択
親クラスはAnimInstanceを指定し、作成してください。今回は、MyAnimInstance.cpp,MyAnimInstance.hという名前で作成しました。
変数や関数の作成
今回はブループリントのTickに当たる部分に処理を記載して、結果を得られるようにします。
MyAnimInstance.h
#pragma once
#include "CoreMinimal.h"
#include "Animation/AnimInstance.h"
#include "MyAnimInstance.generated.h"
/** * */
UCLASS()
class TPS_CPP_SAMPLE_API UMyAnimInstance : public UAnimInstance
{
GENERATED_BODY()
protected:
//歩行速度
UPROPERTY(BlueprintReadWrite) //このUPROPERTYを記載することでABP側からも利用できます。
float Speed = 0.0f;
//接地してない状態かどうか. 空中にいるとTrue
UPROPERTY(BlueprintReadWrite)
bool IsFall;
public:
//ABPのTickと同様に毎フレーム呼び出される処理のオーバーライドです。
virtual void NativeUpdateAnimation(float DeltaSeconds) override;
};
MyAnimInstance.cpp
#include "MyAnimInstance.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/Character.h"
void UMyAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
//Superの呼び出し
Super::NativeUpdateAnimation(DeltaSeconds);
//ABPのオーナーCharacterを取得する
ACharacter* OwnerCharacter = Cast<ACharacter>(GetOwningActor());
//OwnerCharacterにまつわる処理
if (OwnerCharacter != nullptr)
{
//速度を取得する
Speed = OwnerCharacter->GetVelocity().Size();
//空中にいるかどうかを取得する
IsFall = OwnerCharacter->GetCharacterMovement()->IsFalling();
}
}
上記を記載し、保存を行いビルド実行します。
MyAnimInstanceを継承する
UE4Editorが起動したら、早速MyAnimInstanceを継承し上記で追加した変数にアクセスしてみましょう。
新規ABPを作成
新たにABPを作成し継承する方法です。
1 . コンテンツブラウザ内で右クリックしてアニメーションBPを作成を選ぶ
2 . 任意のターゲットスケルトンを選択し、親クラスはMyAnimInstanceを選択
MyAnimInstanceを継承したABPが作られます。
既存ABPの親クラス(継承クラス)を変更する
1 . コンテンツブラウザにて変更したいABPを開きます。
2 . ツールバーからクラス設定をクリック
3 . 詳細タブから作成したMyAnimInstanceを選択します。
これで親クラスを変更できます。この際に、そのままだとコンパイルエラーや変数の名前が被っている…などが発生する可能性があるのでコンパイルが通るか確認しましょう。
ABP側で用意した変数を用いる
では、作成した変数を用いたABPのAnimGraphを例として下に記します。
StateMachine
Locomotion(State)
上記のようにABP内でAnimInstace(C++)で作った変数を扱うことができました。今後はこのクラスを親クラスにしておけば、SpeedやIsFallの取得・更新方法については明記する必要が無くなります。それらの更新方法が変わったとしてもMyAnimInstanceのファイルだけを変更すれば良いので管理も簡単になります。
是非とも試してみてください。
【免責事項】
本サイトでの情報を利用することによる損害等に対し、
株式会社ロジカルビートは一切の責任を負いません。