// Fill out your copyright notice in the Description page of Project Settings. #include "AsyncTraceActor.h" // Sets default values AAsyncTraceActor::AAsyncTraceActor() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; } // Called when the game starts or when spawned void AAsyncTraceActor::BeginPlay() { Super::BeginPlay(); TraceDelegate.BindUObject(this,&AAsyncTraceActor::OnTraceCompleted); } // Called every frame void AAsyncTraceActor::OnTraceCompleted(const FTraceHandle& Handle, FTraceDatum& Data) { ensure(Handle == LastTraceHandle); DoWorkWithTraceResults(Data); LastTraceHandle._Data.FrameNumber = 0; // reset it } void AAsyncTraceActor::DoWorkWithTraceResults(const FTraceDatum& TraceData) { // do things here ReceiveOnTraceCompleted(TraceData.OutHits); } FTraceHandle AAsyncTraceActor::RequestTrace() { UWorld* World = GetWorld(); if (World == nullptr) return FTraceHandle(); auto Channel = UEngineTypes::ConvertToCollisionChannel(MyTraceType); FCollisionObjectQueryParams ObjectQueryParams(Channel); bool bTraceComplex = false; bool bIgnoreSelf = true; TArray ActorsToIgnore; auto Params = UKismetSystemLibrary::ConfigureCollisionParams(NAME_AsyncRequestTrace, bTraceComplex, ActorsToIgnore, bIgnoreSelf, this); auto Start = FVector::ZeroVector; auto End = FVector(1000.f); return World->AsyncLineTraceByChannel(EAsyncTraceType::Single, Start, End, Channel, Params, FCollisionResponseParams::DefaultResponseParam, &TraceDelegate); } void AAsyncTraceActor::SetWantsTrace() { // don't allow overlapping traces here. if (!GetWorld()->IsTraceHandleValid(LastTraceHandle,false)) { bWantsTrace = true; } } void AAsyncTraceActor::Tick(float DeltaTime) { Super::Tick(DeltaTime); if (LastTraceHandle._Data.FrameNumber != 0) { FTraceDatum OutData; if (GetWorld()->QueryTraceData(LastTraceHandle, OutData)) { // Clear out handle so next tick we don't enter LastTraceHandle._Data.FrameNumber = 0; // trace is finished, do stuff with results DoWorkWithTraceResults(OutData); } } if (bWantsTrace) { LastTraceHandle = RequestTrace(); bWantsTrace = false; } }