static bool RayTrace(const AActor &Actor, const FVector &Start, const FVector &End) { FHitResult OutHit; static FName TraceTag = FName(TEXT("VehicleTrace")); FCollisionQueryParams CollisionParams(TraceTag, true); CollisionParams.AddIgnoredActor(&Actor); const bool Success = Actor.GetWorld()->LineTraceSingleByObjectType( OutHit, Start, End, FCollisionObjectQueryParams(FCollisionObjectQueryParams::AllDynamicObjects), CollisionParams); return Success && OutHit.bBlockingHit; }
FHitResult UGrabber::FindTheFirstReachingObject() { // Get the viewport GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(ViewPortLocation, ViewPortRotation); //UE_LOG(LogTemp, Warning, TEXT("Location: %s, Rotation: %s"), *ViewPortLocation.ToString(), *ViewPortRotation.ToString()); // Calculate of the endpoint of debug line EndPointOfLine = ViewPortLocation + ViewPortRotation.Vector() * LineReach; // Draw the debug line DrawDebugLine( GetWorld(), ViewPortLocation, EndPointOfLine, FColor(255.0f, 0.0f, 0.0f), false, 0.0f, 0.0f, 10.0f ); // The variable store the hit result info FHitResult HitResInfo; // Some settings of the line tracing FCollisionQueryParams CollisionParams(FName(TEXT("")), false, GetOwner()); // Do the line tracing GetWorld()->LineTraceSingleByObjectType( HitResInfo, ViewPortLocation, EndPointOfLine, FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody), CollisionParams ); // Log the result of the line tracing AActor* HitActor = HitResInfo.GetActor(); if (HitActor) { UE_LOG(LogTemp, Warning, TEXT("The hitting object's name is: %s"), *(HitActor->GetName())); } return HitResInfo; }
bool AAIController::LineOfSightTo(const AActor* Other, FVector ViewPoint, bool bAlternateChecks) const { if (Other == nullptr) { return false; } if (ViewPoint.IsZero()) { FRotator ViewRotation; GetActorEyesViewPoint(ViewPoint, ViewRotation); // if we still don't have a view point we simply fail if (ViewPoint.IsZero()) { return false; } } static FName NAME_LineOfSight = FName(TEXT("LineOfSight")); FVector TargetLocation = Other->GetTargetLocation(GetPawn()); FCollisionQueryParams CollisionParams(NAME_LineOfSight, true, this->GetPawn()); CollisionParams.AddIgnoredActor(Other); bool bHit = GetWorld()->LineTraceTestByChannel(ViewPoint, TargetLocation, ECC_Visibility, CollisionParams); if (!bHit) { return true; } // if other isn't using a cylinder for collision and isn't a Pawn (which already requires an accurate cylinder for AI) // then don't go any further as it likely will not be tracing to the correct location const APawn * OtherPawn = Cast<const APawn>(Other); if (!OtherPawn && Cast<UCapsuleComponent>(Other->GetRootComponent()) == NULL) { return false; } const FVector OtherActorLocation = Other->GetActorLocation(); const float DistSq = (OtherActorLocation - ViewPoint).SizeSquared(); if (DistSq > FARSIGHTTHRESHOLDSQUARED) { return false; } if (!OtherPawn && (DistSq > NEARSIGHTTHRESHOLDSQUARED)) { return false; } float OtherRadius, OtherHeight; Other->GetSimpleCollisionCylinder(OtherRadius, OtherHeight); if (!bAlternateChecks || !bLOSflag) { //try viewpoint to head bHit = GetWorld()->LineTraceTestByChannel(ViewPoint, OtherActorLocation + FVector(0.f, 0.f, OtherHeight), ECC_Visibility, CollisionParams); if (!bHit) { return true; } } if (!bSkipExtraLOSChecks && (!bAlternateChecks || bLOSflag)) { // only check sides if width of other is significant compared to distance if (OtherRadius * OtherRadius / (OtherActorLocation - ViewPoint).SizeSquared() < 0.0001f) { return false; } //try checking sides - look at dist to four side points, and cull furthest and closest FVector Points[4]; Points[0] = OtherActorLocation - FVector(OtherRadius, -1 * OtherRadius, 0); Points[1] = OtherActorLocation + FVector(OtherRadius, OtherRadius, 0); Points[2] = OtherActorLocation - FVector(OtherRadius, OtherRadius, 0); Points[3] = OtherActorLocation + FVector(OtherRadius, -1 * OtherRadius, 0); int32 IndexMin = 0; int32 IndexMax = 0; float CurrentMax = (Points[0] - ViewPoint).SizeSquared(); float CurrentMin = CurrentMax; for (int32 PointIndex = 1; PointIndex<4; PointIndex++) { const float NextSize = (Points[PointIndex] - ViewPoint).SizeSquared(); if (NextSize > CurrentMin) { CurrentMin = NextSize; IndexMax = PointIndex; } else if (NextSize < CurrentMax) { CurrentMax = NextSize; IndexMin = PointIndex; } } for (int32 PointIndex = 0; PointIndex<4; PointIndex++) { if ((PointIndex != IndexMin) && (PointIndex != IndexMax)) { bHit = GetWorld()->LineTraceTestByChannel(ViewPoint, Points[PointIndex], ECC_Visibility, CollisionParams); if (!bHit) { return true; } } } } return false; }
bool AAIController::LineOfSightTo(const AActor* Other, FVector ViewPoint, bool bAlternateChecks) { if( !Other ) { return false; } if ( ViewPoint.IsZero() ) { AActor* ViewTarg = GetViewTarget(); ViewPoint = ViewTarg->GetActorLocation(); if( ViewTarg == GetPawn() ) { ViewPoint.Z += GetPawn()->BaseEyeHeight; //look from eyes } } static FName NAME_LineOfSight = FName(TEXT("LineOfSight")); FVector TargetLocation = Other->GetTargetLocation(GetPawn()); FCollisionQueryParams CollisionParams(NAME_LineOfSight, true, this->GetPawn()); CollisionParams.AddIgnoredActor(Other); bool bHit = GetWorld()->LineTraceTest(ViewPoint, TargetLocation, ECC_Visibility, CollisionParams); if( !bHit ) { return true; } // if other isn't using a cylinder for collision and isn't a Pawn (which already requires an accurate cylinder for AI) // then don't go any further as it likely will not be tracing to the correct location const APawn * OtherPawn = Cast<const APawn>(Other); if (!OtherPawn && Cast<UCapsuleComponent>(Other->GetRootComponent()) == NULL) { return false; } const FVector OtherActorLocation = Other->GetActorLocation(); float distSq = (OtherActorLocation - ViewPoint).SizeSquared(); if ( distSq > FARSIGHTTHRESHOLDSQUARED ) { return false; } if ( !OtherPawn && (distSq > NEARSIGHTTHRESHOLDSQUARED) ) { return false; } float OtherRadius, OtherHeight; Other->GetSimpleCollisionCylinder(OtherRadius, OtherHeight); if ( !bAlternateChecks || !bLOSflag ) { //try viewpoint to head bHit = GetWorld()->LineTraceTest(ViewPoint, OtherActorLocation + FVector(0.f,0.f,OtherHeight), ECC_Visibility, CollisionParams); if ( !bHit ) { return true; } } if( !bSkipExtraLOSChecks && (!bAlternateChecks || bLOSflag) ) { // only check sides if width of other is significant compared to distance if( OtherRadius * OtherRadius/(OtherActorLocation - ViewPoint).SizeSquared() < 0.0001f ) { return false; } //try checking sides - look at dist to four side points, and cull furthest and closest FVector Points[4]; Points[0] = OtherActorLocation - FVector(OtherRadius, -1 * OtherRadius, 0); Points[1] = OtherActorLocation + FVector(OtherRadius, OtherRadius, 0); Points[2] = OtherActorLocation - FVector(OtherRadius, OtherRadius, 0); Points[3] = OtherActorLocation + FVector(OtherRadius, -1 * OtherRadius, 0); int32 imin = 0; int32 imax = 0; float currentmin = (Points[0] - ViewPoint).SizeSquared(); float currentmax = currentmin; for ( int32 i=1; i<4; i++ ) { float nextsize = (Points[i] - ViewPoint).SizeSquared(); if (nextsize > currentmax) { currentmax = nextsize; imax = i; } else if (nextsize < currentmin) { currentmin = nextsize; imin = i; } } for ( int32 i=0; i<4; i++ ) { if ( (i != imin) && (i != imax) ) { bHit = GetWorld()->LineTraceTest(ViewPoint, Points[i], ECC_Visibility, CollisionParams); if ( !bHit ) { return true; } } } } return false; }