// Copyright VocationLife Project. All Rights Reserved. #include "VocationPlayerController.h" #include "VocationCharacter.h" #include "VocationHUD.h" #include "VocationSessionSubsystem.h" #include "VocationGameInstance.h" #include "VocationMainMenuWidget.h" #include "EnhancedInputComponent.h" #include "EnhancedInputSubsystems.h" #include "InputAction.h" #include "InputMappingContext.h" #include "InputCoreTypes.h" #include "Blueprint/UserWidget.h" #include "Kismet/GameplayStatics.h" AVocationPlayerController::AVocationPlayerController() { } void AVocationPlayerController::BeginPlay() { Super::BeginPlay(); CreateRuntimeInputAssets(); if (ULocalPlayer* LocalPlayer = GetLocalPlayer()) { if (UEnhancedInputLocalPlayerSubsystem* Subsystem = LocalPlayer->GetSubsystem()) { Subsystem->AddMappingContext(SharedMappingContext, SharedMappingPriority); Subsystem->AddMappingContext(TopDownMappingContext, ModeMappingPriority); } } if (AVocationHUD* HUD = Cast(GetHUD())) { VocationHUD = HUD; } if (UVocationGameInstance* GI = GetGameInstance()) { GI->SetGraphicsPreset(GI->GetGraphicsPreset(), GI->IsRayTracingEnabled()); } // Show multiplayer menu on first load (local player only). if (IsLocalController() && !IsRunningDedicatedServer()) { ToggleMultiplayerMenu(); } } void AVocationPlayerController::SetupInputComponent() { Super::SetupInputComponent(); if (UEnhancedInputComponent* EnhancedInput = Cast(InputComponent)) { if (AVocationCharacter* Character = Cast(GetPawn())) { EnhancedInput->BindAction(MoveAction, ETriggerEvent::Triggered, Character, &AVocationCharacter::HandleMove); EnhancedInput->BindAction(LookAction, ETriggerEvent::Triggered, Character, &AVocationCharacter::HandleLook); EnhancedInput->BindAction(JumpAction, ETriggerEvent::Started, Character, &AVocationCharacter::HandleJumpStarted); EnhancedInput->BindAction(InteractAction, ETriggerEvent::Started, Character, &AVocationCharacter::HandleInteract); EnhancedInput->BindAction(AttackAction, ETriggerEvent::Started, Character, &AVocationCharacter::HandleAttack); EnhancedInput->BindAction(ToggleCameraAction, ETriggerEvent::Started, Character, &AVocationCharacter::HandleToggleCamera); EnhancedInput->BindAction(InventoryAction, ETriggerEvent::Started, Character, &AVocationCharacter::HandleInventory); EnhancedInput->BindAction(PauseAction, ETriggerEvent::Started, this, &AVocationPlayerController::TogglePauseMenu); } } InputComponent->BindKey(EKeys::F1, IE_Pressed, this, &AVocationPlayerController::ApplyLowGraphics).bConsumeInput = false; InputComponent->BindKey(EKeys::F2, IE_Pressed, this, &AVocationPlayerController::ApplyMediumGraphics).bConsumeInput = false; InputComponent->BindKey(EKeys::F3, IE_Pressed, this, &AVocationPlayerController::ApplyHighGraphics).bConsumeInput = false; InputComponent->BindKey(EKeys::F4, IE_Pressed, this, &AVocationPlayerController::ApplyUltraGraphics).bConsumeInput = false; InputComponent->BindKey(EKeys::F5, IE_Pressed, this, &AVocationPlayerController::ApplyRayTracingGraphics).bConsumeInput = false; InputComponent->BindKey(EKeys::M, IE_Pressed, this, &AVocationPlayerController::ToggleMultiplayerMenu).bConsumeInput = false; InputComponent->BindKey(EKeys::H, IE_Pressed, this, &AVocationPlayerController::HostCoopGame).bConsumeInput = false; InputComponent->BindKey(EKeys::J, IE_Pressed, this, &AVocationPlayerController::JoinFirstFoundSession).bConsumeInput = false; InputComponent->BindKey(EKeys::S, IE_Pressed, this, &AVocationPlayerController::QuickSave).bConsumeInput = false; } void AVocationPlayerController::OnPossess(APawn* InPawn) { Super::OnPossess(InPawn); SetupInputComponent(); if (AVocationCharacter* Character = Cast(InPawn)) { ApplyInputMappingForCameraMode(Character->GetCameraMode()); } } void AVocationPlayerController::TogglePauseMenu() { bPauseMenuOpen = !bPauseMenuOpen; SetPause(bPauseMenuOpen); if (VocationHUD) { VocationHUD->SetPauseVisible(bPauseMenuOpen); } } void AVocationPlayerController::ShowInteractionPrompt(const FText& Prompt) { if (VocationHUD) { VocationHUD->SetInteractionPrompt(Prompt); } } void AVocationPlayerController::ClearInteractionPrompt() { if (VocationHUD) { VocationHUD->ClearInteractionPrompt(); } } void AVocationPlayerController::ToggleMultiplayerMenu() { if (MultiplayerMenu && MultiplayerMenu->IsInViewport()) { MultiplayerMenu->RemoveFromParent(); bShowMouseCursor = false; SetInputMode(FInputModeGameOnly()); return; } MultiplayerMenu = CreateWidget(this, UVocationMainMenuWidget::StaticClass()); if (MultiplayerMenu) { MultiplayerMenu->AddToViewport(100); bShowMouseCursor = true; FInputModeGameAndUI Mode; Mode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock); Mode.SetHideCursorDuringCapture(false); SetInputMode(Mode); } } void AVocationPlayerController::HostCoopGame() { if (UVocationSessionSubsystem* Sessions = GetGameInstance()->GetSubsystem()) { Sessions->HostSession(4, TEXT("VocationLife"), TEXT("/Engine/Maps/Entry"), 7777, EVocationNetBackend::Auto, false); } } void AVocationPlayerController::FindCoopGames() { if (UVocationSessionSubsystem* Sessions = GetGameInstance()->GetSubsystem()) { Sessions->FindSessions(); } } void AVocationPlayerController::JoinCoopGame(int32 SessionIndex) { if (UVocationSessionSubsystem* Sessions = GetGameInstance()->GetSubsystem()) { Sessions->JoinSessionByIndex(SessionIndex); } } void AVocationPlayerController::ApplyInputMappingForCameraMode(EVocationCameraMode CameraMode) { if (ULocalPlayer* LocalPlayer = GetLocalPlayer()) { if (UEnhancedInputLocalPlayerSubsystem* Subsystem = LocalPlayer->GetSubsystem()) { Subsystem->RemoveMappingContext(FirstPersonMappingContext); Subsystem->RemoveMappingContext(TopDownMappingContext); if (CameraMode == EVocationCameraMode::FirstPerson) { Subsystem->AddMappingContext(FirstPersonMappingContext, ModeMappingPriority); } else { Subsystem->AddMappingContext(TopDownMappingContext, ModeMappingPriority); } } } } void AVocationPlayerController::CreateRuntimeInputAssets() { MoveAction = NewObject(this, TEXT("IA_Move")); MoveAction->ValueType = EInputActionValueType::Axis2D; LookAction = NewObject(this, TEXT("IA_Look")); LookAction->ValueType = EInputActionValueType::Axis2D; JumpAction = NewObject(this, TEXT("IA_Jump")); InteractAction = NewObject(this, TEXT("IA_Interact")); AttackAction = NewObject(this, TEXT("IA_Attack")); ToggleCameraAction = NewObject(this, TEXT("IA_ToggleCamera")); InventoryAction = NewObject(this, TEXT("IA_Inventory")); PauseAction = NewObject(this, TEXT("IA_Pause")); SharedMappingContext = NewObject(this, TEXT("IMC_Vocation_Shared")); SharedMappingContext->MapKey(JumpAction, EKeys::SpaceBar); SharedMappingContext->MapKey(InteractAction, EKeys::E); SharedMappingContext->MapKey(AttackAction, EKeys::LeftMouseButton); SharedMappingContext->MapKey(ToggleCameraAction, EKeys::C); SharedMappingContext->MapKey(InventoryAction, EKeys::I); SharedMappingContext->MapKey(PauseAction, EKeys::Escape); SharedMappingContext->MapKey(JumpAction, EKeys::Gamepad_FaceButton_Bottom); SharedMappingContext->MapKey(InteractAction, EKeys::Gamepad_FaceButton_Left); SharedMappingContext->MapKey(AttackAction, EKeys::Gamepad_RightTrigger); SharedMappingContext->MapKey(ToggleCameraAction, EKeys::Gamepad_Special_Right); SharedMappingContext->MapKey(InventoryAction, EKeys::Gamepad_FaceButton_Top); SharedMappingContext->MapKey(PauseAction, EKeys::Gamepad_Special_Left); FirstPersonMappingContext = NewObject(this, TEXT("IMC_Vocation_FP")); FirstPersonMappingContext->MapKey(MoveAction, EKeys::W); FirstPersonMappingContext->MapKey(MoveAction, EKeys::S); FirstPersonMappingContext->MapKey(MoveAction, EKeys::A); FirstPersonMappingContext->MapKey(MoveAction, EKeys::D); FirstPersonMappingContext->MapKey(LookAction, EKeys::Mouse2D); FirstPersonMappingContext->MapKey(MoveAction, EKeys::Gamepad_LeftX); FirstPersonMappingContext->MapKey(MoveAction, EKeys::Gamepad_LeftY); FirstPersonMappingContext->MapKey(LookAction, EKeys::Gamepad_RightX); FirstPersonMappingContext->MapKey(LookAction, EKeys::Gamepad_RightY); TopDownMappingContext = NewObject(this, TEXT("IMC_Vocation_TP")); TopDownMappingContext->MapKey(MoveAction, EKeys::W); TopDownMappingContext->MapKey(MoveAction, EKeys::S); TopDownMappingContext->MapKey(MoveAction, EKeys::A); TopDownMappingContext->MapKey(MoveAction, EKeys::D); TopDownMappingContext->MapKey(LookAction, EKeys::Mouse2D); TopDownMappingContext->MapKey(MoveAction, EKeys::Gamepad_LeftX); TopDownMappingContext->MapKey(MoveAction, EKeys::Gamepad_LeftY); TopDownMappingContext->MapKey(LookAction, EKeys::Gamepad_RightX); } void AVocationPlayerController::ApplyLowGraphics() { if (UVocationGameInstance* GI = GetGameInstance()) { GI->SetGraphicsPreset(EVocationGraphicsPreset::Low, false); } } void AVocationPlayerController::ApplyMediumGraphics() { if (UVocationGameInstance* GI = GetGameInstance()) { GI->SetGraphicsPreset(EVocationGraphicsPreset::Medium, false); } } void AVocationPlayerController::ApplyHighGraphics() { if (UVocationGameInstance* GI = GetGameInstance()) { GI->SetGraphicsPreset(EVocationGraphicsPreset::High, false); } } void AVocationPlayerController::ApplyUltraGraphics() { if (UVocationGameInstance* GI = GetGameInstance()) { GI->SetGraphicsPreset(EVocationGraphicsPreset::Ultra, false); } } void AVocationPlayerController::ApplyRayTracingGraphics() { if (UVocationGameInstance* GI = GetGameInstance()) { GI->SetGraphicsPreset(EVocationGraphicsPreset::RayTracing, true); } } void AVocationPlayerController::JoinFirstFoundSession() { if (UVocationSessionSubsystem* Sessions = GetGameInstance()->GetSubsystem()) { Sessions->OnSessionSearchComplete.AddDynamic(this, &AVocationPlayerController::HandleSessionSearchForJoin); Sessions->FindSessions(); } } void AVocationPlayerController::HandleSessionSearchForJoin(const TArray& SessionNames) { if (UVocationSessionSubsystem* Sessions = GetGameInstance()->GetSubsystem()) { Sessions->OnSessionSearchComplete.RemoveDynamic(this, &AVocationPlayerController::HandleSessionSearchForJoin); if (SessionNames.Num() > 0) { Sessions->JoinSessionByIndex(0); } } } void AVocationPlayerController::QuickSave() { if (UVocationGameInstance* GI = GetGameInstance()) { GI->SaveGame(); if (VocationHUD) { VocationHUD->ShowDebugStatus(TEXT("Game saved.")); } } }