106 lines
3.2 KiB
C++
106 lines
3.2 KiB
C++
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
|
|
|
|
|
#include "Collision/GCS_AsyncAction_CollisionTrace.h"
|
|
#include "Collision/GCS_TraceSystemComponent.h"
|
|
#include "Components/PrimitiveComponent.h"
|
|
#include "Engine/Engine.h"
|
|
|
|
UGCS_AsyncAction_CollisionTrace* UGCS_AsyncAction_CollisionTrace::SetupAndListenForCollisionTraceHit(UGCS_TraceSystemComponent* TraceSystem,
|
|
const TArray<FGCS_TraceDefinition>& TraceDefinitions,
|
|
UPrimitiveComponent* PrimitiveComponent,
|
|
UObject* OptionalSourceObject)
|
|
{
|
|
if (TraceSystem == nullptr)
|
|
{
|
|
FFrame::KismetExecutionMessage(TEXT("SetupAndListenForCollisionTraceHit was passed a null TraceSystem"), ELogVerbosity::Error);
|
|
return nullptr;
|
|
}
|
|
|
|
if (PrimitiveComponent == nullptr)
|
|
{
|
|
FFrame::KismetExecutionMessage(TEXT("SetupAndListenForCollisionTraceHit was passed a null PrimitiveComponent"), ELogVerbosity::Error);
|
|
return nullptr;
|
|
}
|
|
|
|
if (TraceDefinitions.IsEmpty())
|
|
{
|
|
FFrame::KismetExecutionMessage(TEXT("SetupAndListenForCollisionTraceHit was passed empty TraceDefinitions"), ELogVerbosity::Error);
|
|
return nullptr;
|
|
}
|
|
|
|
UWorld* World = GEngine->GetWorldFromContextObject(TraceSystem, EGetWorldErrorMode::LogAndReturnNull);
|
|
if (!World)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
UGCS_AsyncAction_CollisionTrace* Action = NewObject<UGCS_AsyncAction_CollisionTrace>();
|
|
|
|
Action->TraceDefinitions = TraceDefinitions;
|
|
Action->TraceSystem = TraceSystem;
|
|
Action->SourceComponent = PrimitiveComponent;
|
|
Action->SourceObject = OptionalSourceObject;
|
|
Action->RegisterWithGameInstance(World);
|
|
|
|
return Action;
|
|
}
|
|
|
|
void UGCS_AsyncAction_CollisionTrace::Activate()
|
|
{
|
|
UGCS_TraceSystemComponent* TSC = TraceSystem.Get();
|
|
UPrimitiveComponent* Primitive = SourceComponent.Get();
|
|
UObject* SourceObj = SourceObject.Get();
|
|
|
|
if (TSC && Primitive)
|
|
{
|
|
TSC->OnTraceHitEvent.AddDynamic(this, &ThisClass::TraceHitCallback);
|
|
|
|
static FHitResult EmptyHitResult;
|
|
TraceHandles = TSC->AddTraces(TraceDefinitions, Primitive, SourceObj);
|
|
for (auto& Handle : TraceHandles)
|
|
{
|
|
BeforeActive.Broadcast(Handle, EmptyHitResult);
|
|
TSC->StartTrace(Handle);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetReadyToDestroy();
|
|
}
|
|
}
|
|
|
|
void UGCS_AsyncAction_CollisionTrace::Cancel()
|
|
{
|
|
Super::Cancel();
|
|
UGCS_TraceSystemComponent* TSC = TraceSystem.Get();
|
|
UPrimitiveComponent* Primitive = SourceComponent.Get();
|
|
if (TSC && Primitive)
|
|
{
|
|
TSC->OnTraceHitEvent.RemoveAll(this);
|
|
//Deactivate traces.
|
|
for (const FGCS_TraceHandle& Handle : TraceHandles)
|
|
{
|
|
if (Handle.IsValidHandle())
|
|
{
|
|
TSC->RemoveTrace(Handle);
|
|
}
|
|
}
|
|
TraceHandles.Empty();
|
|
SourceComponent = nullptr;
|
|
TraceSystem = nullptr;
|
|
SourceObject = nullptr;
|
|
}
|
|
}
|
|
|
|
void UGCS_AsyncAction_CollisionTrace::TraceHitCallback(const FGCS_TraceHandle& TraceHandle, const FHitResult& HitResult)
|
|
{
|
|
if (ShouldBroadcastDelegates() && TraceHandle.IsValidHandle())
|
|
{
|
|
if (TraceHandles.Contains(TraceHandle))
|
|
{
|
|
OnHit.Broadcast(TraceHandle, HitResult);
|
|
}
|
|
}
|
|
}
|