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();
}
コード例 #2
0
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);
		}
	}
}