이 글은 Inflearn - Rookiss : 언리얼 엔진4 입문 강의를 듣고 정리한 글입니다.
목차.
개요
플레이어의 다양한 행동에 대해서 애니메이션을 if-else문을 통해 제어할 수 있지만 이후 코드가 꼬이게 될 가능성이 매우 높습니다.
만약 각 행동에 대해 상태로 관리하면 깔끔하게 관리가 가능한데 이번 글에서 상태 머신을 사용해서 애니메이션을 관리해 보겠습니다.
스테이트(상태) 머신 사용 : 점프
플레이어의 움직임에 따라서 애니메이션이 작동하게 했었습니다.
여기서 점프가 추가된다면 if-else를 통해서도 구현할 수 있지만 스테이터 머신을 활용해서 점프 애니메이션을 구현해 보겠습니다.
AnimGraph 창에서 마우스 우클릭 -> state Machines를 검색 -> 스테이트 머신 새로 추가 클릭
새로 추가한 스테이트 머신을 최종 애니메이션 포즈와 연결합니다
스테이트 머신을 더블 클릭하고, 두 가지 상태를 새로 추가합니다.
이름은 각각 Ground, Jumping으로 설정하고 두 개의 상태를 각각 연결해 줍니다.
AnimGraph에서 사용하던 Idle, Walk 애니메이션을 Ground 스테이트로 Ctrl + X , Ctrl + V 해서 옮긴 뒤,
출력 애니메이션 포즈와 연결해 줍니다.
컴파일하고 저장한 뒤, 게임을 실행해 보면 잘 작동하는 것을 볼 수 있습니다.
이제 스페이스바를 누르면 점프를 하고 점프 애니메이션이 작동하도록 하겠습니다.
일단 다시 애니메이션 블루프린트로 돌아와 내 블루프린트에 눈 아이콘을 눌러보면 상속된 변수 표시가 체크 해제되어 있을 텐데 체크를 하면
전에 만들어둔 Speed 변수가 폰에서 표시되는 것을 볼 수 있습니다.
이제 점프도 변수를 활용해서 제어할 것입니다.
점프 기능 구현을 위해 AnimInstance 클래스에 변수를 추가해 주겠습니다.
.h
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Pawn, Meta = (AllowPrivateAccess = true))
bool IsFalling;
.cpp
#include "MyAnimInstance.h"
#include "GameFramework/Character.h"
#include "GameFramework/PawnMovementComponent.h"
void UMyAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
Super::NativeUpdateAnimation(DeltaSeconds);
auto Pawn = TryGetPawnOwner();
if (IsValid(Pawn))
{
Speed = Pawn->GetVelocity().Size();
auto Character = Cast<ACharacter>(Pawn);
if (Character)
{
IsFalling = Character->GetMovementComponent()->IsFalling();
}
}
}
전 코드에서 추가된 부분은 ACharacter를 캐스팅하고,
캐스팅에 성공했다면 MovementComponent를 받아와 IsFalling 함수에 접근하는 코드가 추가되었습니다.
언리얼 엔진에서 이런 식으로 기본적인 움직임부터 해서 낙하 등 다양한 함수가 이미 존재한다는 부분이 좋은 것 같습니다.
이제 키 입력을 받아와야 하니까 키 입력은 Character 클래스에 추가해 주겠습니다.
Character.cpp
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAction(TEXT("Jump"), EInputEvent::IE_Pressed, this, &AMyCharacter::Jump);
....
}
전에 W, A, S, D 입력을 통해 움직임을 구현할 때는 UpDown(value), LeftRight(value)와 같이 함수를 정의했는데 점프는 언리얼에서 기본적으로 구현되어 있기 때문에 따로 구현할 필요는 없습니다.
하지만 여전히 프로젝트 세팅을 통해서 키 입력은 설정해주어야 합니다.
전에는 축 매핑을 추가해서 좌, 우 입력키를 받아왔지만 이번에는 액션 매핑을 추가했습니다.
이제 컴파일 후 게임을 실행하면 점프가 잘 되는 것을 볼 수 있습니다.
점프 애니메이션의 추가는 매우 간단한데, IsFalling이 true일 때는 점프 애니메이션을 작동시키고 false 일때 Ground 스테이트로 넘어가서 점프 애니메이션을 종료시키면 됩니다.
이제 컴파일, 저장 후 게임을 실행하면 점프하는 순간 IsFalling 애니메이션이 작동하고 바닥에 착지하면 애니메이션을 종료시키는 것을 볼 수 있습니다.
아직 문제가 있는데 점프 애니메이션은 보통 점프하는 순간, 점프하는 중, 낙하, 착지 이런 식으로 다양한 애니메이션이 연결되어 점프 애니메이션이 완성됩니다.
이것을 위해 다른 상태를 더 추가해서 점프 애니메이션을 개선해 보겠습니다.
점프 애니메이션 개선
JumpEnd, JumpStart 상태 추가
그리고 각 스테이트에 들어가 적절한 애니메이션을 실행하도록 배치하면 됩니다.
제가 사용하는 애니메이션은 마침 Start와 Jumping, Fall 등 다양하게 있었습니다.
애니메이션이 다른 애니메이션으로 전환될 때 자연스럽게 전환되게 하기 위해
JumpStart -> Jumping 트렌지션에 Time Remaining 함수를 활용해
비율이 0.1보다 작게 남았으면 애니메이션이 끝난 것이라고 판단하게 해 주었습니다.
Jumping -> JumpEnd 트렌지션은 전과 마찬가지로 IsFalling이 false일 때 작동하게 해 주었고,
JumpEnd -> Ground 트렌지션은 클릭해 보면 Automatic Rule Based...라는 체크박스가 있는데 이것을 체크하고
경과시간을 0.2로 하면 End 애니메이션이 다 끝나가면 자동으로 Ground로 상태가 넘어가게 됩니다.
이제 게임을 실행해서 점프를 하면 JumpEnter, Jumping, JumpEnd 모두 자연스럽게 이어집니다.
'언리얼' 카테고리의 다른 글
[UE4] 언리얼 엔진 기초 : 델리게이트(Delegate) (0) | 2023.08.23 |
---|---|
[UE4] 언리얼 엔진 기초 : 애니메이션 몽타주(Animation Montage) (0) | 2023.08.23 |
[UE4] 언리얼 엔진 기초 : 애니메이션 기초 (0) | 2023.08.21 |
[UE4] 언리얼 엔진 기초 : 블루프린트 클래스 사용하기 (0) | 2023.08.21 |
[UE4] 언리얼 엔진 : 스타터 콘텐츠(StarterContent) 삭제하기 (0) | 2023.08.19 |