From 750cd3b65632b8e495132c9e38e65fd581d77920 Mon Sep 17 00:00:00 2001 From: Maxime Date: Fri, 4 Aug 2023 00:19:59 +0200 Subject: [PATCH] Add new events for trigger + fix GetVolumeCenter --- Pawn_Unreal/Content/Characters/BP_Judy.uasset | 4 +-- .../Developers/maxim/BP_TriggerTest.uasset | 4 +-- .../Input/BP_MainPlayerController.uasset | 4 +-- .../Pawn/Private/Interaction/PwnTrigger.cpp | 24 ++++++++------ .../Interaction/PwnTriggerRegister.cpp | 31 +++++++++++++------ .../Pawn/Public/Interaction/PwnInteractable.h | 2 +- .../Pawn/Public/Interaction/PwnTrigger.h | 18 +++++++++-- 7 files changed, 57 insertions(+), 30 deletions(-) diff --git a/Pawn_Unreal/Content/Characters/BP_Judy.uasset b/Pawn_Unreal/Content/Characters/BP_Judy.uasset index d21f3c3..d5f7b21 100644 --- a/Pawn_Unreal/Content/Characters/BP_Judy.uasset +++ b/Pawn_Unreal/Content/Characters/BP_Judy.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:688fd36e25836113024533b73015000e02d1e110cdc1377eba4301450be33207 -size 92219 +oid sha256:0efcf723e3a973e8af63b85a29c32de61390ec5af146b6fd28a9dcc0431d9cbe +size 68228 diff --git a/Pawn_Unreal/Content/Developers/maxim/BP_TriggerTest.uasset b/Pawn_Unreal/Content/Developers/maxim/BP_TriggerTest.uasset index 142e972..cb72b15 100644 --- a/Pawn_Unreal/Content/Developers/maxim/BP_TriggerTest.uasset +++ b/Pawn_Unreal/Content/Developers/maxim/BP_TriggerTest.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:74f0e15b324ce560fe9e595c7917b484d70b8c1eec6b8a190b5dd9a1dea4d526 -size 105126 +oid sha256:2fb54fce233f8c1dc6db6c753aa2a1b65b083a879ca3a260d2154ff2f59d866f +size 125028 diff --git a/Pawn_Unreal/Content/Input/BP_MainPlayerController.uasset b/Pawn_Unreal/Content/Input/BP_MainPlayerController.uasset index e432989..3be82ed 100644 --- a/Pawn_Unreal/Content/Input/BP_MainPlayerController.uasset +++ b/Pawn_Unreal/Content/Input/BP_MainPlayerController.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:19e8e0064886d3e43537a4da6384d38421c4c82ba7a3f6ea191542981c775986 -size 107073 +oid sha256:c5682baa22019295cae9889a6441a91009fc9338181a04cbcfa33b7d8a93cf90 +size 103316 diff --git a/Pawn_Unreal/Source/Pawn/Private/Interaction/PwnTrigger.cpp b/Pawn_Unreal/Source/Pawn/Private/Interaction/PwnTrigger.cpp index 8c09aaf..57db3a9 100644 --- a/Pawn_Unreal/Source/Pawn/Private/Interaction/PwnTrigger.cpp +++ b/Pawn_Unreal/Source/Pawn/Private/Interaction/PwnTrigger.cpp @@ -31,7 +31,7 @@ void UPwnTrigger::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActo if (UPwnTriggerRegister* Register = OtherActor->GetComponentByClass()) { Register->RegisterTrigger(this); OnTriggerEnter.Broadcast(OtherActor); - ExecuteActions(EnterActions); + ExecuteActions(EnterActions, OtherActor); } } @@ -40,13 +40,15 @@ void UPwnTrigger::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* if (UPwnTriggerRegister* Register = OtherActor->GetComponentByClass()) { Register->UnregisterTrigger(this); OnTriggerExit.Broadcast(OtherActor); - ExecuteActions(ExitActions); + ExecuteActions(ExitActions, OtherActor); } } void UPwnTrigger::Activate(const bool bReset) { if (bReset || ShouldActivate() == true) { - VolumeComponent->SetCollisionEnabled(ECollisionEnabled::QueryOnly); + if (VolumeComponent) { + VolumeComponent->SetCollisionEnabled(ECollisionEnabled::QueryOnly); + } SetActiveFlag(true); OnComponentActivated.Broadcast(this, bReset); } @@ -54,34 +56,36 @@ void UPwnTrigger::Activate(const bool bReset) { void UPwnTrigger::Deactivate() { if (ShouldActivate() == false) { - VolumeComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision); + if (VolumeComponent) { + VolumeComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision); + } SetActiveFlag(false); OnComponentDeactivated.Broadcast(this); } } -void UPwnTrigger::Interact_Implementation(const EInteractionType InteractionType) { +void UPwnTrigger::Interact_Implementation(const EInteractionType InteractionType, const AActor* Interactor) { if (InteractionType == Enable) { Activate(true); } else if (InteractionType == Disable) { Deactivate(); } else if (InteractionType == Toggle) { - ExecuteActions(ManualActions); + ExecuteActions(ManualActions, Interactor); } } FVector UPwnTrigger::GetVolumeCenter() const { if (ensure(VolumeComponent)) { - VolumeComponent->Bounds.Origin; + return VolumeComponent->Bounds.Origin; } return FVector::ZeroVector; } -void UPwnTrigger::ExecuteActions(const FInteractableActions& InteractableActions) const { +void UPwnTrigger::ExecuteActions(const FInteractableActions& InteractableActions, const AActor* Interactor) const { for (const FInteractableAction &Action : InteractableActions.Actions) { - Execute_Interact(Action.Interactable.ActorReference.TryLoad(), Action.InteractionType); + Execute_Interact(Action.Interactable.ActorReference.TryLoad(), Action.InteractionType, Interactor); } if (InteractableActions.SelfInteract) { - Execute_Interact(GetOwner(), InteractableActions.SelfInteractionType); + Execute_Interact(GetOwner(), InteractableActions.SelfInteractionType, Interactor); } } diff --git a/Pawn_Unreal/Source/Pawn/Private/Interaction/PwnTriggerRegister.cpp b/Pawn_Unreal/Source/Pawn/Private/Interaction/PwnTriggerRegister.cpp index 305a277..c5cb097 100644 --- a/Pawn_Unreal/Source/Pawn/Private/Interaction/PwnTriggerRegister.cpp +++ b/Pawn_Unreal/Source/Pawn/Private/Interaction/PwnTriggerRegister.cpp @@ -26,21 +26,32 @@ void UPwnTriggerRegister::UnregisterTrigger(UPwnTrigger* Trigger) { RelevantTrigger = nullptr; } } - +UE_DISABLE_OPTIMIZATION void UPwnTriggerRegister::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { - UPwnTrigger* ClosestTrigger = nullptr; - float ClosestDistance = TNumericLimits::Max(); + UPwnTrigger* BestTrigger = nullptr; + float LowestDot = TNumericLimits::Max(); for (UPwnTrigger* PwnTrigger : Triggers) { - const float Distance = FVector::DistSquared2D(GetOwner()->GetActorLocation(), PwnTrigger->GetVolumeCenter()); - if (Distance < ClosestDistance) { - ClosestDistance = Distance; - ClosestTrigger = PwnTrigger; + FVector2D ActorForward = FVector2D(GetOwner()->GetActorForwardVector()); + FVector2D ActorToTrigger = FVector2D(PwnTrigger->GetVolumeCenter() - GetOwner()->GetActorLocation()).GetSafeNormal(); + const float Dot = FVector2D::DotProduct(ActorForward, ActorToTrigger); + // Check dot product against lowest dot product and check if the actor is facing the trigger + + if (Dot < LowestDot && (!PwnTrigger->MustFaceCenter || FMath::RadiansToDegrees(FMath::Acos(Dot)) < PwnTrigger->FaceAngle * 0.5f)) { + LowestDot = Dot; + BestTrigger = PwnTrigger; } } - if (ClosestTrigger != RelevantTrigger) { - OnRelevantTriggerChanged.Broadcast(RelevantTrigger, ClosestTrigger); - RelevantTrigger = ClosestTrigger; + if (BestTrigger != RelevantTrigger) { + OnRelevantTriggerChanged.Broadcast(RelevantTrigger, BestTrigger); + if (RelevantTrigger) { + RelevantTrigger->OnTriggerUnreadyToInteract.Broadcast(GetOwner()); + } + RelevantTrigger = BestTrigger; + if (RelevantTrigger) { + RelevantTrigger->OnTriggerReadyToInteract.Broadcast(GetOwner()); + } } } +UE_ENABLE_OPTIMIZATION \ No newline at end of file diff --git a/Pawn_Unreal/Source/Pawn/Public/Interaction/PwnInteractable.h b/Pawn_Unreal/Source/Pawn/Public/Interaction/PwnInteractable.h index 7bcd2de..eae4022 100644 --- a/Pawn_Unreal/Source/Pawn/Public/Interaction/PwnInteractable.h +++ b/Pawn_Unreal/Source/Pawn/Public/Interaction/PwnInteractable.h @@ -21,5 +21,5 @@ class PAWN_API IPwnInteractable { public: UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category="Interaction") - void Interact(const EInteractionType InteractionType); + void Interact(const EInteractionType InteractionType, const AActor* Interactor); }; diff --git a/Pawn_Unreal/Source/Pawn/Public/Interaction/PwnTrigger.h b/Pawn_Unreal/Source/Pawn/Public/Interaction/PwnTrigger.h index e1473d0..cbbdf30 100644 --- a/Pawn_Unreal/Source/Pawn/Public/Interaction/PwnTrigger.h +++ b/Pawn_Unreal/Source/Pawn/Public/Interaction/PwnTrigger.h @@ -62,14 +62,14 @@ protected: // End of Unreal Engine overrides public: // IPwnInteractable overrides - virtual void Interact_Implementation(const EInteractionType InteractionType) override; + virtual void Interact_Implementation(const EInteractionType InteractionType, const AActor* Interactor) override; // End of IPwnInteractable overrides UFUNCTION() FVector GetVolumeCenter() const; private: - void ExecuteActions(const FInteractableActions &InteractableActions) const; + void ExecuteActions(const FInteractableActions &InteractableActions, const AActor* Interactor) const; public: UPROPERTY(EditAnywhere, Category="Interaction") @@ -81,14 +81,26 @@ public: UPROPERTY(EditAnywhere, Category="Interaction") FInteractableActions ManualActions; + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Interactor", meta=(ToolTip="If true, the manual actions can only be triggered if the player is facing the center of the trigger volume.")) + bool MustFaceCenter = true; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Interactor", meta=(Units="degrees", EditCondition="MustFaceCenter", ClampMin=0.0f, ClampMax=360.0f, UIMin=0.0f, UIMax=360.0f)) + float FaceAngle = 60.0f; + UPROPERTY(BlueprintAssignable) FTriggerDelegate OnTriggerEnter; UPROPERTY(BlueprintAssignable) FTriggerDelegate OnTriggerExit; + UPROPERTY(BlueprintAssignable) + FTriggerDelegate OnTriggerReadyToInteract; + + UPROPERTY(BlueprintAssignable) + FTriggerDelegate OnTriggerUnreadyToInteract; + protected: - UPROPERTY(EditAnywhere, meta=(UseComponentPicker, AllowedClasses="ShapeComponent")) + UPROPERTY(EditAnywhere, Category="Volume", meta=(UseComponentPicker, AllowedClasses="ShapeComponent")) FComponentReference TriggerVolume; private: