yamonメモ.cpp

ue4で勉強中 日々の進捗を簡単に残します。

AnimationBlueprintでEnumを使って遷移させてみた

前回までのあらすじ
LineTraceを実装してみた - yamonメモ.cpp

ActorComponentを作成し、
まずはLineTraceを管理するコンポーネントを追加してみた。

そろそろアクターをCharactorMovementComponentじゃなく、
独自のMovementComponentで動かしたいと思うようになった。

というわけで、今日はキャラのAnimationBlueprintを作成し、
新しく作成したMovementComponentで動作するようにしてみる。
 

CharactorAnimInstanceの作成

 まずはアニメーションさせて少しはそれっぽく見せるために
AnimationInstanceを追加して、AnimationBlueprintを設計してみる。

以前拝見させていただいた講演会で紹介されていた、
Enumでのアニメーション制御をやってみようと思う。

参考にさせていただいたスライド:
UE4を用いたTPS制作事例 EDF:IR アニメーション作成事例紹介


とりあえず、列挙型の追加。

// MyAnimInstance.h
UENUM(BlueprintType)
enum class ECharactorAnimationIndex : uint8
{
	Idle,
	Walk,
	Run,
};

UCLASS()
class MY_API UMyCharactorAnimInstance : public UMyAnimInstance
{
    GENERATED_BODY()

public:
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
	EMyCharactorAnimationIndex AnimIndex = EMyCharactorAnimationIndex::Idle;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "歩き速度")
	float WalkSpeed = 10.0f;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "走り速度")
	float RunSpeed = 50.0f;

};

次にAnimationBlueprint側の設定
f:id:yamonkj:20191103231307p:plain

アクター側の遷移処理(移動部分のみ)

const auto Vel = GetCurrentVelocity();
const auto Speed = Vel.Size2D();

if (Speed < AnimInstance->WalkSpeed)
{
	AnimInstance->AnimIndex = EKJCharactorAnimationIndex::Idle;
}
else if(Speed < AnimInstance->RunSpeed)
{
	AnimInstance->AnimIndex = EKJCharactorAnimationIndex::Walk;
}
else
{
	AnimInstance->AnimIndex = EKJCharactorAnimationIndex::Run;
}

アクター側から、遷移させたいタイミングでAnimIndexを更新しておくと、
勝手に遷移してくれるようにするのが目標です。

Stateを細かく分割して、複雑な制御を用いて遷移させるのは、
トランジションの繋ぎ忘れや、AI側と状態のズレが生じやすくなるのに対して、
列挙型での遷移はわかりやすいだけでなく、
通化もしやすくAI側とは別軸で考えることができるので、
特に大規模開発では良い効果があるように感じた。

まだまだ機能拡張は必要だけど、
とりあえずは速度を入れるだけで、
その状態にあったモーションを再生してくれるようになった。

次の課題

今回やっていて不便だったのは、
速度を与えて移動しているので、カプセルコリジョンのキャラクターが移動しようとすると、
その方向に倒れてしまうので、いったんの対処として「回転をロック」したのだが、
f:id:yamonkj:20191103232805p:plain
もう少し柔軟な挙動を取らせたいので、ロックせずに、
その時に接地している地形にあった回転値を入れるようにしようかと思う。

どうするのが負荷的にも優しいのかな?
CharactorMovementComponentを少し見てみようかな。

次は接地判定をどうやってとるか?を調べてみたいと思います。
接地判定を実装してみた - yamonメモ.cpp