현재까지 게임모드를 만들고 게임모드로 캐릭터와 플레이어 컨트롤러를 관리했다.
플레이어 컨트롤러는 사용자의 입력과 캐릭터 사이를 연결해주고 IMC를 활성화 시켰다.
이제 어떤 키를 눌렀을 때 어떤 행동(함수)를 할것인지를 구현해야한다.
캐릭터에 액션 바인딩 추가하기
입력 액션을 처리할 함수를 선언한다.
인핸스드 인풋에서 입력 액션 값은 FInputActionValue로 전달된다.
// 캐릭터 헤더
struct FInputActionValue; // Enhanced Input에서 액션 값을 받을 때 사용하는 구조체
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);
매개변수를 const &로 받는 이유는 구조체의 경우 크기가 커서 그냥 값을 받을경우 복사되어 성능 저하 문제가 있다.
&(참조)로 원본을 가져오고 const로 값을 변경못하게 방어를 하는것이다.
// 캐릭터 소스
void AJinCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if (UEnhancedInputComponent* EnhancedInput = Cast<UEnhancedInputComponent>(PlayerInputComponent))
{
if (AJinPlayerController* PlayerController = Cast<AJinPlayerController>(GetController()))
{
if (PlayerController->Move)
{ // IA_Move 액션 키를 "누르고 있는 동안" Move 함수 호출
EnhancedInput->BindAction(PlayerController->Move, ETriggerEvent::Triggered, this, &AJinCharacter::Move);
}
if (PlayerController->Jump)
{ // IA_Jump 액션 키를 "누르고 있는 동안" StartJump 함수 호출
EnhancedInput->BindAction(PlayerController->Jump, ETriggerEvent::Triggered, this, &AJinCharacter::StartJump);
// IA_Jump 액션 키를 "뗀 순간" StopJump 함수 호출
EnhancedInput->BindAction(PlayerController->Jump, ETriggerEvent::Completed, this, &AJinCharacter::StopJump);
}
if (PlayerController->Look) //
{ // IA_Look 액션 마우스가 "움직이는 동안" Jump 함수 호출
EnhancedInput->BindAction(PlayerController->Look, ETriggerEvent::Triggered, this, &AJinCharacter::Look);
}
if (PlayerController->Sprint)
{ // IA_Sprint 액션 키를 "누르고 있는 동안" StartSprint 함수 호출
EnhancedInput->BindAction(PlayerController->Sprint, ETriggerEvent::Triggered, this, &AJinCharacter::StartSprint);
// IA_Sprint 액션 키를 "뗀 순간" StopSprint 함수 호출
EnhancedInput->BindAction(PlayerController->Sprint, ETriggerEvent::Completed, this, &AJinCharacter::StopSprint);
}
}
}
}
if (UEnhancedInputComponent* EnhancedInput = Cast<UEnhancedInputComponent>(PlayerInputComponent))
-> Enhanced InputComponent로 캐스팅
if (AJinPlayerController* PlayerController = Cast<AJinPlayerController>(GetController()))
-> IA를 가져오기 위해 현재 소유 중인 Controller를 AJinPlayerController로 캐스팅
// 캐릭터 소스
// BineAction 함수에서 인자로 넣은 함수들(실제로 행동 로직을 구현할 함수)
void AJinCharacter::Move(const FInputActionValue& value)
{
}
void AJinCharacter::StartJump(const FInputActionValue& value)
{
}
void AJinCharacter::StopJump(const FInputActionValue& value)
{
}
void AJinCharacter::Look(const FInputActionValue& value)
{
}
void AJinCharacter::StartSprint(const FInputActionValue& value)
{
}
void AJinCharacter::StopSprint(const FInputActionValue& value)
{
}
- FInputActionValue: Enhanced Input에서 액션 값 (축 이동값, 마우스 이동량 등)을 전달할 때 사용하는 구조체로, IA에서 설정한 Value Type입니다.
- UFUNCTION(): 입력 바인딩 함수는 언리얼 엔진 리플렉션 시스템과 연동되어야 합니다. UFUNCTION()을 붙이지 않으면 바인딩에 실패할 수 있습니다.
- 블루프린트 접근성을 설정하지 않았더라도, 기본적으로 메타데이터가 생성됩니다.
- 언리얼 엔진의 입력 처리 시스템은 바인딩된 함수가 리플렉션 시스템을 통해 접근 가능한지 확인합니다.
- BindAction 함수
- 첫 번째 인자: 어떤 UInputAction과 연결할지. (예: MoveAction)
- 두 번째 인자: 액션이 발생하는 트리거 이벤트 (Triggered, Ongoing, Completed 등).
- 세 번째/네 번째 인자: 액션 발생 시 실행할 객체(this)와 함수 포인터.
- 점프와 스프린트 함수 분리
- IA에서 설정한 Value Type이 bool일 경우 "키를 누를 때"와 "뗄 때"가 다르게 처리되도록 보통 두 함수로 분리한다.
행동 함수 구현하기
Move
void AJinCharacter::Move(const FInputActionValue& value)
{
if (!Controller) return; // 컨트롤러가 있어야 방향 계산이 가능
const FVector2D MoveInput = value.Get<FVector2D>();
if (!FMath::IsNearlyZero(MoveInput.X))
{
AddMovementInput(GetActorForwardVector(), MoveInput.X);
}
if (!FMath::IsNearlyZero(MoveInput.Y))
{
AddMovementInput(GetActorRightVector(), MoveInput.Y);
}
}
value는 Axis2D로 설정된 IA_Move의 입력값 (WASD)을 담고 있음, if 조건은 오류를 방지하기 위한 방어 코드
- AddMovementInput(방향, 크기)
- 첫 번째 파라미터: 월드 좌표 기준 이동 방향(Forward, Right 등)
- 두 번째 파라미터: 이동 스케일(속도)
- 내부적으로 CharacterMovementComponent가 이 요청을 받아 속도를 계산하고, 실제 이동을 구현합니다.
Jump
void AJinCharacter::StartJump(const FInputActionValue& value)
{
if (value.Get<bool>())
{
Jump();
}
}
void AJinCharacter::StopJump(const FInputActionValue& value)
{
if (value.Get<bool>())
{
StopJumping();
}
}
- value.Get<bool>()
- Enhanced Input System에서 전달된 입력 값을 bool로 가져옵니다.
- 이 값은 점프 키(예: 스페이스바)가 눌렸는지 여부를 나타냅니다.
- true: 키가 눌림.
- false: 키가 눌리지 않음.
- StopJumping() , Jump()
- Character 클래스에서 기본 제공되는 함수로, 캐릭터가 점프를 하거나 멈추도록 만들어줍니다.
Look
void AJinCharacter::Look(const FInputActionValue& value)
{
FVector2D LookInput = value.Get<FVector2D>();
AddControllerYawInput(LookInput.X);
AddControllerPitchInput(LookInput.Y);
}
- AddControllerYawInput(): 카메라의 Yaw 축 (수평 회전)을 변경
- AddControllerPitchInput(): 카메라의 Pitch 축 (수직 회전)을 변경
- 실제 어느 방향으로 얼마나 회전할지는, 프로젝트 세팅 → Input → Mouse Sensitivity나 LookInput에 곱해줄 스케일 (Modifiers)을 통해 조정할 수 있습니다.
Sprint
우선, 캐릭터 클래스 SpartaCharacter.h 파일에서 스프린트 관련 멤버 변수를 추가해야 합니다.
// 캐릭터 헤더
private:
float NormalSpeed;
float SprintSpeedMultiplier;
float SprintSpeed;
언리얼 엔진의 CharacterMovementComponent에는 MaxWalkSpeed라는 속성이 있습니다.
MaxWalkSpeed 값을 변경하면, 캐릭터의 이동 속도가 즉시 바뀝니다.
생성자에서 변수의 기초 값들을 넣어주고 MaxWalkSpeed를 NormalSpeed 값을 넣어준다.
// 캐릭터 소스
NormalSpeed = 600.0f;
SprintSpeedMultiplier = 1.7f;
SprintSpeed = NormalSpeed * SprintSpeedMultiplier;
GetCharacterMovement()->MaxWalkSpeed = NormalSpeed;
GetCharacterMovement() : ACharacter 클래스에 기본 내장된 함수로, UCharacterMovementComponent* 포인터를 반환합니다. 여기서 MaxWalkSpeed 등의 이동 관련 설정을 바꿀 수 있습니다.
void AJinCharacter::StartSprint(const FInputActionValue& value)
{
if (GetCharacterMovement())
{
GetCharacterMovement()->MaxWalkSpeed = SprintSpeed;
}
}
void AJinCharacter::StopSprint(const FInputActionValue& value)
{
if (GetCharacterMovement())
{
GetCharacterMovement()->MaxWalkSpeed = NormalSpeed;
}
}
value값이 true면 MaxWalkSpeed를 SprintSpeed로, false면 NormalSpeed로 설정한다.
'언리얼 + cpp' 카테고리의 다른 글
언리얼C++ 7일차(인터페이스) (0) | 2025.09.22 |
---|---|
언리얼C++ 6일차(애니메이션 블루프린트, 스테이트 머신, Control Rig) (0) | 2025.09.19 |
언리얼C++ 5일차(컨트롤러, 인풋시스템, IA, IMC) (0) | 2025.09.18 |
언리얼C++ 5일차(GameMode) (0) | 2025.09.18 |
언리얼C++ 3일차(리플렉션 시스템) (0) | 2025.09.16 |