void UVehiclePathFollowingComponent::UpdatePathSegment() { #ifdef NDEBUG if (Path.IsValid()) { for (int i = 0; i < Path->GetPathPoints().Num(); ++i) { DrawDebugPoint(GetWorld(), Path->GetPathPoints()[i].Location, 40.0f, FColor::Yellow, false, 0.3f); } } #endif float DistanceLeft = ( *Path->GetPathPointLocation(Path->GetPathPoints().Num() - 1) - MovementComp->GetActorLocation() ).Size(); if (DistanceLeft < AcceptanceRadius) { OnSegmentFinished(); OnPathFinished(EPathFollowingResult::Success); } UPathFollowingComponent::UpdatePathSegment(); }
void UCrowdFollowingComponent::UpdatePathSegment() { if (!bEnableCrowdSimulation) { Super::UpdatePathSegment(); return; } if (!Path.IsValid() || MovementComp == NULL) { AbortMove(TEXT("no path"), FAIRequestID::CurrentRequest, true, false, EPathFollowingMessage::NoPath); return; } if (!Path->IsValid()) { if (!Path->IsWaitingForRepath()) { AbortMove(TEXT("no path"), FAIRequestID::CurrentRequest, true, false, EPathFollowingMessage::NoPath); } return; } // if agent has control over its movement, check finish conditions const bool bCanReachTarget = MovementComp->CanStopPathFollowing(); if (bCanReachTarget && Status == EPathFollowingStatus::Moving) { const FVector CurrentLocation = MovementComp->GetActorFeetLocation(); const FVector GoalLocation = GetCurrentTargetLocation(); if (bCollidedWithGoal) { // check if collided with goal actor OnSegmentFinished(); OnPathFinished(EPathFollowingResult::Success); } else if (bFinalPathPart) { const FVector ToTarget = (GoalLocation - MovementComp->GetActorFeetLocation()); const bool bDirectPath = Path->CastPath<FAbstractNavigationPath>() != NULL; const float SegmentDot = FVector::DotProduct(ToTarget, bDirectPath ? MovementComp->Velocity : CrowdAgentMoveDirection); const bool bMovedTooFar = bCheckMovementAngle && (SegmentDot < 0.0); // can't use HasReachedDestination here, because it will use last path point // which is not set correctly for partial paths without string pulling if (bMovedTooFar || HasReachedInternal(GoalLocation, 0.0f, 0.0f, CurrentLocation, AcceptanceRadius, bStopOnOverlap ? MinAgentRadiusPct : 0.0f)) { UE_VLOG(GetOwner(), LogCrowdFollowing, Log, TEXT("Last path segment finished due to \'%s\'"), bMovedTooFar ? TEXT("Missing Last Point") : TEXT("Reaching Destination")); OnPathFinished(EPathFollowingResult::Success); } } else { // override radius multiplier and switch to next path part when closer than 4x agent radius const float NextPartMultiplier = 4.0f; const bool bHasReached = HasReachedInternal(GoalLocation, 0.0f, 0.0f, CurrentLocation, 0.0f, NextPartMultiplier); if (bHasReached) { SwitchToNextPathPart(); } } } // gather location samples to detect if moving agent is blocked if (bCanReachTarget && Status == EPathFollowingStatus::Moving) { const bool bHasNewSample = UpdateBlockDetection(); if (bHasNewSample && IsBlocked()) { OnPathFinished(EPathFollowingResult::Blocked); } } }