diff --git a/Source/MeleeTrace/Private/Async_WaitForMeleeTraceEvent.cpp b/Source/MeleeTrace/Private/Async_WaitForMeleeTraceEvent.cpp index 5fc420b..46ae776 100644 --- a/Source/MeleeTrace/Private/Async_WaitForMeleeTraceEvent.cpp +++ b/Source/MeleeTrace/Private/Async_WaitForMeleeTraceEvent.cpp @@ -9,7 +9,7 @@ #include "MeleeTraceComponent.h" UAsync_WaitForMeleeTraceEvent* UAsync_WaitForMeleeTraceEvent::WaitForMeleeTraceEventHit( - UObject* WorldContextObject, AActor* ActorToWatch) + UObject* WorldContextObject, AActor* ActorToWatch, bool OncePerMultiTrace) { const UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); if (!World) @@ -37,6 +37,7 @@ UAsync_WaitForMeleeTraceEvent* UAsync_WaitForMeleeTraceEvent::WaitForMeleeTraceE } auto* NewAction = NewObject(); + NewAction->OncePerMultiTrace = OncePerMultiTrace; NewAction->ActorToWatch = ActorToWatch; NewAction->MeleeTraceComponent = MeleeTraceComponent; NewAction->RegisterWithGameInstance(World); @@ -73,6 +74,11 @@ void UAsync_WaitForMeleeTraceEvent::HandleTraceHit( FName HitBoneName, FMeleeTraceInstanceHandle TraceHandle) { + if (!CanHit) + { + return; + } + FAsyncMeleeHitInfo HitInfo; HitInfo.OwnerTraceComponent = ThisComponent; HitInfo.HitActor = HitActor; @@ -80,16 +86,23 @@ void UAsync_WaitForMeleeTraceEvent::HandleTraceHit( HitInfo.HitNormal = HitNormal; HitInfo.HitBoneName = HitBoneName; OnHit.Broadcast(HitInfo, TraceHandle); + + if (CanHit && OncePerMultiTrace) + { + CanHit = false; + } } void UAsync_WaitForMeleeTraceEvent::HandleTraceStarted( UMeleeTraceComponent* ThisComponent, FMeleeTraceInstanceHandle TraceHandle) { + CanHit = true; OnStarted.Broadcast(); } void UAsync_WaitForMeleeTraceEvent::HandleTraceEnded( UMeleeTraceComponent* ThisComponent, int32 HitCount, FMeleeTraceInstanceHandle TraceHandle) { + OnEnded.Broadcast(); } diff --git a/Source/MeleeTrace/Private/MeleeTraceComponent.cpp b/Source/MeleeTrace/Private/MeleeTraceComponent.cpp index c0077ba..f0bd83f 100644 --- a/Source/MeleeTrace/Private/MeleeTraceComponent.cpp +++ b/Source/MeleeTrace/Private/MeleeTraceComponent.cpp @@ -229,6 +229,7 @@ void UMeleeTraceComponent::InternalStartTrace(const FMeleeTraceInfo& MeleeTraceI MeshComponents.Append(ActorMeshComponents); } + bool AddedAny = false; for (UActorComponent* MeshComponent : MeshComponents) { UMeshComponent* TypedMeshComponent = Cast(MeshComponent); @@ -261,14 +262,18 @@ void UMeleeTraceComponent::InternalStartTrace(const FMeleeTraceInfo& MeleeTraceI MeleeTraceInfo.EndSocketName, NewMeleeTraceInfo.PreviousFrameSampleLocations); OnTraceStart.Broadcast(this, NewMeleeTraceInfo.TraceHandle); - return; + AddedAny = true; } } - ensureAlwaysMsgf(false, - TEXT("None of the USkeletalMeshComponents contain sockets with names: %s and %s"), - *MeleeTraceInfo.StartSocketName.ToString(), - *MeleeTraceInfo.EndSocketName.ToString()); + if (!AddedAny) + { + UE_LOG(LogMeleeTrace, + Error, + TEXT("None of the USkeletalMeshComponents contain sockets with names: %s and %s"), + *MeleeTraceInfo.StartSocketName.ToString(), + *MeleeTraceInfo.EndSocketName.ToString()); + } } void UMeleeTraceComponent::InternalEndTrace(uint32 TraceHash) @@ -278,21 +283,25 @@ void UMeleeTraceComponent::InternalEndTrace(uint32 TraceHash) return; } - const int32 FoundIndex = ActiveMeleeTraces.IndexOfByPredicate( - [TraceHash](const FActiveMeleeTraceInfo& ActiveMeleeTraceInfo) - { - return TraceHash == ActiveMeleeTraceInfo.TraceHandle.TraceHash; - }); + auto Predicate = [TraceHash](const FActiveMeleeTraceInfo& ActiveMeleeTraceInfo) + { + return TraceHash == ActiveMeleeTraceInfo.TraceHandle.TraceHash; + }; + int32 FoundIndex = ActiveMeleeTraces.IndexOfByPredicate(Predicate); if (ensureAlwaysMsgf(FoundIndex != INDEX_NONE, TEXT("Attemping to end trace with hash: %u but no trace with hash exist"), TraceHash)) { - OnTraceEnd.Broadcast( - this, - ActiveMeleeTraces[FoundIndex].HitActors.Num(), - ActiveMeleeTraces[FoundIndex].TraceHandle); - ActiveMeleeTraces.RemoveAtSwap(FoundIndex); + while (FoundIndex != INDEX_NONE) + { + OnTraceEnd.Broadcast( + this, + ActiveMeleeTraces[FoundIndex].HitActors.Num(), + ActiveMeleeTraces[FoundIndex].TraceHandle); + ActiveMeleeTraces.RemoveAtSwap(FoundIndex); + FoundIndex = ActiveMeleeTraces.IndexOfByPredicate(Predicate); + } } } diff --git a/Source/MeleeTrace/Public/Async_WaitForMeleeTraceEvent.h b/Source/MeleeTrace/Public/Async_WaitForMeleeTraceEvent.h index 16dc094..e08b346 100644 --- a/Source/MeleeTrace/Public/Async_WaitForMeleeTraceEvent.h +++ b/Source/MeleeTrace/Public/Async_WaitForMeleeTraceEvent.h @@ -39,7 +39,8 @@ class MELEETRACE_API UAsync_WaitForMeleeTraceEvent : public UCancellableAsyncAct BlueprintCallable, Category = "Melee Trace", meta = (WorldContext = "WorldContextObject", BlueprintInternalUseOnly = "True")) - static UAsync_WaitForMeleeTraceEvent* WaitForMeleeTraceEventHit(UObject* WorldContextObject, AActor* ActorToWatch); + static UAsync_WaitForMeleeTraceEvent* WaitForMeleeTraceEventHit(UObject* WorldContextObject, AActor* ActorToWatch, + bool OncePerMultiTrace); virtual void Cancel() override; @@ -58,6 +59,8 @@ class MELEETRACE_API UAsync_WaitForMeleeTraceEvent : public UCancellableAsyncAct protected: virtual void Activate() override; + bool CanHit; + bool OncePerMultiTrace; TWeakObjectPtr ActorToWatch; TWeakObjectPtr MeleeTraceComponent;