점프 애니메이션을 적용해보려고 한다.
목차
- c++에서 캐릭터가 점프 중인지 확인하기
- 캐릭터에 점프 애니메이션 적용하기
1. C++에서 캐릭터가 점프 중인지 확인하기
캐릭터 무브먼트 컴포넌트는 점프(체공)중인지 알 수 있는 함수가 존재한다. 이를 통해 간편하게 캐릭터의 점프 유무를 알 수 있다.
함수는 문자 그대로인 IsFalling() 함수이다.
// Header
UPROPERTY(BlueprintReadOnly, Category = "Movement")
bool IsFalling;
// cpp
void UKnightAnimInstance::NativeUpdateAnimation(float DeltaTime)
{
Super::NativeUpdateAnimation(DeltaTime);
if (KnightCharacterMovement)
{
GroundSpeed = UKismetMathLibrary::VSizeXY(KnightCharacterMovement->Velocity);
IsFalling = KnightCharacterMovement->IsFalling();
}
}
헤더의 퍼블릭이나 프로텍트 영역에 떨어지고 있는지 여부를 나타내는 변수를 만들고 cpp 파일에서 값을 저장하면 된다.
캐릭터가 떨어지고 있는지 아닌지는 프레임마다 체크해야함으로 NativeUpdateAnimation() 함수 안에 넣어주면 된다.
2. 캐릭터에 점프 애니메이션 적용하기
이제 캐릭터가 점프중인지 아닌지 알 수 있으니 점프 상태일때 해당 애니메이션을 보여주면 된다.
먼저 애니메이션 블루프린트를 열어보자
AnimGraph에서 Add New State Machine을 한다.
State안으로 들어가 지상에 있는 상태인지 공중에 있는 상태인지 알아내고 이에 맞는 애니메이션을 추가하면 된다.
어떻게 지상에 있는지 알 수 있을까? 여기서 변수를 또 추가해서 하는 것 보다는 이미 만들어진 State를 이용하면 더 편하면서 관리하기 쉽게 만들 수 있다.
다시 AnimGraph로 돌아가보자 처음 만든 state(이름을 Locomotion이라고 지었다.)에서 아웃핀을 드래그 하여 new를 입력하면 New save cached pose.. 가 나온다.
cached pose는 AnimGraph에서 계산된 결과의 애니메이션을 저장하고 여러곳에서 쓰게 해주는 노드이다. 이를 이용하여 새로 만든 state(Main State)에서 지상에 있을 때 출력될 애니메이션을 알려주려고 한다.
이름을 저대로 쓰면 알아보기 매우 힘드니 간단하게 Locomotion으로 이름을 바꿔주자.
이제 이것을 아까 전의 onGround State에 입력해주면 된다.
해당 State로 돌아가서 입력핀을 드래그 하던가 아니면 간편하게 우클릭을 하고 Use cached Pose '방금 이름 지은 캐시'를 사용하면 된다.
이제 지상에 있을때 동작은 완성이 되었다. 다음은 공중에 있을 때 애니메이션을 적용해보려고 한다.
에일리어스를 이용해서 만들 계획인데 이것을 이용하면 여러 상태에서 다른 상태로 넘어갈 수가 있다.
다음과 같이 만들고 디테일 패널을 살펴보자.
State Alias에 체크박스가 있는 것을 볼 수 있다.
체크박스를 체크하면 해당 스테이트에서 에일리어스와 연결된 스테이트로 넘어갈 수 있다는 것을 의미한다. 지금은 그라운드 스테이트 하나만 있지만 이후 스테이트가 더 많아지면 그 중에서 원하는 스테이트만 체크해서 애니메이션이 재생되게 할 수 있다.
먼저 OnGround 항목을 체크하자.
이제 먼저 조건을 적용해주려고 한다. 에일리어스에서 Jump로 가는 조건을 설정해보자.
다시 말하면 에일리어스에서 점프로 간다는 것은 onGround에서 Jump로 간다는 것과 같은 뜻이다.
그런데 이렇게 하려니 문제가 생겼다. C++에서 떨어지고 있는지만 확인했지 점프를 했는지는 확인을 하지 않았다. 다시 C++을 열고 점프중인지 여부도 확인하자.
// Header
UPROPERTY(BlueprintReadOnly, Category = "Movement")
FVector Velocity;
애니메이션인스턴스 헤더 파일에 백터를 저장할 변수를 만든다. 그리고 cpp 파일에 해당 변수의 값을 저장하자.
캐릭터의 Velocity를 구하려면 캐릭터 클래스의 함수를 이용해야 한다. 지상속도와 추락여부를 구하는 함수 내에 Velocity를 구하는 구문도 작성해보자.
void UKnightAnimInstance::NativeUpdateAnimation(float DeltaTime)
{
Super::NativeUpdateAnimation(DeltaTime);
if (KnightCharacterMovement && KnightCharacter)
{
GroundSpeed = UKismetMathLibrary::VSizeXY(KnightCharacterMovement->Velocity);
Velocity = KnightCharacter->GetVelocity();
IsFalling = KnightCharacterMovement->IsFalling();
}
}
캐릭터 포인터를 사용할 것이기 때문에 if 조건문에 캐릭터 포인터가 설정되있는지도 다시 확인해보자. Velocity를 얻는 것 자체는 간단하다.
GetVelocity() 함수를 사용하면 간편하게 구할 수 있다.
이제 캐릭터의 속도를 구했으니 다시 컴파일 하고 에디터를 켜보자.
애니메이션 그래프를 열고 메인 스테이트에 들어와 ToFalling과 Jump로 가는 부분의 조건을 주도록 하자.
isfalling 변수와 velocty 변수를 가져온다. velocity는 벡터값 자체가 필요한게 아니라 Z축으로 이동중인지의 여부만 필요하기 때문에 Split을 해서 Z값만 사용할 것이다.
Z축 크기가 100을 넘는지와 떨어지고 있는지 여부 모두 조건을 충족하면 Jump 조건을 만족한 것이다. 마지막으로 저기 연결되어있지 않은 핀을 연결하면 된다.
To falling에서 Is falling으로 가는 부분은 간단하다. 그냥 떨어지고 있는지 아닌지만 확인하면 되기 때문이다.
이렇게만 설정하면 된다.
그리고 이제 우선순위를 주자. 당연히 점프 부분이 떨어지는 부분보다 우선순위가 높을 것이다. 디테일 패널에서 우선순위를 바꿔주면 된다.
디테일 패널에서 Order를 바꾸면 되는데 To falling에서 Jump로 가는 부분을 1로 To Falling에서 Is Falling으로 가는 부분을 2로 지정하면 된다.
마지막으로 설정할 부분이 또 있는데 Jump 애니메이션이 끝나야 IsFalling으로 가야하기 때문에 디테일 패널에서 Automatic Rule Based on Sequence Player in State 이 부분에 체크를 해주어야 한다.
이제 점프모션에서 다시 지상모션으로 전환해보자.
에일리어스를 만들고 다음과 같이 체크를 한다.
ToLand → Land의 전환 조건은 Is falling이 아니면이다.
이제 Land에서 OnGround로 넘어가면 되는데 그 전에 Land부분의 애니메이션을 확인해보자.
Land 애니메이션을 바로 넣는 것이 아니라 위와 같이 설정해야 하는데 위와 같이 설정하면 지상 모션과 Land 모션의 자연스러운 변화를 줄 수 있다.
하지만 그 이유 보다 더 중요한건 3인칭 게임에서 가져온 착지 애니메이션을 그대로 사용하면 캐릭터가 사라졌다 새로 생긴다. 그렇기 때문에 위와 같은 설정이 필요하다.
이제 Land에서 Locomotion으로 돌아가보자
그냥 간편하게 애니메이션이 끝나면 이후 Locomotion 애니메이션이 재생되게 하면 된다. 다만 이렇게 조건을 하나만 주면 Land 애니메이션이 끝나기 전에 움직여도 그대로 Land 애니메이션이 재생되서 어색한 것을 알 수 있다. 그렇기 때문에 조건을 하나 더 주어 움직임이 있을 경우 바로 Locomotion으로 넘어가게 정해주어야 한다.
이렇게 한번 더 드래그를 하면 조건을 추가해줄 수 있다.
이제 위와 같이 조건을 설정하자. 첫번째 조건은 Land애니메이션의 재생시간을 가져와 일정 시간(위에서는 0.2초)이 넘었는지를 확인하는 것이다.
두번째 조건은 그라운드 스피드가 있는지, 즉 캐릭터가 움직이고 있는지 확인하는 것이다. 최소 재생시간을 넘기고 캐릭터가 움직이면 바로 Locomotion의 애니메이션을 호출한다.
이렇게 함으로써 움직이고 있는데도 착지 모션이 나오는 것을 방지할 수 있다.
이제 점프까지 완성했다. 이 다음에는 3인칭 게임 프로젝트 처럼 걷기와 달리기를 구분해서 애니메이션을 적용하는 것을 하도록 하겠다.
'게임프로그래밍 > 실습1' 카테고리의 다른 글
[언리얼 실습] 7. Overlab Event 생성 (1) | 2024.10.11 |
---|---|
[언리얼 실습] 6. Blend Space 1D를 이용한 걷기와 달리기 애니메이션 구분 (0) | 2024.10.11 |
[언리얼 실습] 4. 점프 애니메이션 가져오기 (1) | 2024.10.10 |
[언리얼 실습] 3. 캐릭터 애니메이션 적용하기 (2) | 2024.10.10 |
[언리얼 실습] 2. Mixamo에서 다운로드 받은 애니메이션 임포트 하기 (0) | 2024.10.10 |