Search code examples
c++unreal-engine4

Unreal Engine 4: How to pass a delegate into an async line trace?


I am attempting to trace a lot of lines in unreal and I am currently doing this with LineTraceSingleByChannel (from different simultaneous threads). However, I am attempting to switch to AsyncLineTraceByChannel where I want to use FTraceDelegate to call a function on completion. I seem to be getting an error at compile time but I cannot figure out the cause. The error points at line 571 which is where the closing bracket of FTraceDelegate is located (I marked this in the code).

What am I doing wrong and how do I fix this?

The code that causes the error:

FTraceHandle UAirBlueprintLib::GetObstacleAdvAsync(const AActor* actor, const FVector& start, const FVector& end,
    FHitResult& hit, TArray<AActor*>& ignore_actors, ECollisionChannel collision_channel, bool trace_complex, bool get_material)
{
    bool bIgnoreSelf = false;
    FName traceTag;
    FTraceDelegate traceDelegate = FTraceDelegate::CreateWeakLambda(actor, [](const FTraceHandle& handle, FTraceDatum& data)
    {
        //My logic goes here;
        if (data.OutHits.Num() > 0)
        {
            const FHitResult& Result = data.OutHits[0];
        }
    });

    FCollisionQueryParams trace_params;
    trace_params.bReturnPhysicalMaterial = get_material;
    trace_params.bTraceComplex = trace_complex;
    trace_params.AddIgnoredActors(ignore_actors);

    return actor->GetWorld()->AsyncLineTraceByChannel(EAsyncTraceType::Single,
        start, end,
        collision_channel,
        trace_params,
        FCollisionResponseParams::DefaultResponseParam,
        &traceDelegate);
}

The error:

1>c:\<redacted>\unrealengine\engine\source\runtime\core\public\Delegates/DelegateInstancesImpl.h(1008): error C2440: 'return': cannot convert from 'T *' to 'UObject *'
1>          with
1>          [
1>              T=const AActor
1>          ]
1>  c:\<redacted>\unrealengine\engine\source\runtime\core\public\Delegates/DelegateInstancesImpl.h(1008): note: Conversion loses qualifiers
1>  c:\<redacted>\unrealengine\engine\source\runtime\core\public\Delegates/DelegateInstancesImpl.h(1007): note: while compiling class template member function 'UObject *TWeakBaseFunctorDelegateInstance<UserClass,TTypeWrapper<void> (const FTraceHandle &,FTraceDatum &),FunctorType>::GetUObject(void) const'
1>          with
1>          [
1>              UserClass=const AActor,
1>              FunctorType=UAirBlueprintLib::GetObstacleAdvAsync::<lambda_628e4b4604e5c1758c2bd3d199f08ff6>
1>          ]
1>  c:\<redacted>\unrealengine\engine\source\runtime\core\public\Delegates/DelegateInstancesImpl.h(1019): note: see reference to function template instantiation 'UObject *TWeakBaseFunctorDelegateInstance<UserClass,TTypeWrapper<void> (const FTraceHandle &,FTraceDatum &),FunctorType>::GetUObject(void) const' being compiled
1>          with
1>          [
1>              UserClass=const AActor,
1>              FunctorType=UAirBlueprintLib::GetObstacleAdvAsync::<lambda_628e4b4604e5c1758c2bd3d199f08ff6>
1>          ]
1>  c:\<redacted>\unrealengine\engine\source\runtime\core\public\Delegates/DelegateInstancesImpl.h(1084): note: see reference to class template instantiation 'TWeakBaseFunctorDelegateInstance<UserClass,TTypeWrapper<void> (const FTraceHandle &,FTraceDatum &),FunctorType>' being compiled
1>          with
1>          [
1>              UserClass=const AActor,
1>              FunctorType=UAirBlueprintLib::GetObstacleAdvAsync::<lambda_628e4b4604e5c1758c2bd3d199f08ff6>
1>          ]
1>  c:\<redacted>\unrealengine\engine\source\runtime\core\public\Delegates/DelegateSignatureImpl.inl(146): note: see reference to class template instantiation 'TWeakBaseFunctorDelegateInstance<UserClass,void (const FTraceHandle &,FTraceDatum &),UAirBlueprintLib::GetObstacleAdvAsync::<lambda_628e4b4604e5c1758c2bd3d199f08ff6>>' being compiled
1>          with
1>          [
1>              UserClass=const AActor
1>          ]
1>  C:\<redacted>\Documenten\<redacted>\Unreal\Environments\<redacted>\Plugins\<redacted>\Source\AirBlueprintLib.cpp(571): note: see reference to function template instantiation 'TBaseDelegate<void,const FTraceHandle &,FTraceDatum &> TBaseDelegate<TTypeWrapper<void>,const FTraceHandle &,FTraceDatum &>::CreateWeakLambda<const AActor,UAirBlueprintLib::GetObstacleAdvAsync::<lambda_628e4b4604e5c1758c2bd3d199f08ff6>,>(UserClass *,FunctorType &&)' being compiled
1>          with
1>          [
1>              UserClass=const AActor,
1>              FunctorType=UAirBlueprintLib::GetObstacleAdvAsync::<lambda_628e4b4604e5c1758c2bd3d199f08ff6>
1>          ]
1>  C:\<redacted>\Documenten\<redacted>\Unreal\Environments\<redacted>\Plugins\<redacted>\Source\AirBlueprintLib.cpp(564): note: see reference to function template instantiation 'TBaseDelegate<void,const FTraceHandle &,FTraceDatum &> TBaseDelegate<TTypeWrapper<void>,const FTraceHandle &,FTraceDatum &>::CreateWeakLambda<const AActor,UAirBlueprintLib::GetObstacleAdvAsync::<lambda_628e4b4604e5c1758c2bd3d199f08ff6>,>(UserClass *,FunctorType &&)' being compiled
1>          with
1>          [
1>              UserClass=const AActor,
1>              FunctorType=UAirBlueprintLib::GetObstacleAdvAsync::<lambda_628e4b4604e5c1758c2bd3d199f08ff6>
1>          ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\Microsoft.MakeFile.Targets(44,5): error MSB3075: The command "C:\<redacted>\UnrealEngine\Engine\Build\BatchFiles\Build.bat -Target="ShaderCompileWorker Win64 Development" -Target="<redacted> Win64 Development -Project=\"C:\<redacted_path>"" -WaitMutex -FromMsBuild" exited with code 5. Please verify that you have sufficient rights to run this command.

Solution

  • I switched to a slightly different approach that did the trick. Creating the delegate as follows worked for me:

    FTraceDelegate traceDelegate;
    traceDelegate.BindLambda([](const FTraceHandle& handle, FTraceDatum& data)
        {
            DrawDebugPoint(data.PhysWorld.Get(), data.End, 7.0f, FColor::Purple, false, 0.105);
            if (data.OutHits.Num() > 0)
            {
                const FHitResult& Result = data.OutHits[0];
            }
        });