캐릭터에 액션 바인딩 추가하기

김민수·2025년 1월 27일

언리얼 C++

목록 보기
27/32

SpartaCharacter.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "SpartaCharacter.generated.h"

class USpringArmComponent;
class UCameraComponent;
// Enhanced Input에서 액션 값을 받을 때 사용하는 구조체 (미리 선언)
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;

	// 캐릭터 동작 처리 함수들
    // Enhanced Input에서 액션 값은 FInputActionValue로 전달됨
	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);
};

(1) FInputActionValue

  • FInputActionValueEnhanced Input System에서 사용되는 구조체로, 입력 데이터를 캡슐화한 객체다.
  • 플레이어의 입력(키보드, 마우스, 게임패드 등)에서 얻은 을 처리하고, 이를 다양한 타입으로 변환할 수 있다.
  • 예를 들어, IA_Move는 방향 입력을 반환할 때 FVector2D를 사용하고, IA_Jumpbool을 사용한다.
데이터 타입설명예시
bool단순 ON/OFF 동작점프, 스프린트 등
float1차원 축 값가속/감속, 조이스틱 트리거
FVector2D2D 벡터 값 (X, Y 축)캐릭터 이동, 마우스 이동
FVector3D3D 벡터 값 (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)
            {
                // IA_Move 액션 키를 "키를 누르고 있는 동안" Move() 호출
                EnhancedInput->BindAction(
                    PlayerController->MoveAction,
                    ETriggerEvent::Triggered,
                    this,
                    &ASpartaCharacter::Move
                );
            }
            
            if (PlayerController->JumpAction)
            {
                // IA_Jump 액션 키를 "키를 누르고 있는 동안" StartJump() 호출
                EnhancedInput->BindAction(
                    PlayerController->JumpAction,
                    ETriggerEvent::Triggered,
                    this,
                    &ASpartaCharacter::StartJump
                );
                
                // IA_Jump 액션 키에서 "키를 뗀 순간" StopJump() 호출
                EnhancedInput->BindAction(
                    PlayerController->JumpAction,
                    ETriggerEvent::Completed,
                    this,
                    &ASpartaCharacter::StopJump
                );
            }
            
            if (PlayerController->LookAction)
            {
                // IA_Look 액션 마우스가 "움직일 때" Look() 호출
                EnhancedInput->BindAction(
                    PlayerController->LookAction,
                    ETriggerEvent::Triggered,
                    this,
                    &ASpartaCharacter::Look
                );
            }
            
            if (PlayerController->SprintAction)
            {
                // IA_Sprint 액션 키를 "누르고 있는 동안" StartSprint() 호출
                EnhancedInput->BindAction(
                    PlayerController->SprintAction,
                    ETriggerEvent::Triggered, 
                    this, 
                    &ASpartaCharacter::StartSprint
                );
                // IA_Sprint 액션 키에서 "키를 뗀 순간" StopSprint() 호출
                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)
{
}

(1) Enhanced InputComponent 타입으로 캐스팅

if (UEnhancedInputComponent* EnhancedInput = Cast<UEnhancedInputComponent>(PlayerInputComponent))
  • PlayerInputComponentUEnhancedInputComponent로 변환한다.
  • 왜 필요한가?
    • Enhanced Input System은 기본 UInputComponent와 달리 UEnhancedInputComponent라는 확장된 버전을 사용한다.
    • 만약 PlayerInputComponentUEnhancedInputComponent 타입이 아니라면, Enhanced Input 기능을 사용할 수 없다.
    • 따라서 Cast를 통해 변환을 시도하고, 성공하면 Enhanced Input 기능을 안전하게 사용할 수 있게 된다.

(2) 현재 소유 중인 Controller를 ASpartaPlayerController 타입으로 캐스팅

if (ASpartaPlayerController* PlayerController = Cast<ASpartaPlayerController>(GetController()))
  • GetController()가 반환한 컨트롤러를 ASpartaPlayerController 타입으로 변환한다.
  • GetController()
    • GetController()는 캐릭터(또는 폰)를 제어하는 컨트롤러 객체를 반환한다.
  • 왜 필요한가?
    • GetController()가 반환하는 기본 타입은 AController이다.
    • 그러나 우리가 정의한 ASpartaPlayerControllerAController를 상속받아 확장된 클래스다.
    • ASpartaPlayerController에 정의된 추가적인 멤버 변수함수(예: MoveAction, JumpAction 등)를 사용하려면 AController 타입에서 ASpartaPlayerController 타입으로 변환해야 한다.

(3) 입력 액션 바인딩

if (PlayerController->JumpAction)
{
    // IA_Jump 액션 키를 "키를 누르고 있는 동안" StartJump() 호출
    EnhancedInput->BindAction(
        PlayerController->JumpAction,
        ETriggerEvent::Triggered,
        this,
        &ASpartaCharacter::StartJump
    );

    // IA_Jump 액션 키에서 "키를 뗀 순간" StopJump() 호출
    EnhancedInput->BindAction(
        PlayerController->JumpAction,
        ETriggerEvent::Completed,
        this,
        &ASpartaCharacter::StopJump
    );
}
  • EnhancedInput->BindAction
    • BindAction: 특정 입력 액션을 지정한 함수와 연결(바인딩)한다.
      • 입력 액션이 발생하면, 지정한 함수가 호출된다.
    • 매개변수:
      • PlayerController->JumpAction : 바인딩할 Input Action(점프 동작)
      • ETriggerEvent::Triggered : 입력 이벤트가 발생하는 시점(키를 누르고 있는 동안)
      • this : 바인딩할 함수를 소유하는 객체(여기서는 ASpartaCharacter)
      • &ASpartaCharacter::StartJump: 입력 이벤트가 발생했을 때 호출할 함수
profile
안녕하세요

0개의 댓글