Add new events for trigger + fix GetVolumeCenter
This commit is contained in:
parent
fbe4129df8
commit
750cd3b656
BIN
Pawn_Unreal/Content/Characters/BP_Judy.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/Characters/BP_Judy.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Pawn_Unreal/Content/Developers/maxim/BP_TriggerTest.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/Developers/maxim/BP_TriggerTest.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Pawn_Unreal/Content/Input/BP_MainPlayerController.uasset
(Stored with Git LFS)
BIN
Pawn_Unreal/Content/Input/BP_MainPlayerController.uasset
(Stored with Git LFS)
Binary file not shown.
@ -31,7 +31,7 @@ void UPwnTrigger::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActo
|
||||
if (UPwnTriggerRegister* Register = OtherActor->GetComponentByClass<UPwnTriggerRegister>()) {
|
||||
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<UPwnTriggerRegister>()) {
|
||||
Register->UnregisterTrigger(this);
|
||||
OnTriggerExit.Broadcast(OtherActor);
|
||||
ExecuteActions(ExitActions);
|
||||
ExecuteActions(ExitActions, OtherActor);
|
||||
}
|
||||
}
|
||||
|
||||
void UPwnTrigger::Activate(const bool bReset) {
|
||||
if (bReset || ShouldActivate() == true) {
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<float>::Max();
|
||||
UPwnTrigger* BestTrigger = nullptr;
|
||||
float LowestDot = TNumericLimits<float>::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
|
||||
@ -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);
|
||||
};
|
||||
|
||||
@ -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:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user