From ac000a37c6c3a46cb643564f2df28bd18a454f07 Mon Sep 17 00:00:00 2001 From: Arnaud Jamin Date: Sun, 30 Mar 2025 23:24:31 -0400 Subject: [PATCH] CogSubsystem: prevent creating multiple input component when having multiple player controller. Typically when entering debug camera. --- .../Cog/Source/Cog/Private/CogSubsystem.cpp | 69 +++++++++++-------- Plugins/Cog/Source/Cog/Public/CogSubsystem.h | 6 +- 2 files changed, 42 insertions(+), 33 deletions(-) diff --git a/Plugins/Cog/Source/Cog/Private/CogSubsystem.cpp b/Plugins/Cog/Source/Cog/Private/CogSubsystem.cpp index 8c37cc4..ec0c1f8 100644 --- a/Plugins/Cog/Source/Cog/Private/CogSubsystem.cpp +++ b/Plugins/Cog/Source/Cog/Private/CogSubsystem.cpp @@ -244,15 +244,18 @@ void UCogSubsystem::Tick(UWorld* InTickedWorld, ELevelTick InTickType, float InD FCogImGuiContextScope ImGuiContextScope(Context); - UpdateServerPlayerControllers(*World); - - if (UPlayerInput* PlayerInput = (LocalPlayerController != nullptr) ? LocalPlayerController->PlayerInput : nullptr) + UpdatePlayerControllers(*World); + + if (auto* LocalPlayerControllerPtr = LocalPlayerController.Get()) { - //------------------------------------------------------------------ - // We must wait for the player input to be valid to disable - // DebugExecBindings conflicting with our shortcuts. - //------------------------------------------------------------------ - TryDisableCommandsConflictingWithShortcuts(PlayerInput); + if (UPlayerInput* PlayerInput = LocalPlayerControllerPtr->PlayerInput) + { + //------------------------------------------------------------------ + // We must wait for the player input to be valid to disable + // DebugExecBindings conflicting with our shortcuts. + //------------------------------------------------------------------ + TryDisableCommandsConflictingWithShortcuts(PlayerInput); + } } if (LayoutToLoad != -1) @@ -284,50 +287,52 @@ void UCogSubsystem::RequestDisableCommandsConflictingWithShortcuts() } //-------------------------------------------------------------------------------------------------------------------------- -void UCogSubsystem::SetLocalPlayerController(APlayerController* PlayerController) +void UCogSubsystem::SetLocalPlayerController(APlayerController& PlayerController) { - if (LocalPlayerController == PlayerController) + if (LocalPlayerController.Get() == &PlayerController) { return; } + + LocalPlayerController = &PlayerController; + InputComponent.Reset(); - LocalPlayerController = PlayerController; - - if (LocalPlayerController == nullptr) - { return; } - - UInputComponent* InputComponentPtr = NewObject(PlayerController, TEXT("Cog_Input")); - InputComponent = InputComponentPtr; - if (InputComponentPtr) + if (UInputComponent* InputComponentPtr = NewObject(&PlayerController, TEXT("Cog_Input"))) { - PlayerController->PushInputComponent(InputComponentPtr); + InputComponent = InputComponentPtr; + PlayerController.PushInputComponent(InputComponentPtr); } for (FCogShortcut& Shortcut : Shortcuts) { BindShortcut(Shortcut); } + + if (LocalPlayerController->PlayerInput != nullptr) + { + FCogImguiInputHelper::DisableCommandsConflictingWithShortcuts(*LocalPlayerController->PlayerInput); + } } //-------------------------------------------------------------------------------------------------------------------------- -void UCogSubsystem::UpdateServerPlayerControllers(UWorld& World) +void UCogSubsystem::UpdatePlayerControllers(UWorld& World) { + if (APlayerController* PlayerController = GetGameInstance()->GetFirstLocalPlayerController()) + { + SetLocalPlayerController(*PlayerController); + } + TArray PluginSubsystems; ServerPlayerControllers.RemoveAll([] (TWeakObjectPtr PlayerController) { return PlayerController.IsValid() == false; }); - + for (FConstPlayerControllerIterator It = World.GetPlayerControllerIterator(); It; ++It) { APlayerController* PlayerController = It->Get(); if (PlayerController == nullptr) { continue; } - if (PlayerController->IsLocalController()) - { - SetLocalPlayerController(PlayerController); - } - if (World.GetNetMode() != NM_Client) { if (ServerPlayerControllers.Contains(PlayerController)) @@ -1062,7 +1067,11 @@ bool UCogSubsystem::BindShortcut(FCogShortcut& InShortcut) const FInputKeyBinding InputBinding(*InputChord, IE_Pressed); InputBinding.KeyDelegate.GetDelegateForManualSet() = InShortcut.Delegate; - InputComponent.Get()->KeyBindings.Add(InputBinding); + + if (UInputComponent* InputComponentPtr = InputComponent.Get()) + { + InputComponentPtr->KeyBindings.Add(InputBinding); + } InShortcut.InputChord = *InputChord; @@ -1078,13 +1087,13 @@ void UCogSubsystem::RebindShortcut(const UCogCommonConfig& InConfig, const FProp UInputComponent* InputComponentPtr = InputComponent.Get(); if (InputComponentPtr == nullptr) { return; } - + for (auto& KeyBinding : InputComponentPtr->KeyBindings) { KeyBinding.KeyDelegate.Unbind(); } - InputComponent.Get()->KeyBindings.Empty(); - + InputComponentPtr->KeyBindings.Empty(); + for (FCogShortcut& Shortcut : Shortcuts) { BindShortcut(Shortcut); diff --git a/Plugins/Cog/Source/Cog/Public/CogSubsystem.h b/Plugins/Cog/Source/Cog/Public/CogSubsystem.h index b047273..3815000 100644 --- a/Plugins/Cog/Source/Cog/Public/CogSubsystem.h +++ b/Plugins/Cog/Source/Cog/Public/CogSubsystem.h @@ -117,7 +117,7 @@ protected: virtual void TryInitialize(UWorld& World); - virtual void UpdateServerPlayerControllers(UWorld& World); + virtual void UpdatePlayerControllers(UWorld& World); virtual void InitializeWindow(FCogWindow* Window); @@ -133,7 +133,7 @@ protected: virtual void RenderMenuItemHelp(FCogWindow& Window); - void SetLocalPlayerController(APlayerController* PlayerController); + void SetLocalPlayerController(APlayerController& PlayerController); virtual void ToggleInputMode(); @@ -183,7 +183,7 @@ protected: mutable TArray> Assets; TArray> ServerPlayerControllers; - + TWeakObjectPtr LocalPlayerController; TWeakObjectPtr InputComponent;