CH3 개인과제
Rider에서 Shift + F10으로 언리얼 에디터를 실행한 직후, 에디터에서 첫 번째 PIE를 시작하면 플레이어 입력이 동작하지 않는다.
동작하지 않는 입력은 다음과 같다.
하지만 첫 PIE를 ESC로 종료한 뒤 다시 PIE를 실행하면 입력이 정상 동작한다.
정리하면 재현 순서는 다음과 같다.
Shift + F10 실행ESC로 PIE 종료APlayerCharacter에서 Enhanced Input을 사용한다.
UInputAction을 C++ 생성자에서 CreateDefaultSubobject로 생성UInputMappingContext도 C++ 생성자에서 생성WASD, Mouse2D, Space, Shift, V 키를 C++에서 매핑BeginPlay()에서 UEnhancedInputLocalPlayerSubsystem::AddMappingContext() 호출SetupPlayerInputComponent()에서 각 InputAction을 바인딩관련 파일:
Source/MS_Simulator/Public/PlayerCharacter.hSource/MS_Simulator/Private/PlayerCharacter.cppConfig/DefaultInput.iniConfig/DefaultEngine.ini프로젝트 설정상 Enhanced Input 기본 클래스는 설정되어 있었다.
DefaultPlayerInputClass=/Script/EnhancedInput.EnhancedPlayerInput
DefaultInputComponentClass=/Script/EnhancedInput.EnhancedInputComponent
아래 조치들은 모두 문제를 해결하지 못했으며, 테스트 후 원상복구했다.
가설:
첫 PIE에서 HUD 위젯이 입력 포커스를 가져가서 캐릭터 입력이 막힐 수 있다.
시도:
HUDWidget->SetVisibility(ESlateVisibility::HitTestInvisible);HUDWidget->SetIsFocusable(false);결과:
가설:
첫 PIE 시작 직후 Viewport 또는 Widget 포커스가 늦게 잡혀서 입력 모드가 꼬일 수 있다.
시도:
GetWorldTimerManager().SetTimerForNextTick(...)FInputModeGameOnlyPlayerController->SetInputMode(InputMode)PlayerController->SetShowMouseCursor(false)SetIgnoreMoveInput(false)SetIgnoreLookInput(false)결과:
RestoreGameInputFocus() 관련 코드 원복 완료BeginPlay()에서 SetupPlayerInputComponent()로 이동가설:
첫 PIE에서 BeginPlay() 시점에는 입력 컴포넌트나 LocalPlayer Subsystem 준비가 덜 되었을 수 있다.
시도:
BeginPlay()의 AddMappingContext() 제거SetupPlayerInputComponent()에서 바인딩 직전 AddMappingContext() 호출결과:
AutoPossessPlayer = EAutoReceiveInput::Player0 추가가설:
첫 PIE에서 캐릭터가 Player0에게 자동 소유되지 않아 입력을 받지 못할 수 있다.
시도:
APlayerCharacter 생성자에 AutoPossessPlayer = EAutoReceiveInput::Player0; 추가결과:
NotifyControllerChanged()에서 입력 매핑 등록가설:
Possession 타이밍이 BeginPlay()보다 늦게 발생해서, 컨트롤러가 붙은 뒤에 매핑해야 할 수 있다.
시도:
NotifyControllerChanged() override 추가AddMappingContext() 호출BeginPlay()의 AddMappingContext() 제거결과:
가설:
첫 PIE에서 생성되는 HUD가 직접 입력을 막고 있을 수 있다.
시도:
BeginPlay()의 CreateWidgetAddToViewport결과:
InputModeGameOnly 복구로는 해결되지 않는다.BeginPlay, SetupPlayerInputComponent, NotifyControllerChanged 사이의 단순 타이밍 문제만으로 보기 어렵다.현재 UInputAction과 UInputMappingContext를 에셋이 아니라 C++ 생성자에서 CreateDefaultSubobject로 만들고 있다.
특히 UInputMappingContext::MapKey()와 NewObject<UInputModifier...>()를 생성자에서 직접 호출한다.
첫 에디터 실행 직후 첫 PIE에서만 입력이 안 먹고, 두 번째 PIE부터 정상화되는 증상은 에셋 로딩이나 CDO 초기화 순서 문제와도 맞닿아 있을 수 있다.
다음 시도 후보:
IA_Move, IA_Look, IA_Jump, IA_Sprint, IA_TogglePerspective, IMC_Player를 Content Browser 에셋으로 생성APlayerCharacter에는 UPROPERTY(EditDefaultsOnly) 참조만 둠BP_PlayerCharacter에서 해당 에셋들을 할당MapKey() 호출 제거두 번째 PIE부터 동작한다는 점 때문에, 첫 PIE에서 실제로 Possess되는 Pawn이 기대한 BP_PlayerCharacter인지 확인해야 한다.
확인 후보:
GetPawn()이 어떤 클래스인지SetupPlayerInputComponent()가 호출되는지PlayerInputComponent가 EnhancedInputComponent인지GetController()가 유효한지LocalPlayer와 EnhancedInputLocalPlayerSubsystem이 유효한지단, 이미 단순 로그 추가만으로 해결되는 작업은 아니므로 다음에는 원인 확인용 로그를 더 구체적으로 설계해서 한 번에 봐야 한다.
현재 Config/DefaultEngine.ini는 BP GameMode를 기본 GameMode로 사용한다.
GlobalDefaultGameMode=/Game/Gamemode/BP_MSSimulator_Gamemode.BP_MSSimulator_Gamemode_C
C++ AMSSimulatorGamemode는 현재 기본 Pawn이나 PlayerController 설정이 비어 있다.
다음 확인 후보:
BP_MSSimulator_Gamemode의 Default Pawn ClassBP_PlayerCharacter가 실제 기본 Pawn인지코드 조치가 모두 실패했고, Rider 실행 직후 첫 PIE에서만 발생하므로 에디터/PIE Viewport 포커스 문제일 가능성도 남아 있다.
다음 확인 후보:
Play in Selected Viewport와 New Editor Window PIE에서 차이가 있는지가장 유력한 다음 작업은 C++에서 InputAction과 MappingContext를 런타임처럼 구성하는 방식을 버리고, Enhanced Input 에셋 기반 구조로 옮기는 것이다.
권장 순서:
CreateDefaultSubobject<UInputAction>(), CreateDefaultSubobject<UInputMappingContext>(), MapKey() 제거APlayerCharacter에는 에셋 참조용 UPROPERTY(EditDefaultsOnly)만 유지BP_PlayerCharacter에서 에셋 할당BeginPlay()에서 AddMappingContext() 호출이 작업은 구조 변경이므로, 적용 전 현재 상태를 커밋하거나 별도 백업 지점을 만드는 것이 좋다.
다음에 이 문제를 다시 이어서 볼 때는 아래 조치를 반복하지 말 것.
InputModeGameOnly 강제 적용AddMappingContext()를 SetupPlayerInputComponent()로 이동AutoPossessPlayer = Player0 추가NotifyControllerChanged()에서 매핑 등록위 조치들은 모두 테스트상 실패했다.