SpartaCharacter.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "SpartaCharacter.generated.h"
class USpringArmComponent;
class UCameraComponent;
struct FInputActionValue;
UCLASS()
class CH3CPP_API ASpartaCharacter : public ACharacter
{
GENERATED_BODY()
public:
ASpartaCharacter();
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera")
USpringArmComponent* SpringArmComp;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera")
UCameraComponent* CameraComp;
protected:
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
UFUNCTION()
void Move(const FInputActionValue& value);
UFUNCTION()
void StartJump(const FInputActionValue& value);
UFUNCTION()
void StopJump(const FInputActionValue& value);
UFUNCTION()
void Look(const FInputActionValue& value);
UFUNCTION()
void StartSprint(const FInputActionValue& value);
UFUNCTION()
void StopSprint(const FInputActionValue& value);
};
FInputActionValue는 Enhanced Input System에서 사용되는 구조체로, 입력 데이터를 캡슐화한 객체다.
- 플레이어의 입력(키보드, 마우스, 게임패드 등)에서 얻은 값을 처리하고, 이를 다양한 타입으로 변환할 수 있다.
- 예를 들어,
IA_Move는 방향 입력을 반환할 때 FVector2D를 사용하고, IA_Jump는 bool을 사용한다.
| 데이터 타입 | 설명 | 예시 |
|---|
bool | 단순 ON/OFF 동작 | 점프, 스프린트 등 |
float | 1차원 축 값 | 가속/감속, 조이스틱 트리거 |
FVector2D | 2D 벡터 값 (X, Y 축) | 캐릭터 이동, 마우스 이동 |
FVector3D | 3D 벡터 값 (X, Y, Z 축) | 카메라 이동, 3D 조이스틱 |
(2) 입력 이벤트의 분리하는 이유
- 입력 이벤트를 나누면 키를 누를 때와 뗄 때 발생하는 다른 동작을 독립적으로 제어할 수 있다.
- 예시:
- 키를 길게 눌렀을 때 높은 점프(Charged Jump)
- 키를 떼는 순간 특수 애니메이션(착지 애니메이션)을 재생
SpartaCharacter.cpp
void ASpartaCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if (UEnhancedInputComponent* EnhancedInput = Cast<UEnhancedInputComponent>(PlayerInputComponent))
{
if (ASpartaPlayerController* PlayerController = Cast<ASpartaPlayerController>(GetController()))
{
if (PlayerController->MoveAction)
{
EnhancedInput->BindAction(
PlayerController->MoveAction,
ETriggerEvent::Triggered,
this,
&ASpartaCharacter::Move
);
}
if (PlayerController->JumpAction)
{
EnhancedInput->BindAction(
PlayerController->JumpAction,
ETriggerEvent::Triggered,
this,
&ASpartaCharacter::StartJump
);
EnhancedInput->BindAction(
PlayerController->JumpAction,
ETriggerEvent::Completed,
this,
&ASpartaCharacter::StopJump
);
}
if (PlayerController->LookAction)
{
EnhancedInput->BindAction(
PlayerController->LookAction,
ETriggerEvent::Triggered,
this,
&ASpartaCharacter::Look
);
}
if (PlayerController->SprintAction)
{
EnhancedInput->BindAction(
PlayerController->SprintAction,
ETriggerEvent::Triggered,
this,
&ASpartaCharacter::StartSprint
);
EnhancedInput->BindAction(
PlayerController->SprintAction,
ETriggerEvent::Completed,
this,
&ASpartaCharacter::StopSprint
);
}
}
}
}
void ASpartaCharacter::Move(const FInputActionValue& value)
{
}
void ASpartaCharacter::StartJump(const FInputActionValue& value)
{
}
void ASpartaCharacter::StopJump(const FInputActionValue& value)
{
}
void ASpartaCharacter::Look(const FInputActionValue& value)
{
}
void ASpartaCharacter::StartSprint(const FInputActionValue& value)
{
}
void ASpartaCharacter::StopSprint(const FInputActionValue& value)
{
}
if (UEnhancedInputComponent* EnhancedInput = Cast<UEnhancedInputComponent>(PlayerInputComponent))
PlayerInputComponent를 UEnhancedInputComponent로 변환한다.
- 왜 필요한가?
- Enhanced Input System은 기본
UInputComponent와 달리 UEnhancedInputComponent라는 확장된 버전을 사용한다.
- 만약
PlayerInputComponent가 UEnhancedInputComponent 타입이 아니라면, Enhanced Input 기능을 사용할 수 없다.
- 따라서
Cast를 통해 변환을 시도하고, 성공하면 Enhanced Input 기능을 안전하게 사용할 수 있게 된다.
(2) 현재 소유 중인 Controller를 ASpartaPlayerController 타입으로 캐스팅
if (ASpartaPlayerController* PlayerController = Cast<ASpartaPlayerController>(GetController()))
GetController()가 반환한 컨트롤러를 ASpartaPlayerController 타입으로 변환한다.
GetController()
GetController()는 캐릭터(또는 폰)를 제어하는 컨트롤러 객체를 반환한다.
- 왜 필요한가?
GetController()가 반환하는 기본 타입은 AController이다.
- 그러나 우리가 정의한
ASpartaPlayerController는 AController를 상속받아 확장된 클래스다.
ASpartaPlayerController에 정의된 추가적인 멤버 변수나 함수(예: MoveAction, JumpAction 등)를 사용하려면 AController 타입에서 ASpartaPlayerController 타입으로 변환해야 한다.
(3) 입력 액션 바인딩
if (PlayerController->JumpAction)
{
EnhancedInput->BindAction(
PlayerController->JumpAction,
ETriggerEvent::Triggered,
this,
&ASpartaCharacter::StartJump
);
EnhancedInput->BindAction(
PlayerController->JumpAction,
ETriggerEvent::Completed,
this,
&ASpartaCharacter::StopJump
);
}
- EnhancedInput->BindAction
BindAction: 특정 입력 액션을 지정한 함수와 연결(바인딩)한다.
- 입력 액션이 발생하면, 지정한 함수가 호출된다.
- 매개변수:
PlayerController->JumpAction : 바인딩할 Input Action(점프 동작)
ETriggerEvent::Triggered : 입력 이벤트가 발생하는 시점(키를 누르고 있는 동안)
this : 바인딩할 함수를 소유하는 객체(여기서는 ASpartaCharacter)
&ASpartaCharacter::StartJump: 입력 이벤트가 발생했을 때 호출할 함수