인간형 캐릭터를 효과적으로 제작하기 위해
언리얼 엔진이 제공하는 캐릭터 모델을 학습하고,
이를 기반으로 움직이는 캐릭터를 제작한다.
카메라를 자유자재로 설정하기 위해 컨트롤 회전에 대한 개념을 익힌다.
<1>. 캐릭터 모델
캐릭터 에셋을 사용해 인간형 '폰'을 만들 수도 있지만, '캐릭터' 모델을 사용해서 만들 수도 있다.
'ABCharacter" 클래스 생성
→ACharacter라는 클래스 상속받고 있음
→ACharacter는 APawn 클래스를 상속받고 있음
→둘 다 동일하게 Capsule 컴포넌트, SkeletalMesh 컴포넌트, CharacterMovement 컴포넌트를 사용함
ACharacter 클래스는 GetCapsuleComponent, GetMesh, GetCharacterMovement 함수를 제공한다. 이를 기반으로 전에 제작한 폰과 동일한 액터를 제작한다 → ABCharacter를 DefaultPawn으로 설정한다.
<2>. 컨트롤 회전의 활용
플레이어 컨트롤러가 제공하는 속성인 '컨트롤 회전'은 곧 플레이어의 의지를 나타낸다.
→ 입력 설정에서 마우스를 이용해 회전하는 Turn(Z 축 회전), LookUp(Y축 회전) 함수를 사용한다.
→ 캐릭터 모델은 기본으로 '컨트롤 회전의 Yaw 회전' 값과 '폰의 Yaw 회전'이 서로 연동돼 있다.
→ 마우스를 돌렸을 때, 좌우 회전은 하지만 상하회전은 하지 않는다.
//ABCharacter.cpp
void AABCharacter::LookUp(float NewAxisValue)
{
AddControllerPitchInput(NewAxisValue);
}
void AABCharacter::Turn(float NewAxisValue)
{
AddControllerYawInput(NewAxisValue);
}
<3>. 삼인칭 컨트롤 구현(GTA 방식) - 흰색 마네킹과 동일한 방식
흰색 마네킹은 다음과 같은 성질을 가지고 있다.
- 캐릭터의 이동 : 보는 시점으로 상하좌우 이동 / 카메라는 회전 X
- 캐릭터의 회전 : 이동하는 방향으로 마네킹이 회전
- 카메라 지지대 길이 : 450cm
- 카메라 회전 : 마우스 이동에 따라 카메라 지지대가 회전
- 카메라 줌 : 장애물 있으면 캐릭터 보이도록 장애물 앞으로 줌인
//카메라 설정
void AABCharacter::SetControlMode(int32 ControlMode)
{
if (ControlMode == 0)
{
SpringArm->TargetArmLength = 450.0f;
SpringArm->SetRelativeRotation(FRotator::ZeroRotator);
SpringArm->bUsePawnControlRotation = true;
SpringArm->bInheritPitch = true;
SpringArm->bInheritRoll = true;
SpringArm->bInheritYaw = true;
SpringArm->bDoCollisionTest = true;
bUseControllerRotationYaw = false;
}
}
→ 카메라의 방향과 상관없이 시선 방향, 좌우 방향으로만 이동한다.
→우리는 카메라 방향을 중심으로 이동 방향을 변경해야 한다.
→이동 방향은 FVector이고, FVector를 얻기 위해 FRotator(컨트롤 회전) 데이터가 필요하다. ★
→ 컨트롤 회전 값으로부터 회전 행렬을 생성한 후, 원하는 방향 축을 대입해 캐릭터가 움직일 방향을 정한다. ★
※언리얼에서 "시선 방향은 X축" / "우측 방향은 Y축"을 의미한다. ★
void AABCharacter::UpDown(float NewAxisValue)
{
AddMovementInput(FRotationMatrix(GetControlRotation()).GetUnitAxis(EAxis::X), NewAxisValue);
}
void AABCharacter::LeftRight(float NewAxisValue)
{
AddMovementInput(FRotationMatrix(GetControlRotation()).GetUnitAxis(EAxis::Y), NewAxisValue);
}
→ 이동은 잘 하지만, X축만 보고 이동함.
→ 움직이는 방향으로 캐릭터를 자동으로 회전시켜 주는 캐릭터 무브먼트 컴포넌트의 'OrientRotationToMovement' 기능이 있음.
//ABCharacter.cpp
void AABCharacter::SetControlMode(int32 ControlMode)
{
if (ControlMode == 0)
{
...
GetCharacterMovement()->bOrientRotationToMovement = true;
GetCharacterMovement()->RotationRate = FRotator(0.0f, 720.0f, 0.0f);
}
}
<4>. 삼인칭 컨트롤 구현(디아블로 방식)
디아블로 방식은 다음과 같은 성질을 가지고 있다.
- 캐릭터의 이동 : 상하좌우 키를 조합해 이동할 방향을 결정
- 캐릭터의 회전 : 입력한 방향으로 회전
- 카메라 길이 : 800cm
- 카메라 회전 : 회전 없이 항상 고정으로 45도
- 카메라 줌 : 없음
//카메라 설정
void AABCharacter::SetControlMode(EControlMode NewControlMode)
{
switch(CurrentControlMode)
{
case EControlMode::DIABLO:
ArmLengthTo = 800.0f;
ArmRotationTo = FRotator(-45.0f, 0.0f, 0.0f);
SpringArm->bUsePawnControlRotation = false;
SpringArm->bInheritPitch = false;
SpringArm->bInheritRoll = false;
SpringArm->bInheritYaw = false;
SpringArm->bDoCollisionTest = false;
bUseControllerRotationYaw = false;
GetCharacterMovement()->bOrientRotationToMovement = false;
GetCharacterMovement()->bUseControllerDesiredRotation = true;
GetCharacterMovement()->RotationRate = FRotator(0.0f, 720.0f, 0.0f);
break;
}
...
}
※컨트롤 회전이 가리키는 방향으로 부드럽게 회전하기
bUseControllerRotationYaw = false;
GetCharacterMovement()->bOrientRotationToMovement = false;
GetCharacterMovement()->bUseControllerDesiredRotation = true;
GetCharacterMovement()->RotationRate = FRotator(0.0f, 720.0f, 0.0f);
※SpringArm의 길이와 회전 값 서서히 변경하기 : FMath 클래스의 'InterpTo' 사용
<5>. 컨트롤 설정 변경
두 가지 조작 방식이 서로 전환되도록, ViewChange라는 액션 매핑 하나를 추가해 준다.
→ 입력 설정(Shift+v)을 완료하면, 해당 키가 눌러질 때마다 SetControlMode함수에 다른 인자값이 들어가도록
→ 액션 매핑 입력 설정과 연동된 함수 : BindAction
→ 버튼이 눌렸는지(EInputEvent::IE_Pressed), 떼어졌는지(EInputEvent::IE_Released)
※카메라 길이가 부드럽게 전환되도록
→ FMath 클래스의 InterpTo 명령어 사용.
※4.27에서 달라진 부분은 SpringArm의 RelativeRotation이 private기 때문에 Get, Set 함수로 설정해줘야 함!!!
#p.203,204
SpringArm->RelativeRotation = FMath::RInterpTo(SpringArm->RelativeRotation, ArmRotationTo, DeltaTime, ArmRotationSpeed);
=>
SpringArm->SetRelativeRotation(FMath::RInterpTo(SpringArm->GetRelativeRotation(), ArmRotationTo, DeltaTime, ArmRotationSpeed));
'게임 개발 > 이득우의 언리얼 C++' 카테고리의 다른 글
[이득우의 언리얼 C++ 게임개발의 정석] #8. 애니메이션 시스템 활용 (0) | 2024.06.20 |
---|---|
[이득우의 언리얼 C++ 게임개발의 정석] #7. 애니메이션 시스템의 설계 (0) | 2024.06.17 |
[이득우의 언리얼 C++ 게임개발의 정석] #5. 폰의 제작과 조작 (0) | 2024.06.10 |
[이득우의 언리얼 C++ 게임개발의 정석] #4. 게임플레이 프레임워크 (0) | 2024.06.10 |
[이득우의 언리얼 C++ 게임개발의 정석] #3. 움직이는 액터의 제작 (1) | 2024.06.08 |