Unreal Engine Programming
Unreal Engine 5 - CPP先にAnimation Blueprintとかを準備してから
段階的にCPPとBlueprintを混ぜ合わせながら色々試す
一人称視点+移動時に歩くアニメーションが動く状態になります。
1. AB_Mainというブループリントの 状態マシン
2. 状態マシン Ground Locomotion
3. 状態マシン Ground Locomotion - Idle状態
4. 状態マシン Ground Locomotion - IdleからWalkへの遷移
5. 状態マシン Ground Locomotion - WalkからIdleへの遷移
6. 状態マシン Ground Locomotion - Walk, Idle状態遷移準備
下はアニメーションインスタンスのコードです 上のアニメーションブループリントの親クラス。
#####
File:MainAnimInstance.h
#pragma once
#include "CoreMinimal.h"
#include "CPPCharacter.h"
#include "GameFramework/Pawn.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Animation/AnimInstance.h"
#include "MainAnimInstance.genereated.h"
UCLASS()
class CPPCHARACTER_API UMainAnimInstance : public UAnimInstance {
GENERATED_BODY()
public:
virtual void NativeInitializeAnimation() override;
UFUNCTION(BlueprintCallable, Category = "AnimProps")
void UpdateAnimationProperties();
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Movement")
bool bIsMoving;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Movement")
class APawn* Pawn;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Movement")
class ACPPCharacter* MainCharacter;
};
#####
File:MainAnimInstance.cpp
#include "MainAnimInstance.h"
void UMainAnimInstance::NativeInitializeAnimation() {
Super::NativeInitializeAnimation();
if (Pawn == nullptr) {
Pawn = TryGetPawnOwner();
if (Pawn) {
MainCharacter = Cast <ACPPCharacter>(Pawn);
}
}
}
void UMainAnimInstance::UpdateAnimationProperties() {
if (Pawn == nullptr) {
Pawn = TryGetPawnOwner();
}
if (Pawn) {
FVector Speed = Pawn->GetVelocity();
FVector LateralSpeed = FVector(Speed.X, Speed.Y, 0.f);
MovementSpeed = LateralSpeed.Size();
if (MainCharacter == nullptr) {
MainCharacter = Cast<ACPPCharacter>(Pawn);
}
if (MainCharacter) {
if (MainCharacter->GetCharacterMovement()->GetCurrentAcceleration().Size() > 0) {
bIsMoving = true; // 移動中
} else {
bIsMoving = false; // 移動停止
}
}
}
}
#####
File:CPPCharacter.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "CPPCharacter.generated.h"
class UInputComponent;
class USkeletalMeshComponent;
class USceneComponent;
class UCameraComponent;
class UAnimMontage;
class USoundBase;
UCLASS(config=Game)
class ACPPCharacter : public ACharacter {
GENERATED_BODY()
// Pawn mesh
UPROPERTY(VisibleDefaultsOnly, Category = "Mesh")
USkeletalMeshComponent* Mesh;
// Camera
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera", meta = (AllowPrivateAccess = "true"))
UCameraComponent* MainCamera;
public:
ACPPCharacter();
protected:
virtual void BeginPlay();
public:
// 視点移動(Left/Right)
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera")
float BaseTurnRate;
// 視点移動(Up/Down)
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera")
float BaseLookUpRate;
// Sound
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay")
USoundBase* SomethingSound;
// Animation Montage
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay")
UAnimMontage* SomethingAnimation;
protected:
// 移動(前後)
void MoveForward(float Val);
// 移動(左右)
void MoveRight(float Val);
// 視点移動(左右)レート 0.0 - 1.0(0 - 100%)
void TurnAtRate(float Rate);
// 視点移動(上下)レート 0.0 - 1.0(0 - 100%)
void LookUpAtRate(float Rate);
protected:
virtual void SetupPlayerInputComponent(UInputComponent* InputComponent) override;
void Tick(float DeltaSeconds) override;
public:
// スケルタルメッシュコンポーネントを取得する
USkeletalMeshComponent* GetMesh() const { return Mesh; }
// カメラコンポーネントを取得する
UCameraComponent* GetMainCamera() const { return MainCamera; }
};
#####
File:CPPCharacter.cpp
#include "CPPCharacter.h" // Custom
#include "Animation/AnimInstance.h" // UE
#include "Camera/CameraComponent.h" // UE
#include "Components/CapsuleComment.h" // UE
#include "Components/InputComponent.h" // UE
#include "GameFramework/InputSettings.h" // UE
#include "Kismet/GameplayStatics.h" // UE
#include "GameFramework/CharacterMovementComponent.h" // UE
#include "GameFramework/Controller.h" // UE
// ACPPCharacter
ACPPCharacter::ACPPCharacter() {
GetCharacterMovement()->bOrientRotationToMovement = true;
GetCharacterMovement()->RotationRate = FRotator(0.0f, 540.0f, 0.0f);
BaseTurnRate = 45.f;
BaseLookUpRate = 45.f;
MainCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("MainCamera"))
MainCameraComponent->SetupAttachment(GetCapsuleComponent());
MainCameraComponent->SetRelativeLocation(FVector(-39.56f, 1.75f, 64.f));
MainCameraComponent->bUsePawnControlRotation = true;
}
void ACPPCharacter::BeginPlay() {
Super::BeginPlay();
//
}
void ACPPCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) {
check(PlayerInputComponent);
// Jump - UE Default
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);
// Movement
PlayerInputComponent->BindAxis("MoveForward", this, &ACPPCharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &ACPPCharacter::MoveRight);
PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
PlayerInputComponent->BindAxis("TurnRate", this, &APawn, &ACPPCharacter::TurnAtRate);
PlayerInputComponent->BindAxis("LookUp", this, $APawn::AddControllerPitchInput);
PlayerInputComponent->BindAxis("LookUpRate", this, &ACPPCharacter::LookUpAtRate);
}
void ACPPCharacter::MoveForward(float Value) {
AddMovementInput(GetActorForwardVector(), Value);
}
void ACPPCharacter::MoveRight(float Value) {
AddMovementInput(GetActorRightVector(), Value);
}
void ACPPCharacter::TurnAtRate(float Rate) {
AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds());
}
void ACPPCharacter::LookUpAtRate(float Rate) {
AddControllerPitchInput(Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds());
}
void ACPPCharacter::Tick(float DeltaTime) {
Super::Tick(DeltaTime);
}