[C++] 스테이트 머신(Standing - Crouching) / 에임 오프셋 / Camera Lag Enable
스테이트 머신(Locomotion) 추가 및 설정 (Standing - Crouching)
ABP_Character 애니메이션 블루프린트 화면에서 AnimGraph에 스테이트 머신(Locomontion)을 추가했다.
* 기존의 BS_Standing / BS_Crouching 블렌드 스페이스는 지웠음.
이제 Locomotion 내부에 BS_Standing(Standing) / BS_Crouching(Crouching) 블렌드 스페이스를 추가해주고, 각각
Entry → Standing ↔ Crouching으로 트렌지션 룰을 연결해준다. Prone_Idle(LyingProne) 애니메이션도 추가했다.
Locomotion 스테이트 머신에서 추가한 Standing과 Crouching 블렌드 스페이스에 들어가서 디테일에 값을 다시 바인딩 해주어야한다.
이제 Standing에서 Crouching을 왔다갔다할 조건으로 쓸 bool 변수를 추가해주기 위해 GPCAnimInstance 클래스로 간다.
bool bIsCrouching 변수를 선언하고, UPROPERTY()를 통해 EditDefaultsOnly와 BlueprintReadOnly 권한을 주었다.
class GPC_CPP_12_API UGPCAnimInstance : public UAnimInstance
{
GENERATED_BODY()
protected:
.
.
.
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
bool bIsCrouching;
};
그리고 GPCAnimInstance.cpp에서 PawnMoveComponent 헤더파일을 포함시켜준다.
bIsCrouching 변수에 MovementComponent() 안에 있는 IsCrouching()값을 정의해준다.
#include "GameFramework/PawnMovementComponent.h"
void UGPCAnimInstance::NativeUpdateAnimation(float const DeltaSeconds)
{
if (auto const PawnOwner = TryGetPawnOwner())
{
.
.
.
bIsCrouching = PawnOwner->GetMovementComponent()->IsCrouching();
}
}
다시 Locomotion으로 돌아와, Standing → Crouching / Crouching → Standing 트렌지션 룰들을 정의해주었다.
GPCCharacter 클래스로 와서 액션매핑에 지정한 C키 BeginPoseB()가 호출된다면 Crouch();를 부른다.
한번 더 키입력한다면 UnCrouch();를 부르게 되는 토글형식으로 구현했다.
void AGPCCharacter::BeginPoseB()
{
if (bIsCrouched == false)
{
Crouch();
}
else
{
UnCrouch();
}
}
* 만약 토글형식이 싫다면 BeginPoseB()에 Crouch()만 부르고, EndPoseB()에서 UnCrouch()를 부르면 된다.
에임 오프셋(AimOffset) 만들기
시점이 위 아래로 바뀔 때마다 캐릭터의 방향이 그에 맞게 위 아래로 움직이도록 하기 위해 에임 오프셋을 사용했다.
AnimStarterPack 폴더에 AimOffset 폴더를 하나 만들어준다. 그리고 Aim_Space_Hip 애니메이션 시퀀스를 복사하여
폴더에 넣어준다.
Aim_Space_Hip 애니메이션을 보면, 10프레임씩 시점이 나뉘어 있는걸 볼 수 있다.
* 0 프레임 : 전방 / 10 프레임 : 위 / 20 프레임 : 아래
에임 오프셋에 필요한 애니메이션 만들기
Aim_Center_Hip
Aim_Space_Hip을 복사하여 하나 더 만들고 Aim_Center_Hip으로 명해준다.
그리고 전방을 보고있는 0프레임으로 고정 후, 우클릭 - 프레임 1에서 프레임 87까지 제거를 한다.
이러면 이제 전방만 보고있는 1프레임짜리 애니메이션이 남게된다.
Aim_Up_Hip
마찬가지로 Aim_Space_Hip 애니메이션 복사한 뒤, Aim_Up_Hip을 만들고 10프레임으로 고정한다.
그리고 10프레임을 제외한 앞과 뒤 프레임 모두 제거해주면 된다.
Aim_Down_Hip
Aim_Space_Hip 애니메이션을 Aim_Down_Hip으로 이름을 바꿔주고, 애니메이션을 20프레임으로 고정해준다.
마찬가지로 앞과 뒤의 프레임을 모두 제거해주면 된다.
Aim_Down / Up / Center_Ironsights
Aim_Space_Hip 애니메이션(지향사격자세)말고 Aim_Space_Ironsights 애니메이션(조준사격자세)도 위와 같이
Center / Up / Down 3가지 애니메이션으로 만들어주었다.
프로퍼티 매트릭스 사용하기
이제 각 애니메이션마다 Additive Settings을 통해 Base Animation 동작을 정해주어야 한다.
이 애니메이션들을 한번에 설정해주는 기능인 프로퍼티 매트릭스를 사용했다.
먼저 동일한 설정을 할 애니메이션들을 선택하고, 우클릭 - 애셋 액션 - 프로퍼티 매트릭스를 통한 대량 편집을 선택해준다.
이제 다음과 같이 보이는 표의 여러가지 탭이 보일텐데, 보기 쉽게 이름을 제외한 모든 탭을 지워준다.
* 우클릭 - 다음을 제외하고 모두 제거 클릭
그리고 AdditiveSettings에서 Additive Anim Type /
Base Pose Type / Base Pose Animation 3개만 토글을
활성화 해준다.
- Additive Anim Type : Mesh Space
- Base Pose Type : Selected animation frame
- Base Pose Animation : Idle_Rifle_Hip
Aim_Hip 애니메이션 3개 모두 같은 설정을 해주면 된다.
이는 Aim_Ironsights 애니메이션 3개 또한 같은 방식으로 세팅해주면 된다.
다만 Base Pose Animation만 Idle_Rifle_Ironsights로 바꿔서 설정해주면 된다.
에임 오프셋 만들기
우클릭 - 애니메이션 - 에임 오프셋 1D로 하나 생성해준다. 스켈레톤은 UE4_Mannequin을 선택해주고 AO_Hip / AO_Ironsights 두개를 만들어준다.
각각의 에임 오프셋에 들어가서 에셋 디테일의 가로 축을 설정해준다.
- Name : Pitch(Y축 회전)
- Min : -90.0
- Max : 90.0
- Number of Grid : 2
AO_Hip에는 좌측부터 Aim_Down_Hip / Aim_Center_Hip / Aim_Up_Hip을 넣어주었다.
마찬가지로, AO_Ironsights도 똑같이 설정해주고, Aim_Ironsights 애니메이션으로만 바꿔주면 된다.
Pitch(Y축 회전값) 받아오기
ABP_Character 애니메이션 블루프린트에서 Standing 블렌드 스페이스와 Crouching 블렌드 스페이스에
AO_Hip 에임 오프셋을 연결해준다.
이제 Pitch값을 받아오기 위해 GPCAnimInstance 클래스로 가서 Pitch 변수를 선언해준다.
float Pitch를 선언하고 UPROPERTY()를 통해 Min ~ Max의 값을 설정해준다.
class GPC_CPP_12_API UGPCAnimInstance : public UAnimInstance
{
GENERATED_BODY()
.
.
.
protected:
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Meta = (ClampMin = "-90", ClampMax = "90"))
float Pitch;
};
이어서 GPCAnimInstance.cpp로 와서 Pitch 변수에 값을 정의해준다.
GetBaseAimRotation()의 Pitch를 받아와서 Pitch 변수에 정의해주었다.
void UGPCAnimInstance::NativeUpdateAnimation(float const DeltaSeconds)
{
if (auto const PawnOwner = TryGetPawnOwner())
{
.
.
.
Pitch = PawnOwner->GetBaseAimRotation().Pitch;
}
}
빌드 후, 다시 애니메이션 블루프린트로 넘어와 AO_Hip의 디테일에서 Alpha는 1.0으로 고정해두고 핀으로 노출을 꺼준다.
* 여기서 Alpha는 불투명도를 뜻한다. 1.0은 완전 불투명함 ~ 0.0은 불투명하지 않음(투명하다)
그리고 X에 대해서 Pitch를 바인드해주고, 플레이해보면 잘 적용된 것을 확인할 수 있다.
SpringArm의 Camera Lag Enable
Stand와 Crouch 상태를 오갈때마다 카메라가 불연속적으로 뚝뚝 끊기는 느낌이 든다.
이는 SpringArm이 기본을 붙는 위치는 Root Component(Capsule)이다.
그런데 Crouch할 때마다 Capsule의 크기가 절반으로 줄어들게되고, 이에 따라 Capsule 중심이 변화하며 SpringArm도
영향을 받기 때문이다.
※ 여기서 Capsule Component는 피격 충돌이 아닌 지형 충돌을 검사하기 위한 용도로 사용하는 것이다.
Character Movement의 Crouched Half Hight값을 통해 Crouch 시 Capsule의 크기를 조절할 수 있다.(60.0)
이를 해결해주기 위해선 SpringArm의 Enable Camera Lag를 활성화 한다.
불연속적인 이동을 연속적으로 만들어주어 자연스럽게 바뀌게 된다.
디버그 랙 마커 드로를 켜보면 좀 더 쉽게 확인해볼 수 있다.
카메라 랙의 최대값을 지정하기 위해 Camera Lag Max Distance에 값을 제한해주었고, Camera Lag Speed를 조절하여
자연스러운 속도를 만들어줄 수 있다.
이를 블루프린트에서 말고 C++에서 Camera Lag를 활성화시켜줄 수 있다.
SpringArm의 bEnableCameraLag에 접근하여 true로 설정해주면 된다.
* 자세한 Lag의 속도 조정은 블루프린트에서 해주는 것이 편하다.
AGPCCharacter::AGPCCharacter()
{
.
.
.
SpringArm->bEnableCameraLag = true;
}
무기 생성을 위한 클래스 생성
무기로 총을 만들어주기 위해 먼저 새 클래스를 생성해주었다.
새 C++클래스 생성 - 부모클래스 Actor 선택 - GPCWeapon으로 만들어 주었다.