입력 애셋과 EnhancedInputSystem Context 등록

DevBison·2025년 8월 15일

3인칭 카메라 기본 개념

스프링 암(팔)로 카메라를 캐릭터 뒤에 띄워놓고, 충돌/지연 설정으로 “부드럽게 따라오는” 느낌을 만든다.


스프링 암 컴포넌트는 3인칭에서 카메라를 캐릭터와 일정 거리로 유지해주는 역할


스프링 암 끝 소켓 위치에 카메라를 붙인다


소켓 오프셋/타깃 오프셋보다, 스프링 암 자체의 위치·회전을 잡아주는 편이 직관적

카메라 충돌(Probe Size)은 “장애물에 부딪힐 때 판정 반지름”. 너무 크면 쉽게 끼고, 너무 작으면 벽을 뚫는 느낌이 날 수 있음.
폰 제어 회전 사용(Use Pawn Control Rotation)을 켜면, 컨트롤러 요/피치가 스프링 암에도 반영돼 같이 돈다.
카메라 렉(Camera Lag)을 켜면 질량감 있는 “따라오기” 느낌을 줄 수 있음.


Perspective는 원근감 있는 투시, Orthographic은 원근 없는 직교 투영(2D/전략뷰 느낌)

C++로 구성하기


PlatformCharacter 헤더에 필요한 컴포넌트 포인터(스프링암/카메라)를 멤버로 선언


cpp에서 생성/세팅

// PlatformCharacter.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "PlatformCharacter.generated.h"

class USpringArmComponent;
class UCameraComponent;

UCLASS()
class APlatformCharacter : public ACharacter
{
	GENERATED_BODY()

public:
	APlatformCharacter();

protected:
	UPROPERTY(VisibleAnywhere, Category="Camera")
	USpringArmComponent* SpringArm;

	UPROPERTY(VisibleAnywhere, Category="Camera")
	UCameraComponent* FollowCamera;

	virtual void BeginPlay() override;
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
};
// PlatformCharacter.cpp
#include "PlatformCharacter.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/CharacterMovementComponent.h"

APlatformCharacter::APlatformCharacter()
{
	PrimaryActorTick.bCanEverTick = true;

	// 스프링암
	SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));
	SpringArm->SetupAttachment(GetRootComponent());
	SpringArm->TargetArmLength = 350.f;           // 캐릭터와의 거리
	SpringArm->bUsePawnControlRotation = true;    // 컨트롤러 회전 반영
	SpringArm->bEnableCameraLag = true;           // 카메라 따라오기
	SpringArm->CameraLagSpeed = 12.f;
	SpringArm->ProbeSize = 12.f;                  // 충돌 프로브 반지름

	// 카메라
	FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
	FollowCamera->SetupAttachment(SpringArm, USpringArmComponent::SocketName);
	FollowCamera->bUsePawnControlRotation = false; // 카메라 자체는 회전 고정, 팔이 돌아감

	// 캐릭터 이동 세팅
	UCharacterMovementComponent* Move = GetCharacterMovement();
	Move->bOrientRotationToMovement = false; // 캐릭터가 이동방향으로 자동 회전하지 않음
	Move->RotationRate = FRotator(0.f, 540.f, 0.f);

	// 컨트롤러 요만 캐릭터에 적용(3인칭 보통 구성)
	bUseControllerRotationYaw = true;
	bUseControllerRotationPitch = false;
	bUseControllerRotationRoll = false;
}

void APlatformCharacter::BeginPlay()
{
	Super::BeginPlay();
}

void APlatformCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);
	// Enhanced Input로 바인딩 예정
}


캐릭터 무브먼트에는 중력/가속/마찰/점프 등 다양한 파라미터가 있다. 목적에 맞게 조정


기존(레거시) Input도 사용 가능하지만, UE5에선 Enhanced Input 사용을 권장한다(완전 폐기 아님).

Enhanced Input 핵심 정리


입력 액션(Input Action): “무슨 동작인가”(점프/이동/회전 등) 정의
입력 매핑 컨텍스트(Input Mapping Context): “어떤 키/스틱을 어떤 액션에 매핑할지” 정의


이동용 IAMove 생성 (Value Type: Axis2D/Vector2D)


앞/뒤/좌/우 축을 한 번에 전달하기 위해 Axis2D 사용

bool은 눌렀다/뗐다(디지털), Axis는 연속 값(아날로그 스틱/마우스)


“누적” 세팅은 입력 변환이 연쇄되어 적용되도록 하는 개념 (여러 Modifier/Swizzle 조합 시 유용)


회전용 IARotation 생성 (Value Type: Axis1D/float) — 보통 요(yaw) 회전을 바인딩



입력 매핑 컨텍스트에 방금 만든 액션들을 키/축에 매핑


키를 누르면 기본 입력 값은 1


W는 전진이므로 +1, S는 후진이므로 Negate로 -1


Swizzle(YXZ)은 “순서를 바꿔 특정 축을 꺼내는” 변환. 예) Y를 오른쪽/왼쪽 스트레이프 축으로 사용
E는 +1(오른쪽), Q는 Negate로 -1(왼쪽)


회전 IARotation: D를 +1(우회전), A를 Negate로 -1(좌회전)

입력 리소스 따로 관리하기 (UPlatformInput)

입력 리소스(매핑 컨텍스트/액션)를 한 곳에 모아두면 캐릭터에서 참조만 하면 되어 편함.



별도 폴더에서 관리


UPlatformInput 클래스 이름 지정


기본 생성자

#include "InputMappingContext.h"
#include "InputAction.h"

헤더에 포함


퍼블릭 변수로 IMC/IAMove/IARotation 등 노출(에셋 할당용)




참조 복사 후 붙여넣기


나머지도 동일하게 채우기

아래처럼 “데이터 에셋” 형태로 두면 사용하기 좋다.

// PlatformInput.h
#pragma once
#include "Engine/DataAsset.h"
#include "PlatformInput.generated.h"

class UInputMappingContext;
class UInputAction;

UCLASS(BlueprintType)
class UPlatformInput : public UDataAsset
{
	GENERATED_BODY()
public:
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Input")
	UInputMappingContext* MappingContext = nullptr;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Input")
	UInputAction* IA_Move = nullptr;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Input")
	UInputAction* IA_Rotation = nullptr;

	// 필요 시 점프/공격 등 추가
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Input")
	UInputAction* IA_Jump = nullptr;
};

캐릭터에 입력 연결하기


PlatformCharacter.cpp에서 위 입력 리소스를 받아와 등록·바인딩

이 코드는 캐릭터가 게임에 등장할 때(BeginPlay) 플레이어 입력을 받을 수 있도록 Enhanced Input 시스템에 입력 매핑 컨텍스트를 등록하는 과정이에요.


코드 흐름 설명

  1. Super::BeginPlay();

    • 부모 클래스(ACharacter)의 BeginPlay()를 먼저 호출해서 기본 초기화 로직을 실행합니다.
    • 안 하면 부모 쪽 필수 동작들이 안 돌 수 있어요.
  2. APlayerController* PlyerController = Cast<APlayerController>(GetController());

    • 이 캐릭터가 현재 어떤 컨트롤러(PlayerController)로 조종되고 있는지 가져옵니다.
    • Cast<>()는 타입 변환 함수인데, 안전하게 형변환을 해주고 실패하면 nullptr을 반환합니다.
    • 플레이어가 조종 중이면 PlayerController가 있을 것이고, AI가 조종 중이면 없을 수도 있어요.
  3. if (IsValid(PlyerController))

    • IsValid()는 UObject가 null이 아니고 파괴되지 않은 상태인지 확인하는 함수입니다.
    • 안전하게 다음 단계를 실행하기 위한 체크입니다.
  4. UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlyerController->GetLocalPlayer());

    • 언리얼의 Enhanced Input 시스템에서 Local Player Subsystem을 얻어옵니다.
    • Subsystem은 실제로 입력 매핑을 관리해주는 객체예요.
    • GetLocalPlayer() → 현재 플레이어의 로컬 플레이어 객체를 반환.
    • ULocalPlayer::GetSubsystem<>() → 특정 타입의 서브시스템(여기선 입력 서브시스템)을 가져옴.
  5. const UPlatformInput* InputCDO = GetDefault<UPlatformInput>();

    • GetDefault<>()는 해당 클래스 타입의 **CDO(Class Default Object)**를 가져옵니다.
    • CDO는 클래스의 '원본 템플릿 객체'라고 생각하면 돼요. 디폴트 값이 들어있고, 메모리상 1개만 존재합니다.
    • 여기선 UPlatformInput 클래스의 기본 인스턴스를 얻어오는 거죠.
    • const인 이유는 CDO는 기본값만 참고하고 수정하면 안 되기 때문입니다.
  6. Subsystem->AddMappingContext(InputCDO->mContext, 0);

    • 실제로 입력 매핑 컨텍스트(mContext)를 Enhanced Input 시스템에 등록하는 단계입니다.
    • mContext는 보통 Input Mapping Context 애셋을 가리킵니다.
    • 두 번째 인자 0은 우선순위입니다. 숫자가 클수록 높은 우선순위를 가집니다.

한 줄로 정리

이 함수는 게임 시작 시, 해당 캐릭터가 플레이어 입력을 받을 수 있도록 UPlatformInput의 기본 입력 매핑 컨텍스트를 Enhanced Input 서브시스템에 등록하는 초기화 과정입니다.


체크리스트/팁

  • 스프링암이 안 돌아간다면 bUsePawnControlRotation을 확인
  • 캐릭터가 이동 방향으로 돌아가면 bOrientRotationToMovement를 끄고, 컨트롤러 요를 켠다
  • Camera Lag은 과하면 멀미 유발, 8~15 사이에서 감 잡으면서 조절
  • Probe Size가 너무 크면 벽에 과하게 튕김
  • Enhanced Input에서 S, A 같은 반대 방향은 Negate(부정)로 -1을 만들어준다
  • Swizzle은 축 셔플이므로, 원하는 축(Y 등)을 정확히 뽑아오는지 미리 콘솔 로그로 확인하면 좋다
  • DataAsset(UPlatformInput)로 묶어두면 프로젝트 전역에서 재사용 편리
profile
응애 개발자

0개의 댓글