AEyeXActorBase* AEyeXPlayerController::FindBySweep(FHitResult& OutHit, const FSceneView* const View, const FVector2D& GazePoint, const FCollisionObjectQueryParams& ObjectParams, const FCollisionQueryParams& TraceParams) { if (SweepIntervals <= 1) { UE_LOG(LogEyeX, Warning, TEXT("Invalid value for SweepIntervals: %i. Must be greater than 0."), SweepIntervals); return nullptr; } UWorld* World = GetWorld(); if (!World) return nullptr; FVector Start, Direction; View->DeprojectFVector2D(GazePoint, Start, Direction); const float TanFOVScaled = GetTanOfFOVAngleScaled(); // Perform sweeps const float DeltaDistance = MaxDistance / SweepIntervals; const FVector DeltaDirection = DeltaDistance * Direction; float CurrentDistance = DeltaDistance / 2; FCollisionShape Shape; AEyeXActorBase* EyeXActor = nullptr; for (int i = 0; i < SweepIntervals; ++i) { const FVector End = Start + DeltaDirection; const float Radius = (i == 0) ? 0.0f : TanFOVScaled * CurrentDistance; // Depends on the view frustrum, size of the screen and the distance. Shape.SetSphere(Radius); if (World->SweepSingleByObjectType(OutHit, Start, End, FQuat::Identity, ObjectParams, Shape, TraceParams)) { EyeXActor = Cast<AEyeXActorBase>(OutHit.GetActor()); break; } Start = End; CurrentDistance += DeltaDistance; } VisualizeHit(bVisualizeDetection, World, OutHit, Shape.GetSphereRadius()); VisualizeGazePoint(bVisualizeDetection, World, Start); return EyeXActor; }
UCollision2PGeom::UCollision2PGeom(const FCollisionShape& CollisionShape) { switch (CollisionShape.ShapeType) { case ECollisionShape::Box: { new (Storage)PxBoxGeometry(U2PVector(CollisionShape.GetBox())); break; } case ECollisionShape::Sphere: { new (Storage)PxSphereGeometry(CollisionShape.GetSphereRadius()); break; } case ECollisionShape::Capsule: { new (Storage)PxCapsuleGeometry(CollisionShape.GetCapsuleRadius(), CollisionShape.GetCapsuleAxisHalfLength()); break; } default: // invalid point ensure(false); } }
float UAISense_Aquaphobia::Update() { AIPerception::FListenerMap& ListenersMap = *GetListeners(); //For each listener who has this sense we're going to perform a sweep to determine nearby aqua actors for (auto& Elem : ListenersMap) { //Get the listener FPerceptionListener Listener = Elem.Value; const AActor* ListenerBodyActor = Listener.GetBodyActor(); for (int32 DigestedPropertyIndex = 0; DigestedPropertyIndex < DigestedProperties.Num(); DigestedPropertyIndex++) { //Create the sphere for this sense and perform the sweep to determine nearby actors FCollisionShape CollisionSphere = FCollisionShape::MakeSphere(DigestedProperties[DigestedPropertyIndex].PhobiaRadius); TArray<FHitResult> HitResults; GetWorld()->SweepMultiByChannel(HitResults, ListenerBodyActor->GetActorLocation(), ListenerBodyActor->GetActorLocation() + FVector::UpVector*CollisionSphere.GetSphereRadius(), FQuat(), ECollisionChannel::ECC_WorldDynamic, CollisionSphere); //Draw debug sphere if we have activated it via the config if (DigestedProperties[DigestedPropertyIndex].bDisplayDebugSphere) { DrawDebugSphere(GetWorld(), ListenerBodyActor->GetActorLocation(), DigestedProperties[DigestedPropertyIndex].PhobiaRadius, 8, FColor::Blue, false, 30.f, 1, 2.f); } //Check hit results for aqua actors for (int32 i = 0; i < HitResults.Num(); i++) { FHitResult hit = HitResults[i]; //To simplify things, we're going to assume that "water resources" for this post are actors that have the following game tag if (hit.GetActor()->ActorHasTag(FName("AquaActor"))) { if ((hit.GetActor()->GetActorLocation() - ListenerBodyActor->GetActorLocation()).Size() <= DigestedProperties[DigestedPropertyIndex].PhobiaRadius) { Elem.Value.RegisterStimulus(hit.GetActor(), FAIStimulus(*this, 5.f, hit.GetActor()->GetActorLocation(), ListenerBodyActor->GetActorLocation())); GLog->Log("registered stimulus!"); } } } } } //Time until next update; in this case we're forcing the update to happen in each frame return 0.f; }