From e4fb702a1cb02731aa26df34e506f8a4818e9fb9 Mon Sep 17 00:00:00 2001 From: Dolobarsch Date: Sat, 5 Sep 2026 21:57:27 +0200 Subject: [PATCH] =?UTF-8?q?"Hold-to-Interact"-System=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ein neues "Hold-to-Interact"-System wurde implementiert, das es Spielern ermöglicht, durch Halten einer Taste mit Objekten zu interagieren. - `UInteractionComponent` erweitert, um den Fortschritt des Halte-Timers zu berechnen und über das neue `OnInteractHoldProgressChanged`-Event zu übertragen. - Neues Widget `UInteractionPromptWidget` eingeführt, das die Fortschrittsanzeige und Interaktionsaufforderungen modular handhabt. - Veraltete Logik aus `UInteractionContextMenuWidget` entfernt und in `UInteractionPromptWidget` ausgelagert. - Zwei neue Widgets (`WBP_InteractionBar.uasset`, `WBP_InteractionQuick.uasset`) hinzugefügt. - Logging und neue Abhängigkeiten (`USegmentedBarWidget`) integriert. - Verbesserte Modularität und Benutzererfahrung durch visuelles Feedback und klare Trennung der Logik. --- .../Blueprints/BP_ThirdPersonCharacter.uasset | Bin 179358 -> 180019 bytes Content/UI/WBP_InteractionBar.uasset | Bin 0 -> 23770 bytes Content/UI/WBP_InteractionContextMenu.uasset | Bin 31175 -> 29348 bytes Content/UI/WBP_InteractionOptionEntry.uasset | Bin 39949 -> 39695 bytes Content/UI/WBP_InteractionQuick.uasset | Bin 0 -> 35557 bytes .../Interaction/InteractionComponent.cpp | 17 ++ .../Interaction/InteractionComponent.h | 18 ++ .../UI/InteractionContextMenuWidget.cpp | 92 +-------- .../UI/InteractionContextMenuWidget.h | 57 ++---- .../UI/InteractionPromptWidget.cpp | 178 ++++++++++++++++++ .../UI/InteractionPromptWidget.h | 96 ++++++++++ 11 files changed, 334 insertions(+), 124 deletions(-) create mode 100644 Content/UI/WBP_InteractionBar.uasset create mode 100644 Content/UI/WBP_InteractionQuick.uasset create mode 100644 Source/KingshearthLegacy/UI/InteractionPromptWidget.cpp create mode 100644 Source/KingshearthLegacy/UI/InteractionPromptWidget.h diff --git a/Content/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.uasset b/Content/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.uasset index b34e36996d1913e3195b097f9e896584ccfa0414..8f86ef68b8671c2e54ff4af70660010a93f9d5ef 100644 GIT binary patch delta 14830 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 delta 14304 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 diff --git a/Content/UI/WBP_InteractionBar.uasset b/Content/UI/WBP_InteractionBar.uasset new file mode 100644 index 0000000000000000000000000000000000000000..15b34f10755b39b6db6f9b19677a0e07a03d7c54 GIT binary patch literal 23770 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 Ee;M1& literal 0 HcmV?d00001 diff --git a/Content/UI/WBP_InteractionContextMenu.uasset b/Content/UI/WBP_InteractionContextMenu.uasset index 7cd0feeaf90ea1498dfd3aa89b027fea412b435f..4850b410c3fc236b0ba12735433880d405b4aea0 100644 GIT binary patch delta 8368 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 Sv`JmwVDHA%K@+b@cmEf%5G7dv delta 9335 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 Rn4KaWI)+)Fij}$%{{f=adFKEC diff --git a/Content/UI/WBP_InteractionOptionEntry.uasset b/Content/UI/WBP_InteractionOptionEntry.uasset index 0680b24588fe9e5c0c7ec5e548ca104ec6a3d8f7..2d6444d3d9b62d12dfc0214fa66022e563cbf2ab 100644 GIT binary patch delta 6879 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 diff --git a/Content/UI/WBP_InteractionQuick.uasset b/Content/UI/WBP_InteractionQuick.uasset new file mode 100644 index 0000000000000000000000000000000000000000..6a66df8046d04fe99866e32d269de73d1991b411 GIT binary patch literal 35557 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 J$bg9d{{U$uZX^Hz literal 0 HcmV?d00001 diff --git a/Source/KingshearthLegacy/Interaction/InteractionComponent.cpp b/Source/KingshearthLegacy/Interaction/InteractionComponent.cpp index db42270..674e1df 100644 --- a/Source/KingshearthLegacy/Interaction/InteractionComponent.cpp +++ b/Source/KingshearthLegacy/Interaction/InteractionComponent.cpp @@ -26,6 +26,7 @@ void UInteractionComponent::TickComponent(float DeltaTime, ELevelTick TickType, { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); UpdateFocus(); + UpdateHoldProgress(); } bool UInteractionComponent::PerformInteractionTrace(FHitResult& OutHit) const @@ -120,6 +121,22 @@ void UInteractionComponent::UpdateFocus() OnFocusedInteractableChanged.Broadcast(NewFocusedActor, FocusedOptions); } +void UInteractionComponent::UpdateHoldProgress() +{ + const bool bTimerActive = GetWorld()->GetTimerManager().IsTimerActive(HoldTimerHandle); + const float Progress = bTimerActive && HoldThreshold > 0.0f + ? FMath::Clamp(GetWorld()->GetTimerManager().GetTimerElapsed(HoldTimerHandle) / HoldThreshold, 0.0f, 1.0f) + : 0.0f; + + if (FMath::IsNearlyEqual(Progress, LastBroadcastHoldProgress, KINDA_SMALL_NUMBER)) + { + return; + } + + LastBroadcastHoldProgress = Progress; + OnInteractHoldProgressChanged.Broadcast(Progress); +} + void UInteractionComponent::TryBeginInteract() { UpdateFocus(); diff --git a/Source/KingshearthLegacy/Interaction/InteractionComponent.h b/Source/KingshearthLegacy/Interaction/InteractionComponent.h index da7f11d..dd10ce2 100644 --- a/Source/KingshearthLegacy/Interaction/InteractionComponent.h +++ b/Source/KingshearthLegacy/Interaction/InteractionComponent.h @@ -11,6 +11,7 @@ DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnFocusedInteractableChanged, AAct DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnContextMenuOpened, const TArray&, Options, int32, InitialHighlightedIndex); DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnContextMenuHighlightChanged, int32, NewHighlightedIndex); DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnContextMenuClosed); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnInteractHoldProgressChanged, float, Progress); /** * Drives the whole "hold E" contextual interaction system for its owning Actor: @@ -53,6 +54,17 @@ public: UPROPERTY(BlueprintAssignable, Category = "Interaction") FOnContextMenuClosed OnContextMenuClosed; + /** + * Fired every tick while the hold timer is running, with the 0-1 fraction of + * HoldThreshold elapsed so far - drives a fill bar for the "hold E" prompt. + * Fires once more with 0 the instant the hold ends, however it ends (release, + * secondary fired, Context Menu opened), so a bound bar always snaps back + * empty. Never fires at all for a 1-option target, since no hold timer is + * started for it. + */ + UPROPERTY(BlueprintAssignable, Category = "Interaction") + FOnInteractHoldProgressChanged OnInteractHoldProgressChanged; + /** Call from the Interact input's Started/pressed event. */ UFUNCTION(BlueprintCallable, Category = "Interaction") void TryBeginInteract(); @@ -106,6 +118,9 @@ protected: /** Re-runs PerformInteractionTrace, updates FocusedActor/FocusedOptions, and broadcasts OnFocusedInteractableChanged if either changed. */ void UpdateFocus(); + /** Re-derives hold progress from HoldTimerHandle every tick and broadcasts OnInteractHoldProgressChanged when it changes. */ + void UpdateHoldProgress(); + /** Bound to the hold timer; only ever runs when CurrentOptions.Num() >= 2. */ void HandleHoldThresholdReached(); @@ -141,4 +156,7 @@ protected: bool bHoldConsumed = false; FTimerHandle HoldTimerHandle; + + /** Last value passed to OnInteractHoldProgressChanged, so UpdateHoldProgress only broadcasts on actual change. */ + float LastBroadcastHoldProgress = 0.0f; }; diff --git a/Source/KingshearthLegacy/UI/InteractionContextMenuWidget.cpp b/Source/KingshearthLegacy/UI/InteractionContextMenuWidget.cpp index f22ec64..9d945e6 100644 --- a/Source/KingshearthLegacy/UI/InteractionContextMenuWidget.cpp +++ b/Source/KingshearthLegacy/UI/InteractionContextMenuWidget.cpp @@ -2,37 +2,15 @@ #include "InteractionContextMenuWidget.h" #include "InteractionOptionListItem.h" +#include "InteractionPromptWidget.h" #include "Interaction/InteractionComponent.h" -#include "Interaction/Interactable.h" #include "Components/ListView.h" -#include "Components/TextBlock.h" -#include "Components/Widget.h" #include "KingshearthLegacy.h" -namespace -{ - /** Toggles TextContainer when bound (so a background living alongside PromptText hides with it), else PromptText itself. */ - void SetPromptVisible(UWidget* TextContainer, UTextBlock* PromptText, bool bVisible) - { - const ESlateVisibility Visibility = bVisible ? ESlateVisibility::HitTestInvisible : ESlateVisibility::Collapsed; - - if (TextContainer) - { - TextContainer->SetVisibility(Visibility); - } - else if (PromptText) - { - PromptText->SetVisibility(Visibility); - } - } -} - void UInteractionContextMenuWidget::NativeConstruct() { Super::NativeConstruct(); - SetPromptVisible(TextContainer, PromptText, false); - if (OptionsList) { OptionsList->SetVisibility(ESlateVisibility::Collapsed); @@ -43,7 +21,6 @@ void UInteractionContextMenuWidget::InitializeInteraction(UInteractionComponent* { if (InteractionComponent) { - InteractionComponent->OnFocusedInteractableChanged.RemoveDynamic(this, &UInteractionContextMenuWidget::HandleFocusedInteractableChanged); InteractionComponent->OnContextMenuOpened.RemoveDynamic(this, &UInteractionContextMenuWidget::HandleContextMenuOpened); InteractionComponent->OnContextMenuHighlightChanged.RemoveDynamic(this, &UInteractionContextMenuWidget::HandleContextMenuHighlightChanged); InteractionComponent->OnContextMenuClosed.RemoveDynamic(this, &UInteractionContextMenuWidget::HandleContextMenuClosed); @@ -53,72 +30,19 @@ void UInteractionContextMenuWidget::InitializeInteraction(UInteractionComponent* if (InteractionComponent) { - InteractionComponent->OnFocusedInteractableChanged.AddDynamic(this, &UInteractionContextMenuWidget::HandleFocusedInteractableChanged); InteractionComponent->OnContextMenuOpened.AddDynamic(this, &UInteractionContextMenuWidget::HandleContextMenuOpened); InteractionComponent->OnContextMenuHighlightChanged.AddDynamic(this, &UInteractionContextMenuWidget::HandleContextMenuHighlightChanged); InteractionComponent->OnContextMenuClosed.AddDynamic(this, &UInteractionContextMenuWidget::HandleContextMenuClosed); } -} -void UInteractionContextMenuWidget::HandleFocusedInteractableChanged(AActor* FocusedActor, const TArray& Options) -{ - LastFocusedActor = FocusedActor; - LastFocusedOptions = Options; - UpdatePromptVisibility(); -} + UE_LOG(LogKingshearthLegacy, Log, TEXT("[Interaction] ContextMenu widget InitializeInteraction: OptionsList bound: %s, WBP_InteractionQuick bound: %s"), + OptionsList ? TEXT("yes") : TEXT("NO"), + WBP_InteractionQuick ? TEXT("yes") : TEXT("NO - check its Name in the Designer tree matches the native property, and that it's reparented to UInteractionPromptWidget")); -void UInteractionContextMenuWidget::UpdatePromptVisibility() -{ - if (!PromptText) + if (WBP_InteractionQuick) { - return; + WBP_InteractionQuick->InitializeInteraction(InInteractionComponent); } - - // The Context Menu owns the screen while it's open - keep the ever-present prompt - // out of its way until OnContextMenuClosed brings us back here. - if (InteractionComponent && InteractionComponent->IsContextMenuOpen()) - { - SetPromptVisible(TextContainer, PromptText, false); - return; - } - - AActor* FocusedActor = LastFocusedActor.Get(); - if (!FocusedActor || LastFocusedOptions.Num() == 0) - { - SetPromptVisible(TextContainer, PromptText, false); - return; - } - - // "{Verb} with {ObjectName}" on line one (or PromptOverride verbatim, if the primary - // option set one), "Press E" always, then a hint for the hold behaviour only when - // there is one (2 options = secondary, 3+ = Context Menu). - const FInteractionOption& PrimaryOption = LastFocusedOptions[0]; - FString Prompt; - if (!PrimaryOption.PromptOverride.IsEmpty()) - { - Prompt = PrimaryOption.PromptOverride.ToString(); - } - else - { - const FText ObjectName = IInteractable::Execute_GetInteractableDisplayName(FocusedActor); - Prompt = ObjectName.IsEmpty() - ? PrimaryOption.DisplayName.ToString() - : FString::Printf(TEXT("%s with %s"), *PrimaryOption.DisplayName.ToString(), *ObjectName.ToString()); - } - - Prompt += TEXT("\nPress E"); - - if (LastFocusedOptions.Num() == 2) - { - Prompt += TEXT("\nHold E for secondary interaction"); - } - else if (LastFocusedOptions.Num() >= 3) - { - Prompt += TEXT("\nHold E for Context Menu"); - } - - PromptText->SetText(FText::FromString(Prompt)); - SetPromptVisible(TextContainer, PromptText, true); } void UInteractionContextMenuWidget::PopulateOptionsList(const TArray& Options) @@ -175,8 +99,6 @@ void UInteractionContextMenuWidget::HandleContextMenuOpened(const TArraySetVisibility(ESlateVisibility::Visible); } - - UpdatePromptVisibility(); } void UInteractionContextMenuWidget::HandleContextMenuHighlightChanged(int32 NewHighlightedIndex) @@ -194,6 +116,4 @@ void UInteractionContextMenuWidget::HandleContextMenuClosed() OptionsList->ClearListItems(); OptionsList->SetVisibility(ESlateVisibility::Collapsed); } - - UpdatePromptVisibility(); } diff --git a/Source/KingshearthLegacy/UI/InteractionContextMenuWidget.h b/Source/KingshearthLegacy/UI/InteractionContextMenuWidget.h index 3dc3abe..7fa15c6 100644 --- a/Source/KingshearthLegacy/UI/InteractionContextMenuWidget.h +++ b/Source/KingshearthLegacy/UI/InteractionContextMenuWidget.h @@ -9,20 +9,18 @@ class UInteractionComponent; class UInteractionOptionListItem; +class UInteractionPromptWidget; class UListView; -class UTextBlock; -class UWidget; /** - * One widget covering both interaction UI needs so you only wire up a single thing - * in WBP_PlayerHUD: an ever-present "you're looking at something" prompt (PromptText, - * driven by OnFocusedInteractableChanged - shows any time the look trace is on an - * IInteractable, regardless of option count or whether Interact is even pressed) and - * the Context Menu shown while holding Interact on a 3+-option IInteractable - * (OptionsList, driven by OnContextMenuOpened/HighlightChanged/Closed). Both bound - * widgets are optional and toggle their own visibility independently - add whichever - * you want in the Designer, named exactly as below; all population/highlight/show-hide - * logic lives here in C++. + * The Context Menu shown while holding Interact on a 3+-option IInteractable + * (OptionsList, driven by OnContextMenuOpened/HighlightChanged/Closed). The + * ever-present "you're looking at something" prompt lives in a separate + * nested UInteractionPromptWidget instance (e.g. WBP_InteractionQuick) - + * BindWidget can only see direct nodes of this widget's own tree, not reach + * inside another UserWidget's tree, so that prompt/slider logic can't live + * here; InitializeInteraction forwards to it instead, so the HUD only needs + * to call this one entry point. */ UCLASS(abstract) class UInteractionContextMenuWidget : public UUserWidget @@ -31,7 +29,7 @@ class UInteractionContextMenuWidget : public UUserWidget public: - /** Call once, right after creation (see UPlayerHUDWidget::InitializeHUD), to bind to InInteractionComponent's delegates. */ + /** Call once, right after creation (see UPlayerHUDWidget::InitializeHUD), to bind to InInteractionComponent's delegates, including forwarding to the nested WBP_InteractionQuick prompt widget. */ UFUNCTION(BlueprintCallable, Category = "Interaction") void InitializeInteraction(UInteractionComponent* InInteractionComponent); @@ -45,9 +43,6 @@ protected: /** Selects ListItems[Index] on OptionsList, which drives each row's IUserObjectListEntry::NativeOnItemSelectionChanged. */ void SelectHighlighted(int32 Index); - UFUNCTION() - void HandleFocusedInteractableChanged(AActor* FocusedActor, const TArray& Options); - UFUNCTION() void HandleContextMenuOpened(const TArray& Options, int32 InitialHighlightedIndex); @@ -57,19 +52,6 @@ protected: UFUNCTION() void HandleContextMenuClosed(); - /** Ever-present prompt - shows the primary option's DisplayName any time the look trace is on an IInteractable. Optional, place it in the WBP subclass's Designer tree. */ - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) - TObjectPtr PromptText; - - /** - * Optional wrapper around PromptText (e.g. a panel/border providing its background) named - * exactly "TextContainer" in the Designer. When bound, its visibility is toggled instead of - * PromptText's own - so a background that lives alongside PromptText, not inside it, actually - * hides too. Falls back to toggling PromptText directly when this isn't bound. - */ - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) - TObjectPtr TextContainer; - /** * The Context Menu's option list. Optional, place it in the WBP subclass's Designer * tree as a ListView, single-selection, with its Entry Widget Class set to a WBP @@ -79,6 +61,15 @@ protected: UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) TObjectPtr OptionsList; + /** + * The ever-present prompt + hold-progress bar, nested as a WBP_InteractionQuick + * instance (a UInteractionPromptWidget subclass) named exactly "WBP_InteractionQuick" + * in the Designer tree. Optional - InitializeInteraction just skips forwarding to it + * when unbound. + */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr WBP_InteractionQuick; + UPROPERTY() TArray CachedOptions; @@ -88,14 +79,4 @@ protected: UPROPERTY() TObjectPtr InteractionComponent; - -private: - - /** Rebuilds PromptText from LastFocused*, collapsing it while the Context Menu is open. Called on focus change and on menu close. */ - void UpdatePromptVisibility(); - - TWeakObjectPtr LastFocusedActor; - - UPROPERTY() - TArray LastFocusedOptions; }; diff --git a/Source/KingshearthLegacy/UI/InteractionPromptWidget.cpp b/Source/KingshearthLegacy/UI/InteractionPromptWidget.cpp new file mode 100644 index 0000000..bce4851 --- /dev/null +++ b/Source/KingshearthLegacy/UI/InteractionPromptWidget.cpp @@ -0,0 +1,178 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "InteractionPromptWidget.h" +#include "Interaction/InteractionComponent.h" +#include "Interaction/Interactable.h" +#include "Components/TextBlock.h" +#include "Components/Widget.h" +#include "SegmentedBarWidget.h" +#include "KingshearthLegacy.h" + +namespace +{ + /** Toggles TextContainer when bound (so a background living alongside PromptText hides with it), else PromptText itself. */ + void SetPromptVisible(UWidget* TextContainer, UTextBlock* PromptText, bool bVisible) + { + const ESlateVisibility Visibility = bVisible ? ESlateVisibility::HitTestInvisible : ESlateVisibility::Collapsed; + + if (TextContainer) + { + TextContainer->SetVisibility(Visibility); + } + else if (PromptText) + { + PromptText->SetVisibility(Visibility); + } + } +} + +void UInteractionPromptWidget::NativeConstruct() +{ + Super::NativeConstruct(); + SetPromptVisible(TextContainer, PromptText, false); + if (InfoText) + { + InfoText->SetVisibility(ESlateVisibility::Collapsed); + } + if (WBP_InteractionsSlider) + { + WBP_InteractionsSlider->SetVisibility(ESlateVisibility::Collapsed); + // USegmentedBarWidget defaults to full (it's shared with the health/stamina bars), but + // the hold bar should start empty and only fill as OnInteractHoldProgressChanged reports. + WBP_InteractionsSlider->SetSegments(0.0f, 0.0f); + } +} + +void UInteractionPromptWidget::InitializeInteraction(UInteractionComponent* InInteractionComponent) +{ + UE_LOG(LogKingshearthLegacy, Log, TEXT("[Interaction] Prompt widget InitializeInteraction: component=%s, PromptText bound: %s, InfoText bound: %s, TextContainer bound: %s, Slider bound: %s"), + *GetNameSafe(InInteractionComponent), + PromptText ? TEXT("yes") : TEXT("NO"), + InfoText ? TEXT("yes") : TEXT("NO"), + TextContainer ? TEXT("yes") : TEXT("NO"), + WBP_InteractionsSlider ? TEXT("yes") : TEXT("NO")); + + if (InteractionComponent) + { + InteractionComponent->OnFocusedInteractableChanged.RemoveDynamic(this, &UInteractionPromptWidget::HandleFocusedInteractableChanged); + InteractionComponent->OnContextMenuOpened.RemoveDynamic(this, &UInteractionPromptWidget::HandleContextMenuOpened); + InteractionComponent->OnContextMenuClosed.RemoveDynamic(this, &UInteractionPromptWidget::HandleContextMenuClosed); + InteractionComponent->OnInteractHoldProgressChanged.RemoveDynamic(this, &UInteractionPromptWidget::HandleHoldProgressChanged); + } + + InteractionComponent = InInteractionComponent; + + if (InteractionComponent) + { + InteractionComponent->OnFocusedInteractableChanged.AddDynamic(this, &UInteractionPromptWidget::HandleFocusedInteractableChanged); + InteractionComponent->OnContextMenuOpened.AddDynamic(this, &UInteractionPromptWidget::HandleContextMenuOpened); + InteractionComponent->OnContextMenuClosed.AddDynamic(this, &UInteractionPromptWidget::HandleContextMenuClosed); + InteractionComponent->OnInteractHoldProgressChanged.AddDynamic(this, &UInteractionPromptWidget::HandleHoldProgressChanged); + } +} + +void UInteractionPromptWidget::HandleHoldProgressChanged(float Progress) +{ + if (WBP_InteractionsSlider) + { + WBP_InteractionsSlider->SetSegments(Progress, 0.0f); + } +} + +void UInteractionPromptWidget::HandleFocusedInteractableChanged(AActor* FocusedActor, const TArray& Options) +{ + UE_LOG(LogKingshearthLegacy, Log, TEXT("[Interaction] Prompt widget HandleFocusedInteractableChanged: actor='%s' options=%d"), + *GetNameSafe(FocusedActor), Options.Num()); + + LastFocusedActor = FocusedActor; + LastFocusedOptions = Options; + UpdatePromptVisibility(); +} + +void UInteractionPromptWidget::HandleContextMenuOpened(const TArray& Options, int32 InitialHighlightedIndex) +{ + UpdatePromptVisibility(); +} + +void UInteractionPromptWidget::HandleContextMenuClosed() +{ + UpdatePromptVisibility(); +} + +void UInteractionPromptWidget::UpdatePromptVisibility() +{ + if (!PromptText) + { + return; + } + + const auto HideAll = [this]() + { + SetPromptVisible(TextContainer, PromptText, false); + if (InfoText) + { + InfoText->SetVisibility(ESlateVisibility::Collapsed); + } + if (WBP_InteractionsSlider) + { + WBP_InteractionsSlider->SetVisibility(ESlateVisibility::Collapsed); + } + }; + + // The Context Menu owns the screen while it's open - keep the ever-present prompt + // out of its way until OnContextMenuClosed brings us back here. + if (InteractionComponent && InteractionComponent->IsContextMenuOpen()) + { + HideAll(); + return; + } + + AActor* FocusedActor = LastFocusedActor.Get(); + if (!FocusedActor || LastFocusedOptions.Num() == 0) + { + HideAll(); + return; + } + + // Primary line: "{Verb} with {ObjectName}" (or PromptOverride verbatim, if the primary + // option set one). Hint line: "Press E" always, plus a hint for the hold behaviour only + // when there is one (2 options = secondary, 3+ = Context Menu). + const FInteractionOption& PrimaryOption = LastFocusedOptions[0]; + FString Prompt; + if (!PrimaryOption.PromptOverride.IsEmpty()) + { + Prompt = PrimaryOption.PromptOverride.ToString(); + } + else + { + const FText ObjectName = IInteractable::Execute_GetInteractableDisplayName(FocusedActor); + Prompt = ObjectName.IsEmpty() + ? PrimaryOption.DisplayName.ToString() + : FString::Printf(TEXT("%s with %s"), *PrimaryOption.DisplayName.ToString(), *ObjectName.ToString()); + } + + FString Hint = TEXT("Press E"); + if (LastFocusedOptions.Num() == 2) + { + Hint += TEXT("\nHold E for secondary interaction"); + } + else if (LastFocusedOptions.Num() >= 3) + { + Hint += TEXT("\nHold E for Context Menu"); + } + + PromptText->SetText(FText::FromString(Prompt)); + SetPromptVisible(TextContainer, PromptText, true); + + if (InfoText) + { + InfoText->SetText(FText::FromString(Hint)); + InfoText->SetVisibility(ESlateVisibility::HitTestInvisible); + } + + if (WBP_InteractionsSlider) + { + WBP_InteractionsSlider->SetVisibility(ESlateVisibility::HitTestInvisible); + WBP_InteractionsSlider->SetSegments(0.0f, 0.0f); + } +} diff --git a/Source/KingshearthLegacy/UI/InteractionPromptWidget.h b/Source/KingshearthLegacy/UI/InteractionPromptWidget.h new file mode 100644 index 0000000..8ac3aad --- /dev/null +++ b/Source/KingshearthLegacy/UI/InteractionPromptWidget.h @@ -0,0 +1,96 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Blueprint/UserWidget.h" +#include "Interaction/InteractionTypes.h" +#include "InteractionPromptWidget.generated.h" + +class UInteractionComponent; +class USegmentedBarWidget; +class UTextBlock; +class UWidget; + +/** + * The ever-present "you're looking at something" prompt (PromptText, driven by + * OnFocusedInteractableChanged - shows any time the look trace is on an + * IInteractable, regardless of option count or whether Interact is even + * pressed) plus an optional hold-to-interact fill bar. Kept as its own + * UserWidget (e.g. WBP_InteractionQuick) rather than folded into + * UInteractionContextMenuWidget so it can be laid out and nested independently + * of the Context Menu's option list - see UInteractionContextMenuWidget's + * WBP_InteractionQuick binding, which forwards InitializeInteraction here. + */ +UCLASS(abstract) +class UInteractionPromptWidget : public UUserWidget +{ + GENERATED_BODY() + +public: + + /** Call once, right after creation, to bind to InInteractionComponent's delegates. Safe to call again to rebind to a different component. */ + UFUNCTION(BlueprintCallable, Category = "Interaction") + void InitializeInteraction(UInteractionComponent* InInteractionComponent); + +protected: + + virtual void NativeConstruct() override; + + UFUNCTION() + void HandleFocusedInteractableChanged(AActor* FocusedActor, const TArray& Options); + + UFUNCTION() + void HandleContextMenuOpened(const TArray& Options, int32 InitialHighlightedIndex); + + UFUNCTION() + void HandleContextMenuClosed(); + + UFUNCTION() + void HandleHoldProgressChanged(float Progress); + + /** Ever-present prompt's primary line - "{Verb} with {ObjectName}" (or PromptOverride verbatim). Named exactly "PromptText" in the Designer. */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr PromptText; + + /** + * Optional wrapper around PromptText (e.g. a panel/border providing its background, or the + * Overlay it shares with WBP_InteractionsSlider) named exactly "TextContainer" in the + * Designer. When bound, its visibility is toggled instead of PromptText's own - so a + * background/slider living alongside PromptText, not inside it, actually hides too. Falls + * back to toggling PromptText directly when this isn't bound. + */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr TextContainer; + + /** + * Optional second line - "Press E" plus a hint for the hold behaviour (2 options = + * secondary, 3+ = Context Menu). Named exactly "InfoText" in the Designer. Kept separate + * from PromptText so it can sit outside TextContainer (e.g. below the slider bar rather + * than layered on top of it). Toggles visibility on its own, in lockstep with PromptText. + */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr InfoText; + + /** + * Optional hold-to-interact fill bar - drop a WBP_SegmentedBar instance into the + * Designer tree named exactly "WBP_InteractionsSlider" and it fills 0 to 1 while + * holding E on a 2+-option target, driven by InteractionComponent's + * OnInteractHoldProgressChanged. Left unbound, holding just does nothing visually. + */ + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional = true)) + TObjectPtr WBP_InteractionsSlider; + + UPROPERTY() + TObjectPtr InteractionComponent; + +private: + + /** Rebuilds PromptText from LastFocused*, collapsing it while the Context Menu is open. */ + void UpdatePromptVisibility(); + + TWeakObjectPtr LastFocusedActor; + + UPROPERTY() + TArray LastFocusedOptions; +};