[Unreal]#1_Pawn, Character, Character Movement
Unreal 개발 중 "Character Movement"에 대해 알아보겠습니다.
"Simple Shooter Game"의 Character Class 개발 과정 중 일부입니다.
C++의 Character 클래스
"A Character is a Pawn which has some basic bipedal movement functionality by default"
Unreal에서 제공하는 "Character" 클래스는 "Pawn"클래스의 하위 클래스입니다.
"Character" 클래스는 "Pawn"클래스로부터 확장되어 기본적으로 "Character Movement Component", "Capsule Component", 그리고 "Mesh Component"를 Default로 갖습니다.
기본적으로 제공되는 "Component"들을 보면 알 수 있듯이 "Character" 클래스는 월드 내에서 걷고, 점프하고, 그리고 수영하는 등의 기본적인 동작들을 수행하는 Pawn을 디자인하기 위함입니다!
Editor Setting
1. 새로운 C++ 생성
2. Character 선택
코드
// ATestCharacter.h 파일
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "TestCharacter.generated.h"
UCLASS()
class SIMPLESHOOTER_API ATestCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
ATestCharacter();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
};
위 코드는 헤더 파일의 코드입니다.
가장 먼저, "ACharacter" 클래스를 상속하며, "ACharacter" 클래스는 "APawn" 클래스를 상속하죠!
쓸데없는 생각이지만 왜 클래스 명의 앞에 항상 'A'가 붙는지 아직도 이해가...
그리고 "BeginPlay()", "Tick()", 그리고 "SetupPlayerInputComponent()" 멤버 메서드가 디폴트로 제공됩니다. 각각 간단한 설명이 주석처리되어있습니다!
이번 포스팅에서 우리는 "SetupPlayerInputComponent()" 가상 멤버 메서드에 집중해보겠습니다!
APawn::SetupPlayerInputComponent()
"Allows a Pawn to set up custom input bindings. Called upon possession by a PlayerController, using the InputComponent created by CreatePlayerInputComponent()"
-> "APawn" 클래스가 제공하는 "SetupPlayerInputComponent()" 메서드는 Pawn의 커스텀 입력 바인딩을 세팅할 수 있도록 합니다.
먼저, "입력 바인딩"이란 Pawn을 소유하고 있는 "PlayerController"의 특정 키 입력과 Pawn이 수행할 특정 동작을 바인딩하는 것입니다.
"입력 바인딩"을 통해 우리가 구현할 "Character" 클래스의 "Movement"를 순차적으로 구현해보겠습니다.
Character Movement
1. 프로젝트 세팅 -> 입력
2. Action Mapping + Axis Mapping 추가 및 Scale 설정
첫 번째로, Editior의 프로젝트 세팅 창을 열어 "입력" 카테고리에서 우리는 "Action Mapping"과 "Axis Mapping"을 설정합니다.
이때, "Action Mapping"은 소유할 Pawn의 행동과 관련된 동작들을 설정하기 위함이고,
"Axis Mapping"은 말 그대로 "Axis"는 Pawn의 이동 방향을 설정하기 위함입니다.
1. MoveForward() 멤버 메서드 선언
// ATestCharacter.h 헤더 파일
class ATestCharacter : public ACharacter
{
//...
private:
void MoveForward(float AxisValue);
}
그리고, 우리가 구현할 "Character" 클래스 내부에 "MoveForward(float AxisValue)"를 선언합니다.
"MoveForward(float AxisValue)" 메서드는 Pawn의 전진 이동을 구현하기 위한 메서드가 되겠죠!
2. SetupPlayerInputComponent() 메서드 정의, BindAxis를 통한 입력 바인딩
// APawn::SetupPlayerInputComponent( UInputComponent* PlayerInputComponent ) 정의부
// Called to bind functionality to input
void ATestCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
// BindAxis : Binds a delegate function on Axis defined in the project settings.
PlayerInputComponent->BindAxis(TEXT("MoveForward"), this, &ATestCharacter::MoveForward);
}
다음으로, "SetupPlayerInputComponent()" 메서드의 정의부에서 "MoveForward()"메서드를 앞서 프로젝트 세팅에서 설정한 Pawn의 전진 이동 (MoveForward) Axis Mapping과 명시적으로 바인딩해줍니다!
"SetupPlayerInputComponent()" 메서드의 매개 변수 "PlayerInputComponent"는 Pawn을 소유하고 있는 Player Controller의 키 입력을 의미하며, 이를 통해 "MoveForward()" 메서드를 대리자 함수(Delegate Funciton)로 "BindAxis()"를 호출합니다.
이때, "BindAxis()"는 앞서 프로젝트 세팅에서 설정한 "AxisMapping"중 "MoveForwrad" 동작과 우리가 별도로 C++ 클래스 내부에 선언한 "MoveForward()" 멤버 메서드를 "Binding" 해주는 역할을 수행합니다.
* 주의: Out-Parameter 사용 혹은 Delegate Funciton(대리자 함수)은 추후에 설명하겠습니다.
3. MoveForward() 멤버 메서드 정의
// MoveForward(float AxisValue) 정의부
void ATestCharacter::MoveForward(float AxisValue)
{
AddMovementInput(GetActorForwardVector() * AxisValue);
}
다음으로, Pawn의 전진 이동을 정의하는 "MoveForward()" 멤버 메서드의 정의부를 살펴보겠습니다.
"SetupPlayerInputComponent()" 메서드 내부에서 "대리자 함수"로 호출되는 "MoveForward()"메서드는 앞서 Editor에서 설정한 Axis Mapping 중 "MoveForward"에 해당하는 Scale Value(AxisValue)를 매개 변수로 받습니다.
여기서, Scale Value는 Player Controller가 'W'를 입력했을 때 "+1.0" 혹은 'S'를 입력 했을 때 '-1.0'이 되겠죠?
4. APawn::AddMovementInput() 메서드
// Pawn.cpp에 정의된 AddMovemntInput() 메서드
void APawn::AddMovementInput(FVector WorldDirection, float ScaleValue, bool bForce /*=false*/)
{
UPawnMovementComponent* MovementComponent = GetMovementComponent();
if (MovementComponent)
{
MovementComponent->AddInputVector(WorldDirection * ScaleValue, bForce);
}
else
{
Internal_AddMovementInput(WorldDirection * ScaleValue, bForce);
}
}
Pawn의 이동 동작을 수행하기 위해 우리는 "APawn::AddMovementInput()" 메서드를 활용합니다!
Axis Mapping을 활용한 Pawn의 앞, 뒤, 그리고 횡 이동은 "APawn::AddMovementInput()"에 Pawn을 이동시킬 "World" 기준의 방향벡터를 인자로 넘김으로써 구현할 수 있습니다.
그렇다면, "APawn::AddMovementInput()" 메서드는 실제로 무엇을 수행할까요?
먼저, "Character" 클래스를 상속받아 생성된 Blueprint 클래스를 Editor애 서 먼저 살펴보겠습니다!
위 그림은 Default로 생성된 컴포넌트의 목록을 보여줍니다.
왜 뜬금없이 이 그림을 보여줄까요?
"APawn::AddMovementInput()" 메서드의 정의를 위에서 제시한 "Pawn.cpp" 코드에서 다시 한번 살펴보죠!
우리가 이동 동작을 구현할 "Character"의 "MovementComponent"를 "GetMovementComponent()"를 통해 얻어오고 있습니다.
그리고, 이 컴포넌트에 인자로 받은 "방향벡터"를 InputVector로 추가해주는 모습을 쉽게 발견할 수 있습니다!
정리하자면, Character 생성 시 기본적으로 제공되는 컴포넌트 목록 중 "MovementComponent"에 우리가 키 입력을 통해 Pawn을 이동시킬 방향벡터를 "AddMovementInput()"을 통해 전달함으로써 최종적으로 Character의 이동 동작 수행을 입력 바인딩을 통해 구현하는 것이죠!
컨트롤러의 움직임, 즉 Pawn의 회전 또한 위와 마찬가지로 "Pawn::AddControllerPitchInput(X축 기준)"과 "Pawn::AddControllerYawInput(Z축 기준)"를 활용합니다.
5. Pawn::AddControllerPitchInput
// SetupPlayerInput( UInputComponent* PlayerInputComponent ) 메서드 구현부
{
PlayerInputComponent->BindAxis(TEXT("LookUp"), this, &AShooterCharacter::LookUp);
}
// AShooterCharacter::LookUp(float AxisValue) 메서드 구현부
{
AddControllerPitchInput(AxisValue);
}
Pawn의 회전도 이동 동작 구현과 같습니다.
우리가 별도로 선언한 "LookUp()" 메서드를 대리자 함수로 PlayerInputComponent와 바인딩합니다.
이때, "LookUp()" 메서드 내부에 "AddControllerPitchInput()"메서드의 인자로 AxisValue를 넘김으로서, Pawn의 X축 회전을 구현합니다.
더불어, "LookSide()"는 Z축 회전으로 "AddControllerYawInput()"이 되겠죠???
'게임개발 > Unreal C++' 카테고리의 다른 글
[Unreal]#6_Gun Actor Setting (0) | 2022.08.11 |
---|---|
[Unreal]#5_Character의 이동 속도와 각도 구하기, Animation Blueprint (0) | 2022.08.10 |
[Unreal]#4_Animation Blueprint, Gameplay와 Animation 연결하기 (0) | 2022.08.08 |
[Unreal]#3_Character Animation, Animation Blueprint, Animation Blend Space (0) | 2022.08.07 |
[Unreal]#2_Camera Setting, 3인칭 카메라 세팅 (0) | 2022.08.06 |