언리얼C++ 기초, 알고리즘 1문제
TryGetPawnOwner()는 AnimInstance를 소유하고 있는 Pawn을 가져오는 함수이다. 여기서 Try가 붙은 이유는 이름 그대로 "시도는 해보는데, 없을 수도 있다"라는 뜻이다. 그런데 왜 APawn에서 가져오는 걸까? 이건 AnimInstance가 일반적으로 Pawn 계열에 붙는 쪽에서 시작하는 게 더 넓은 범위이기 때문이다.
NativeInitializeAnimation() -> 초기 연결단계. AnimInstance가 시작될 때, 사용
결국 GetCharacterMovement()를 꺼내오는 이유는 속도/가속도/낙하 같은 이동 데이터를 애니메이션 판단에 쓰기 위해서 이다.
NativeUpdateAnimation은 AnimInstance전용 Tick 비슷한 함수이다. 하지만 목적은 이동/전투 로직 실행이 아니라 애니메이션 상태 갱신이다.
Velocity = OwnerCharacterMovement->Velocity;
GroundSpeed = UKismetMathLibrary::VSizeXY(Velocity);
float GroundAcceleration = UKismetMathLibrary::VSizeXY(OwnerCharacterMovement->GetCurrentAcceleration());
bool bIsAccelerationNearlyZero = FMath::IsNearlyZero(GroundAcceleration);
bShouldMove = (KINDA_SMALL_NUMBER < GroundSpeed) && (bIsAccelerationNearlyZero == false);
VSizeXY는 Z축을 빼고 X/Y 평면 속도만 구한다.
GetCurrnentAcceleration() -> 캐릭터가 지금 어느 방향으로 얼마나 가속하려는지 알려주는 벡터를 반환하는 함수이고, 애니메이션에선 실제로 움직이려고 입력 중인지를 판단할 때 자주 쓴다.
즉, bShouldMove는 가속도나 XY의 속도가 0일때 true가 되는것.
Animation State에서 각 State간 Rule의 Details -> Transition -> Automatic Rule Based on Sequence Player in State라는걸 체크하게 되면 해당 상태 안에서 재생 중인 시퀀스 플레이어 애니메이션이 끝나는 시점을 기준으로, Rule을 자동으로 잡아주는 옵션이다.
쉽게 말하면 이 State의 애니메이션이 거의 끝나면 자동으로 넘어가게 해주는 체크박스이다.
Priority Order는 전이 조건이 여러 개 동시에 참일 때, 어느 전이를 먼저 탈지 정하는 우선순위 이야기이다. Priority Order값이 더 높은 쪽이 아니라, 더 우선인 쪽을 먼저 탄다.
결국 다른 전이보다 이 전이를 나중에 선택되게 만든다는 뜻이다.
Delegate는 어떤 일이 일어났다는 사실을 다른 객체들에게 알려주는 중개인 역할을 한다고 생각하면 된다. 발행 - 구독 패턴 사이의 중개인으로써, 발행자는 이벤트가 일어났다고 알리고, 구독자는 미리 등록해 둔 콜백을 받는다. 이렇게 둘이 서로를 직접 몰라도 연결되는 결합도를 낮추는 의존성 분리를 하는게 Delegate
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPickUp, AUSPlayerCharacter*, InPickUpCharacter);
DECLARE_{델리게이트 유형}_DELEGATE_{바인드될 함수 명세}
델리게이트 유형으로는
DELEGATE -> 1 : 1
MULTICAST_DELEGATE -> 1 : N
DYNAMIC이 추가로 뒤에 붙을 수 있는데 DYNAMIC이 없으면 C++ 중심이고, 있으면 리플렉션/블루프린트 친화적으로 하겠다는 뜻이다. 또 뒤에 OneParam, TwoParam은 말 그대로 매개변수 개수/형태이다.
if (SpawnedPigeon->OnPigeonFlying.IsAlreadyBound(this, &ThisClass::HandlePigeonFlying) == false)
{
SpawnedPigeon->OnPigeonFlying.AddDynamic(this, &ThisClass::HandlePigeonFlying);
}
IsAlreadyBound -> "이 함수가 이미 이 델리게이트에 등록되어 있냐?" 확인하는 용도이다. 왜 필요하냐면 같은 함수를 두 번 등록하면 Broadcast()할 때 두 번 실행될 수 있기 때문이다.
AddDynamic(..) -> 델리게이트의 구독 목록에 추가하는것이다.
Broadcast()를 했을때 등록된 함수들이 전부 다 호출된다. 그래서 인자를 똑같이 맞춰야한다. 이건 델리게이트가 처음부터 호출 시그니처를 정해놓은 타입이기 때문이다.
결국, 아무 함수나 받는 게 아니라 정해진 형태의 함수만 등록 가능하기 때문에 인자를 맞춰줘야한다.