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); } } }
void UOrionPathFollowingComponent::FollowPathSegment(float DeltaTime) { if (Controller && Controller->GetPawn()) { /*AOrionDinoPawn *Dino = Cast<AOrionDinoPawn>(Controller->GetPawn()); if (Dino && Dino->bShouldStopMovement) { Dino->bShouldStopMovement = false; OnPathFinished(EPathFollowingResult::Success); return; }*/ AOrionCharacter *Pawn = Cast<AOrionCharacter>(Controller->GetPawn()); if (Pawn && Pawn->IsFlying()) { if (Controller->bFinishedPath) OnPathFinished(EPathFollowingResult::Success); if (MovementComp == NULL)//|| !Path.IsValid()) { return; } float dist = (Pawn->GetActorLocation() - GetCurrentTargetFlyingLocation()).Size(); if (dist < (Pawn->bLanding ? Pawn->GetCapsuleComponent()->GetScaledCapsuleHalfHeight() + 10.0f : Pawn->FlyingOffset)) { if (Pawn->bLanding) { Controller->bFinishedLanding = true; OnPathFinished(EPathFollowingResult::Success); } else { Controller->FlightIndex++; if (Controller->FlightIndex >= Controller->FlightPath.Num()) { Controller->bFinishedPath = true; OnPathFinished(EPathFollowingResult::Success); } } } else if (Controller->FlightIndex + 1 >= Controller->FlightPath.Num() && dist < 2.5f * (Pawn->bLanding ? Pawn->GetCapsuleComponent()->GetScaledCapsuleHalfHeight() + 10.0f : Pawn->FlyingOffset) && (Controller->GetEnemy() == nullptr || (Controller->GetEnemy()->GetActorLocation() - Controller->FlightPath.Last()).Size() > 100.0f)) { Controller->bFinishedPath = true; OnPathFinished(EPathFollowingResult::Success); } CharacterMoveComp->SetMovementMode(MOVE_Flying); //const FVector CurrentLocation = MovementComp->IsMovingOnGround() ? MovementComp->GetActorFeetLocation() : MovementComp->GetActorLocation(); const FVector CurrentLocation = MovementComp->GetActorFeetLocation(); const FVector CurrentTarget = GetCurrentTargetFlyingLocation(); FVector MoveVelocity = (CurrentTarget - CurrentLocation) / DeltaTime; ////const int32 LastSegmentStartIndex = Path->GetPathPoints().Num() - 2; ////const bool bNotFollowingLastSegment = (MoveSegmentStartIndex < LastSegmentStartIndex); PostProcessMove.ExecuteIfBound(this, MoveVelocity); MovementComp->RequestDirectMove(MoveVelocity, false);// true);// bNotFollowingLastSegment); return; } } if (MovementComp == NULL || !Path.IsValid()) return; //if we need to play a rotate animation before we actually move, do that now if (HandleRotation()) return; /*if (Path->IsPartial()) { if (Controller && Controller->GetPawn()) { AOrionCharacter *Pawn = Cast<AOrionCharacter>(Controller->GetPawn()); if (Pawn) { Pawn->Jump(); } } return; }*/ if (CharacterMoveComp->MovementMode == MOVE_Flying) CharacterMoveComp->SetMovementMode(MOVE_Walking); Super::FollowPathSegment(DeltaTime); }