Pawn은 플레이어나 AI가 제어할 수 있는 모든 액터의 베이스를 의미한다.
CapsuleComponent
추후에 충돌 관련을 구현하기 위해 CapsuleComponent가 필요함.
우선 헤더파일에 CapsuleComponent를 선언해준다.... // 전방선언 class UCapsuleComponent; ... private: // CapsuleComponent UPROPERTY(VisibleAnywhere) UCapsuleComponent* Capsule; ...
이어서 cpp파일에 관련 코드를 작성한다.
// pawn명 = Bird ABird::ABird() { ... Capsule = CreateDefaultSubobject<CapsuleComponent>(TEXT("Capsule")); RootComponent = Capsule; ... }
CapsuleComponent 설정 관련된 코드
// CapsuleComponent의 높이(half) Capsule->SetCapsuleHalfHeight(20.f); // CapsuleComponent의 반지름 Capsule->SetCapsuleHalfRadius(15.f);
SkeletalMeshComponent
SkeletalMeshComponent는 StaticMeshComponent와는 다르게 뼈대가 있어 동적인 애니메이션 지원이 가능한 Component이다.
StaticMeshComponent : 문, 나무, 사물등과 같은 정적인 것들
SkeletalMeshComponent : 애니메이션같은 동적인 것들
우선 헤더파일에 USkeletalMeshComponent타입 변수를 선언해준다.... // 전방선언 class USkeletalMeshComponent; ... private: ... // SkeletalMeshComponent UPROPERTY(VisibleAnywhere) USkeletalMeshComponent* BirdMesh; ... ....
이어서 cpp파일에 관련 코드를 추가해준다.
... #include "Components/SkeletalMeshComponent.h" ... // pawn명 = Bird ABird::ABird() { ... BirdMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("BirdMesh")); BirdMesh->SetupAttachment(GetRootComponent()); ... }
마지막으로 BP_Bird파일에 들어가서 좌측의 Components의 BirdMesh를 클릭후
우측의 Details 패널에서 SkeletalMesh를 추가해준다.
마지막으로 전방방향이 x축이 되도록 SkeletalMesh가 빨간 화살표를 바라보도록 회전시켜주고, CapsuleComponent안에 들어가도록 높낮이를 잘 조정해준다.
해당 pawn 에셋에서 애니메이션을 지원해준다면 Blueprint에서 확인해보는 것이 가능하다.
BirdMesh를 클릭하고, 우측 Details 패널에서 Animation탭에 보면 Animation모드가 있다.
Use Animation Asset으로 변경하고 보고싶은 에셋을 넣으면 에디터에서 해당 애니메이션을 볼 수 있다.
Binding(이동)
캐릭터의 시야를 조종하거나 움직이기 위해서 Binding이 필요하다.
Binding을 간단하게 설명하자면, 에디터에서 Input관련 키를 몇가지 설정해 두었을 때 class상에 있는 함수가 발동되도록 하는 것을 의미한다.
- 우선 pawn을 움직이게 하기위해 player가 pawn을 소유하도록 해야 한다.
Blueprint에서 pawn 소유방법
우측 Details 패널에서 Auto Posses Player에 Player0을 할당해준다.
cpp에서 pawn 소유방법
pawn class에서 아래의 코드를 추가해준다.
... // pawn명 = Bird ABird::ABird() { ... AutoPossessPlayer = EAutoReceiveInput::Player0; ... } ...
- 에디터의 Project Settings에서 Input탭에 있는 Axis Mapping을 설정해주어야 한다(ActionMapping은 입력값을 받았을 경우에 대한 바인딩이므로 지금 당장은 필요없음).
그리고 헤더파일에 이동을 구현할 함수를 선언한다.... protected: // 전후 이동 함수 void MoveForward(float Value); //좌우 이동 함수 void MoveRight(float Value); ...
이어서 cpp 파일에 관련된 코드를 작성한다.
... // pawn명 = Bird // 전후 이동 함수 void ABird::MoveForward(float Value) { if((Controller != nullptr) && (Value != 0.f)) { FVector ForwardVector = GetActorForwardVector(); AddMovementInput(ForwardVector, Value); } } // 좌우 이동 함수 void ABird::MoveRight(float Value) { if((Controller != nullptr) && (Value != 0.f)) { FVector RightVector = GetActorRightVector(); AddMovementInput(RightVector, Value); } } ... // Binding 구현 // PlayerInputComponent->BindAxis(FName AxisName, ABird* Object, void(ABird::*Func)(float)) void ABird::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { ... // BindAxis PlayerInputComponent->BindAxis(FName("MoveForward"), this, &ABird::MoveForward); PlyerInputComonent->BindAxis(FName("MoveRight"), this, &ABird::MoveRight); ... }
- FName AxisName
에디터에서 추가한 AxisName- ABird* Object
Binding 적용 대상, 해당 class 자기 자신에게 적용이므로 this사용- void(ABird::*Func)(float)
Input 발생시 실행시킬 함수
- Blueprint에서 FloatingPawnMovementComponent를 추가해준다.
Binding(회전)
이동과 마찬가지로 에디터의 Project Settings에서 Axis Mapping을 추가해줘야 한다.
Blueprint에서 구현법
- 노드 배치
Turn 이라는 Axis Mapping Input이 발생하면 AddControllerYawInput 노드를 통해 Value값만큼 yaw축 기준으로 회전시킨다.- 좌측의 Components에서 BP_PAWN_NAME(Self)을 선택하고 우측의 Details 패널에서 UseControllerRotaionYaw를 활성화시킨다.
UseControllerRotationYaw는 Yaw축 기준 회전을 사용할 수 있도록 한다.
LookUp도 똑같이 구현하되, pitch 기준으로 적용해야 한다(AddControllerPitchInput, UseControllerRotationPitch).cpp에서 구현법
먼저 헤더파일에 관련 함수를 선언한다
... protected: // yaw 기준 좌우 회전 void Turn(float Value); // pitch 기준 상하 회전 void LookUp(float Value); ...
이어서 cpp파일에 관련 코드를 작성한다.
... // yaw 기준 좌우 회전 함수 void ABird::Turn(float Value) { if((Controller != nullptr) && (Value != 0.f)) { AddControllerYawInput(Value); } } // pitch 기준 상하 회전 함수 void ABird::LookUp(float Value) { if((Controller != nullptr) && (Value != 0.f)) { AddControllerPitchInput(Value); } } ... void ABird::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { ... PlayerInputComponent->BindAxis(FName("Turn"), this, &ABird::Turn); PlayerInputComponent->BindAxis(FName("LookUp"), this, &ABird::LookUp); ... }
Camera, SpringArm
camera와 springarm을 부착하면 셀카봉처럼 캐릭터를 볼 수 있다.
Bleueprint에서 구현방법
좌측의 Components탭에서 SpringArm과 Camera를 추가해 준다.
이때 Camera는 SpringArm에 부착된 상태여야 한다.
SpringArm을 사용할 경우 지형과 Camera가 충돌 발생시에 대한 처리가 가능해진다(카메라가 지형을 뚫고 들어가는 것을 방지).
우측의 Details 패널에서 SpringArm의 각도와 길이를 적절히 조절하면 Pawn을 볼 수 있게 된다.
cpp에서 구현방법
우선 헤더파일에 SpringArmComponent와 CameraComponent를 선언해준다.
... // 전방선언 class USpringArmComponent; class UCameraComponent; ... private: // SpringArmComponent UPROPERTY(VisibleAnywhere) USpringArmComponent* CameraLine; // CameraComonent UPROPERTY(VisibleAnywhere) UCameraComponent* Camera; ...
이어서 cpp파일에 관련된 코드를 작성한다.
... #include "GameFramework/SpringArmComponent.h" #include "Camera/CameraComponent.h" ... // pawn명 = Bird ABird::ABird() { ... // SpringArmCompent 관련 코드 CameraLine = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraLine")); CameraLine->SetupAttachment(GetRootComponent()); CameraLine->TargetArmLength = 300.f // CameraComponent 관련 코드 Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera")); Camera->SetupAttachment(CameraLine); ... }
- TargetArmLength
SpringArm의 길이 설정 가능
CapsuleComponent에 Collision 부여
Pawn의 blueprint에 들어가 CapsuleComponent를 선택하고, 우측의 Details 패널에 Collision을 검색하면 Collision Presets라는 탭이 있다.
OverlapAllDynamic은 모든 것들과 Overlap, 즉 겹치도록 설정하는 것인데 이를 BlockAll로 변경하면 모든 것들에 충돌이 발생하여 막히게 된다.