Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion Source/MeleeTrace/Private/Async_WaitForMeleeTraceEvent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -37,6 +37,7 @@ UAsync_WaitForMeleeTraceEvent* UAsync_WaitForMeleeTraceEvent::WaitForMeleeTraceE
}

auto* NewAction = NewObject<UAsync_WaitForMeleeTraceEvent>();
NewAction->OncePerMultiTrace = OncePerMultiTrace;
NewAction->ActorToWatch = ActorToWatch;
NewAction->MeleeTraceComponent = MeleeTraceComponent;
NewAction->RegisterWithGameInstance(World);
Expand Down Expand Up @@ -73,23 +74,35 @@ void UAsync_WaitForMeleeTraceEvent::HandleTraceHit(
FName HitBoneName,
FMeleeTraceInstanceHandle TraceHandle)
{
if (!CanHit)
{
return;
}

FAsyncMeleeHitInfo HitInfo;
HitInfo.OwnerTraceComponent = ThisComponent;
HitInfo.HitActor = HitActor;
HitInfo.HitLocation = HitLocation;
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();
}
39 changes: 24 additions & 15 deletions Source/MeleeTrace/Private/MeleeTraceComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ void UMeleeTraceComponent::InternalStartTrace(const FMeleeTraceInfo& MeleeTraceI
MeshComponents.Append(ActorMeshComponents);
}

bool AddedAny = false;
for (UActorComponent* MeshComponent : MeshComponents)
{
UMeshComponent* TypedMeshComponent = Cast<UMeshComponent>(MeshComponent);
Expand Down Expand Up @@ -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)
Expand All @@ -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);
}
Comment on lines +296 to +304
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't really necessary. Each trace should have unique hash. Did you add this code just as a caution or did you actually run into a case where there were two traces active at the same time with identical hash?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rlewicki I ran into the case.

In this PR I'm enabling adding multiple traces, which are added in InternalStartTrace - where we already have the hash. Hence all the traces added in there will have the same hash.

The issue without this part is that only the 1st trace would be removed; e.g. for 2 swords, the 2nd is left and kept tracing.

Probably the more "correct" code would be to make the hash unique by both the context object and the mesh object.
But honestly there's just no need; simply considering this hash is now a "group hash", and removing them all in this loop, works perfectly.

}
}

Expand Down
5 changes: 4 additions & 1 deletion Source/MeleeTrace/Public/Async_WaitForMeleeTraceEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -58,6 +59,8 @@ class MELEETRACE_API UAsync_WaitForMeleeTraceEvent : public UCancellableAsyncAct
protected:
virtual void Activate() override;

bool CanHit;
bool OncePerMultiTrace;
TWeakObjectPtr<AActor> ActorToWatch;
TWeakObjectPtr<UMeleeTraceComponent> MeleeTraceComponent;

Expand Down