GameMode
PlayerController
제트기(Pawn)
Enhanced Input을 통한 이동/카메라/롤 조작
시점 및 컨트롤 문제
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameMode.h"
#include "MyGameMode.generated.h"
UCLASS()
class HW07PROJECT_API AMyGameMode : public AGameMode
{
GENERATED_BODY()
public:
AMyGameMode();
};
#include "MyGameMode.h"
#include "UObject/ConstructorHelpers.h"
AMyGameMode::AMyGameMode()
{
}
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "MyPlayerController.generated.h"
class UInputMappingContext;
UCLASS()
class HW07PROJECT_API AMyPlayerController : public APlayerController
{
GENERATED_BODY()
public:
AMyPlayerController();
protected:
virtual void BeginPlay() override; // 플레이어 컨트롤러의 초기화
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input")
UInputMappingContext* InputMappingContext;
};
#include "MyPlayerController.h"
#include "EnhancedInputSubsystems.h"
#include "EnhancedInputComponent.h"
AMyPlayerController::AMyPlayerController()
{
}
void AMyPlayerController::BeginPlay()
{
Super::BeginPlay();
// 현재 게임의 로컬 플레이어를 가져오는 함수
if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
{
// 로컬 플레이어의 Enhanced Input 서브시스템을 가져
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
{
// 입력 맵핑 컨텍스트가 있으면 추가
if (InputMappingContext)
{
Subsystem->AddMappingContext(InputMappingContext, 0); // 0은 우선 순위
}
}
}
}
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "InputActionValue.h"
#include "MyPawn.generated.h"
UCLASS()
class HW07PROJECT_API AMyPawn : public APawn
{
GENERATED_BODY()
public:
AMyPawn();
protected:
virtual void BeginPlay() override;
virtual void Tick(float DeltaTime) override;
// 플레이어 입력을 설정하는 함수
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// 플레이어 입력을 설정하는 함수
void OnMove(const FInputActionValue& Value);
void OnLook(const FInputActionValue& Value);
void OnRoll(const FInputActionValue& Value);
private:
// 컴포넌트 선언
UPROPERTY(EditAnywhere)
class UCapsuleComponent* Capsule;
UPROPERTY(EditAnywhere)
class USkeletalMeshComponent* JetMesh;
UPROPERTY(EditAnywhere)
class USpringArmComponent* SpringArm;
UPROPERTY(EditAnywhere)
class UCameraComponent* Camera;
// 입력 맵핑과 관련된 변수들
UPROPERTY(EditAnywhere, Category = "Input")
class UInputMappingContext* InputMapping;
UPROPERTY(EditAnywhere, Category = "Input")
class UInputAction* MoveAction;
UPROPERTY(EditAnywhere, Category = "Input")
class UInputAction* LookAction;
UPROPERTY(EditAnywhere, Category = "Input")
class UInputAction* RollAction;
// 이동 컴포넌트
UPROPERTY(VisibleAnywhere, Category = "Movement")
class UFloatingPawnMovement* MovementComponent;
// 속도 설정
UPROPERTY(EditAnywhere)
float MoveSpeed = 600.f;
UPROPERTY(EditAnywhere)
float TurnSpeed = 100.f;
// 이동, 시점, 롤 제어를 위한 함수들
UFUNCTION()
void Move(const FInputActionValue& Value);
UFUNCTION()
void Look(const FInputActionValue& Value);
UFUNCTION()
void Roll(const FInputActionValue& Value);
};
#include "MyPawn.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "InputMappingContext.h"
#include "InputAction.h"
#include "InputActionValue.h"
#include "Components/CapsuleComponent.h"
#include "Components/SkeletalMeshComponent.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "GameFramework/FloatingPawnMovement.h"
AMyPawn::AMyPawn()
{
PrimaryActorTick.bCanEverTick = true;
bUseControllerRotationYaw = true;
Capsule = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule"));
RootComponent = Capsule;
Capsule->SetSimulatePhysics(false);
JetMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("JetMesh"));
JetMesh->SetupAttachment(RootComponent);
JetMesh->SetSimulatePhysics(false);
SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));
SpringArm->SetupAttachment(RootComponent);
SpringArm->TargetArmLength = 1200.f; // 카메라와의 거리
SpringArm->SetRelativeLocation(FVector(0.f, 0.f, 200.f)); // 스프링암의 위치 설정
SpringArm->SetRelativeRotation(FRotator(-15.f, 0.f, 0.f)); // 스프링암의 회전 설정
SpringArm->bUsePawnControlRotation = true; // 카메라의 회전이 Pawn의 제어에 의해 결정되도록 설정
SpringArm->bInheritPitch = true;
SpringArm->bInheritYaw = true;
SpringArm->bInheritRoll = true;
Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
Camera->SetupAttachment(SpringArm); // 카메라를 스프링암에 부착
MovementComponent = CreateDefaultSubobject<UFloatingPawnMovement>(TEXT("MovementComponent"));
}
void AMyPawn::BeginPlay()
{
Super::BeginPlay();
// Enhanced Input 시스템 초기화
if (APlayerController* PlayerController = Cast<APlayerController>(GetController()))
{
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
{
Subsystem->AddMappingContext(InputMapping, 0);
}
}
}
void AMyPawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
if (UEnhancedInputComponent* Input = Cast<UEnhancedInputComponent>(PlayerInputComponent))
{
Input->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMyPawn::Move);
Input->BindAction(LookAction, ETriggerEvent::Triggered, this, &AMyPawn::Look);
Input->BindAction(RollAction, ETriggerEvent::Triggered, this, &AMyPawn::Roll);
}
}
void AMyPawn::Move(const FInputActionValue& Value)
{
FVector2D MoveVector = Value.Get<FVector2D>();
UE_LOG(LogTemp, Warning, TEXT("Move Input: X=%f, Y=%f"), MoveVector.X, MoveVector.Y);
// 이동 입력이 있을 경우, 그 방향으로 이동
if (!MoveVector.IsNearlyZero())
{
AddMovementInput(GetActorForwardVector(), MoveVector.Y); // 전후 이동
AddMovementInput(GetActorRightVector(), MoveVector.X); // 좌우 이동
}
}
void AMyPawn::Look(const FInputActionValue& Value)
{
// 시점 입력 처리 (Yaw, Pitch)
FVector2D LookVector = Value.Get<FVector2D>();
// 시점 변경 입력이 있을 경우, 회전 적용
if (LookVector != FVector2D::ZeroVector)
{
AddControllerYawInput(LookVector.X); // 좌우 회전
AddControllerPitchInput(LookVector.Y); // 상하 회전
}
}
void AMyPawn::Roll(const FInputActionValue& Value)
{
// 롤 회전 입력 처리
float RollValue = Value.Get<float>();
// 롤 회전 값이 있을 경우 회전 적용
if (!FMath::IsNearlyZero(RollValue))
{
FRotator NewRotation = GetActorRotation();
NewRotation.Roll += RollValue * 2.0f; // 롤 회전 값에 따른 회전 적용
SetActorRotation(NewRotation); // 회전 적용
}
}
AddMovementInput(GetActorForwardVector(), MoveVector.Y) 로컬 축 기준으로 수정 GetActorRightVector() 방향 반전 문제로 코드 점검 Use Auto Possess Player 옵션 확인 Subsystem->AddMappingContext 가 BeginPlay에 들어가는지 확인 OnRoll, Roll 중복 제거하고 하나로 통합 Shift + F11 전체화면 또는 Play 세팅에서 New Editor Window 사용bShowMouseCursor, bEnableClickEvents, bEnableMouseOverEvents 확인LogTemp로 디버깅 유용하게 사용 `UE_LOG(LogTemp, Warning, TEXT("Move called"));