PyObject *py_ue_line_trace_multi_by_channel(ue_PyUObject * self, PyObject * args) { ue_py_check(self); PyObject *py_obj_start; PyObject *py_obj_end; int channel; UWorld *world = ue_get_uworld(self); if (!world) return PyErr_Format(PyExc_Exception, "unable to retrieve UWorld from uobject"); if (!PyArg_ParseTuple(args, "OOi:line_trace_multi_by_channel", &py_obj_start, &py_obj_end, &channel)) { return NULL; } ue_PyFVector *start = py_ue_is_fvector(py_obj_start); ue_PyFVector *end = py_ue_is_fvector(py_obj_end); if (!start || !end) return PyErr_Format(PyExc_Exception, "start and end location must be vectors"); TArray<struct FHitResult> hits; hits.Reset(); PyObject *hits_list = PyList_New(0); bool got_hits = world->LineTraceMultiByChannel(hits, start->vec, end->vec, (ECollisionChannel)channel); if (got_hits) { for (int i = 0; i < hits.Num(); i++) { FHitResult hit = hits[i]; PyList_Append(hits_list, py_ue_new_fhitresult(hit)); } } return hits_list; }
void UAblRayCastQueryTask::OnTaskStart(const TWeakObjectPtr<const UAblAbilityContext>& Context) const { Super::OnTaskStart(Context); AActor* SourceActor = m_QueryLocation.GetSourceActor(*Context.Get()); check(SourceActor); UWorld* World = SourceActor->GetWorld(); FTransform QueryTransform; m_QueryLocation.GetTransform(*Context.Get(), QueryTransform); const FVector RayStart = QueryTransform.GetLocation(); const FVector RayEnd = RayStart + QueryTransform.GetRotation().GetForwardVector() * m_Length; if (m_UseAsyncQuery && UAbleSettings::IsAsyncEnabled()) { UAblRayCastQueryTaskScratchPad* ScratchPad = Cast<UAblRayCastQueryTaskScratchPad>(Context->GetScratchPadForTask(this)); check(ScratchPad); if (m_OnlyReturnBlockingHit) { ScratchPad->AsyncHandle = World->AsyncLineTraceByChannel(EAsyncTraceType::Single, RayStart, RayEnd, m_CollisionChannel); } else { ScratchPad->AsyncHandle = World->AsyncLineTraceByChannel(EAsyncTraceType::Multi, RayStart, RayEnd, m_CollisionChannel); } } else { TArray<FHitResult> HitResults; FHitResult TraceResult; if (m_OnlyReturnBlockingHit) { if (World->LineTraceSingleByChannel(TraceResult, RayStart, RayEnd, m_CollisionChannel)) { HitResults.Add(TraceResult); } } else { World->LineTraceMultiByChannel(HitResults, RayStart, RayEnd, m_CollisionChannel); } #if !(UE_BUILD_SHIPPING) if (IsVerbose()) { PrintVerbose(FString::Printf(TEXT("Raycast found %d results."), HitResults.Num())); } #endif if (HitResults.Num()) { #if !(UE_BUILD_SHIPPING) if (IsVerbose()) { // Quick distance print help to see if we hit ourselves. float DistanceToBlocker = HitResults[HitResults.Num() - 1].Distance; PrintVerbose(FString::Printf(TEXT("Raycast blocking hit distance: %4.2f."), DistanceToBlocker)); } #endif if (m_CopyResultsToContext) { #if !(UE_BUILD_SHIPPING) if (IsVerbose()) { PrintVerbose(FString::Printf(TEXT("Copying %d results into Context."), HitResults.Num())); } #endif CopyResultsToContext(HitResults, Context); } if (m_FireEvent) { #if !(UE_BUILD_SHIPPING) if (IsVerbose()) { PrintVerbose(FString::Printf(TEXT("Firing Raycast Event %s with %d results."), *m_Name.ToString(), HitResults.Num())); } #endif Context->GetAbility()->OnRaycastEvent(Context.Get(), m_Name, HitResults); } } } #if !UE_BUILD_SHIPPING if (FAblAbilityDebug::ShouldDrawQueries()) { FAblAbilityDebug::DrawRaycastQuery(World, QueryTransform, m_Length); } #endif }