FVector ABaseController::GetHitPosition()
{
	FNavLocation location;
	UNavigationSystem* navSys = UNavigationSystem::GetCurrent(World);
	navSys->GetRandomPointInNavigableRadius(AttackLocation, 200.f, location);
	return location.Location;
}
FVector ABaseController::GetNewWanderPosition()
{
	FNavLocation Location;
	UNavigationSystem* NavSys = World->GetNavigationSystem();

	FHitResult hit(ForceInit);
	FCollisionQueryParams traceParams = FCollisionQueryParams(FName(TEXT("RV_Trace")), true, Self);
	traceParams.bTraceComplex = true;
	traceParams.bTraceAsyncScene = true;

	int times = 0;
	float minimuimDist = Self->MinimuimDistanceBetweenWanderLocations;

	do{
		if (times >= 50)
		{
			times = 0;
			minimuimDist -= 500.f;
		}

		times++;
		NavSys->GetRandomPointInNavigableRadius(Self->GetActorLocation(), Self->SightRange, Location);
	} while (FVector::Dist(Location.Location, Self->GetActorLocation()) < minimuimDist);

	bool bHit = World->LineTraceSingleByChannel(hit, Self->EyeLocation, Location.Location, ECC_Visibility, traceParams);

	return Location.Location;
}
FVector ABaseController::GetNewSearchPosition()
{
	FNavLocation Location;
	UNavigationSystem* NavSys = World->GetNavigationSystem();
	NavSys->GetRandomPointInNavigableRadius(TargetsLastKnownPosition, Self->SearchRange, Location);
	return Location.Location;
}
void ANavLinkProxy::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) 
{
	bool bUpdateInNavOctree = false;
	if (PropertyChangedEvent.Property && PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(ANavLinkProxy, bSmartLinkIsRelevant))
	{
		SmartLinkComp->SetNavigationRelevancy(bSmartLinkIsRelevant);
		bUpdateInNavOctree = true;
	}

	const FName CategoryName = FObjectEditorUtils::GetCategoryFName(PropertyChangedEvent.Property);
	const FName MemberCategoryName = FObjectEditorUtils::GetCategoryFName(PropertyChangedEvent.MemberProperty);
	if (CategoryName == TEXT("SimpleLink") || MemberCategoryName == TEXT("SimpleLink"))
	{
		bUpdateInNavOctree = true;
	}

	if (bUpdateInNavOctree)
	{
		UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
		if (NavSys)
		{
			NavSys->UpdateActorInNavOctree(*this);
		}
	}

	Super::PostEditChangeProperty(PropertyChangedEvent);
}
Esempio n. 5
0
FAIRequestID AAIController::RequestPathAndMove(FPathFindingQuery& Query, AActor* Goal, float AcceptanceRadius, bool bStopOnOverlap, FCustomMoveSharedPtr CustomData)
{
	FAIRequestID RequestID;

	UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
	if (NavSys)
	{
		FPathFindingResult PathResult = NavSys->FindPathSync(Query);
		if (PathResult.Result != ENavigationQueryResult::Error)
		{
			if (PathResult.IsSuccessful() && PathResult.Path.IsValid())
			{
				if (Goal)
				{
					PathResult.Path->SetGoalActorObservation(*Goal, 100.0f);
				}

				PathResult.Path->EnableRecalculationOnInvalidation(true);
			}

			RequestID = RequestMove(PathResult.Path, Goal, AcceptanceRadius, bStopOnOverlap, CustomData);
		}
		else
		{
			UE_VLOG(this, LogBehaviorTree, Error, TEXT("Trying to find path to %s resulted in Error"), *GetNameSafe(Goal));
		}
	}

	return RequestID;
}
FORCENOINLINE
#endif // NAVSYS_DEBUG
void FNavigationOctreeSemantics::SetElementId(const FNavigationOctreeElement& Element, FOctreeElementId Id)
{
	UWorld* World = NULL;
	UObject* ElementOwner = Element.GetOwner();

	if (AActor* Actor = Cast<AActor>(ElementOwner))
	{
		World = Actor->GetWorld();
	}
	else if (UActorComponent* AC = Cast<UActorComponent>(ElementOwner))
	{
		World = AC->GetWorld();
	}
	else if (ULevel* Level = Cast<ULevel>(ElementOwner))
	{
		World = Level->OwningWorld;
	}

	UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(World);
	if (NavSys)
	{
		NavSys->SetObjectsNavOctreeId(ElementOwner, Id);
	}
}
Esempio n. 7
0
FAIRequestID AAIController::RequestPathAndMove(const FAIMoveRequest& MoveRequest, FPathFindingQuery& Query)
{
	FAIRequestID RequestID;

	UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
	if (NavSys)
	{
		FPathFindingResult PathResult = NavSys->FindPathSync(Query);
		if (PathResult.Result != ENavigationQueryResult::Error)
		{
			if (PathResult.IsSuccessful() && PathResult.Path.IsValid())
			{
				if (MoveRequest.IsUsingPathfinding())
				{
					if (MoveRequest.HasGoalActor())
					{
						PathResult.Path->SetGoalActorObservation(*MoveRequest.GetGoalActor(), 100.0f);
					}

					PathResult.Path->EnableRecalculationOnInvalidation(true);
				}

				RequestID = RequestMove(MoveRequest, PathResult.Path);
			}
		}
		else
		{
			UE_VLOG(this, LogAINavigation, Error, TEXT("Trying to find path to %s resulted in Error"), *GetNameSafe(MoveRequest.GetGoalActor()));
		}
	}

	return RequestID;
}
void AAIController::FindPathForMoveRequest(const FAIMoveRequest& MoveRequest, FPathFindingQuery& Query, FNavPathSharedPtr& OutPath) const
{
    SCOPE_CYCLE_COUNTER(STAT_AI_Overall);

    UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
    if (NavSys)
    {
        FPathFindingResult PathResult = NavSys->FindPathSync(Query);
        if (PathResult.Result != ENavigationQueryResult::Error)
        {
            if (PathResult.IsSuccessful() && PathResult.Path.IsValid())
            {
                if (MoveRequest.IsMoveToActorRequest())
                {
                    PathResult.Path->SetGoalActorObservation(*MoveRequest.GetGoalActor(), 100.0f);
                }

                PathResult.Path->EnableRecalculationOnInvalidation(true);
                OutPath = PathResult.Path;
            }
        }
        else
        {
            UE_VLOG(this, LogAINavigation, Error, TEXT("Trying to find path to %s resulted in Error")
                    , MoveRequest.IsMoveToActorRequest() ? *GetNameSafe(MoveRequest.GetGoalActor()) : *MoveRequest.GetGoalLocation().ToString());
            UE_VLOG_SEGMENT(this, LogAINavigation, Error, GetPawn() ? GetPawn()->GetActorLocation() : FAISystem::InvalidLocation
                            , MoveRequest.GetGoalLocation(), FColor::Red, TEXT("Failed move to %s"), *GetNameSafe(MoveRequest.GetGoalActor()));
        }
    }
}
Esempio n. 9
0
void UCheatManager::RebuildNavigation()
{
	UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
	if (NavSys)
	{
		NavSys->Build();
	}
}
void UNavLinkCustomComponent::SetDisabledArea(TSubclassOf<UNavArea> AreaClass)
{
	DisabledAreaClass = AreaClass;
	if (IsNavigationRelevant() && !bLinkEnabled && GetWorld() != nullptr )
	{
		UNavigationSystem* NavSys = GetWorld()->GetNavigationSystem();
		NavSys->UpdateCustomLink(this);
	}
}
// execution
EBTNodeResult::Type UAIE_GoToRandom_BTTaskNode::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) {
	/*	call super 
	 *	should aquire refrences for our BehaviorTreeComp, BlackboardComp, AIController, and BotCharacter
	 *	will return EBTNodeResult::Succeeded if we have all of them
	 *	will return EBTNodeResult::Failed if it failed to grab any of them
	*/
	EBTNodeResult::Type resultFromSuperExecution = Super::ExecuteTask(OwnerComp, NodeMemory);
	// check that we successfully grabbed the BehaviorTreeComp, BlackboardComp, AIController, and BotCharacter
	if (resultFromSuperExecution == EBTNodeResult::Succeeded) {
		// check that we can get the World
		if (GetWorld()) {
			// get the current nav system from the world
			UNavigationSystem* navSystem = UNavigationSystem::GetCurrent(GetWorld());
			// check that we have a nav system
			if (navSystem) {
				// get our actors current location to pe used as our start position
				FVector startPosi = BotCharacter->GetActorLocation();
				// create a nav location to be used as our end position 
				// default will be set to our current position in case of failure to find a suitable end position
				FNavLocation endPosi = FNavLocation(startPosi);
				// attempt to get a random new position
				if (navSystem->GetRandomReachablePointInRadius(startPosi, searchRadius, endPosi)) {
					// if we were successfull in finding a new location get the MoveToLocation BlackboardKeyID
					FBlackboard::FKey BlackboardKey_MoveToLocation = Blackboard->GetKeyID("MoveToLocation");
					// check that we got the key
					if ( Blackboard->IsValidKey( BlackboardKey_MoveToLocation)) {
						// set the MoveToLocation BlackboardKeyID to our new location
						Blackboard->SetValue<UBlackboardKeyType_Vector>(BlackboardKey_MoveToLocation, endPosi.Location);
						// return succeeded now that we have set up our new loacation
						return EBTNodeResult::Succeeded;
					}
					else {
						// return Aborted if we can't find the Key as it will never succeed without a proper Key
						if (bForceSuccess) {
							return EBTNodeResult::Succeeded;
						}
						return EBTNodeResult::Aborted;
					}
				}
				// return in progress if their are currently no valid locations
				if (bForceSuccess) {
					return EBTNodeResult::Succeeded;
				}
				return EBTNodeResult::InProgress;
			}
		}
		 
		
	}
	// we will only get here if execution fails so we will check if force success is on
	if (bForceSuccess) {
		// if force success is on we will return Succeeded anyway
		return EBTNodeResult::Succeeded;
	}
	// we want to return Failed after the force success check
	return EBTNodeResult::Failed;
}
void USmartNavLinkComponent::SetDisabledArea(TSubclassOf<class UNavArea> AreaClass)
{
	DisabledAreaClass = AreaClass;
	if (IsNavigationRelevant() && !bLinkEnabled)
	{
		UNavigationSystem* NavSys = GetWorld()->GetNavigationSystem();
		NavSys->UpdateSmartLink(this);
	}
}
void UNavLinkCustomComponent::SetEnabledArea(TSubclassOf<class UNavArea> AreaClass)
{
	EnabledAreaClass = AreaClass;
	if (IsNavigationRelevant() && bLinkEnabled)
	{
		UNavigationSystem* NavSys = GetWorld()->GetNavigationSystem();
		NavSys->UpdateCustomLink(this);
	}
}
bool UGameplayDebuggingComponent::ServerCollectNavmeshData_Validate(FVector_NetQuantize10 TargetLocation)
{
    bool bIsValid = false;
#if WITH_RECAST
    UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
    bIsValid = NavSys && NavSys->GetMainNavData(FNavigationSystem::DontCreate);
#endif

    return bIsValid;
}
void USmartNavLinkComponent::OnOwnerUnregistered()
{
	if (GetOwner() == NULL || GetWorld() == NULL || GetWorld()->GetNavigationSystem() == NULL)
	{
		return;
	}

	// always try to unregister, even if not relevant right now
	UNavigationSystem* NavSys = GetWorld()->GetNavigationSystem();
	NavSys->UnregisterSmartLink(this);
}
void ANavigationTestingActor::SearchPathTo(ANavigationTestingActor* Goal)
{
#if WITH_EDITORONLY_DATA
	if (EdRenderComp)
	{
		EdRenderComp->MarkRenderStateDirty();
	}
#endif // WITH_EDITORONLY_DATA

	if (Goal == NULL) 
	{
		return;
	}

	UNavigationSystem* NavSys = GetWorld()->GetNavigationSystem();
	check(NavSys);

	const double StartTime = FPlatformTime::Seconds();

	FPathFindingQuery Query = BuildPathFindingQuery(Goal);
	EPathFindingMode::Type Mode = bUseHierarchicalPathfinding ? EPathFindingMode::Hierarchical : EPathFindingMode::Regular;
	FPathFindingResult Result = NavSys->FindPathSync(NavAgentProps, Query, Mode);

	const double EndTime = FPlatformTime::Seconds();
	const float Duration = (EndTime - StartTime);
	PathfindingTime = Duration * 1000000.0f;			// in micro seconds [us]
	bPathIsPartial = Result.IsPartial();
	bPathExist = Result.IsSuccessful();
	bPathSearchOutOfNodes = bPathExist ? Result.Path->DidSearchReachedLimit() : false;
	LastPath = Result.Path;
	PathCost = bPathExist ? Result.Path->GetCost() : 0.0f;

	if (bPathExist)
	{
		LastPath->AddObserver(PathObserver);

		if (OffsetFromCornersDistance > 0.0f)
		{
			((FNavMeshPath*)LastPath.Get())->OffsetFromCorners(OffsetFromCornersDistance);
		}
	}

#if WITH_RECAST && WITH_EDITORONLY_DATA
	if (bGatherDetailedInfo && !bUseHierarchicalPathfinding)
	{
		ARecastNavMesh* RecastNavMesh = Cast<ARecastNavMesh>(MyNavData);
		if (RecastNavMesh && RecastNavMesh->HasValidNavmesh())
		{
			PathfindingSteps = RecastNavMesh->DebugPathfinding(Query, DebugSteps);
		}
	}
#endif
}
void ANavMeshBoundsVolume::PostLoad()
{
	Super::PostLoad();

#if WITH_NAVIGATION_GENERATOR
	UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
	if (NavSys && Role == ROLE_Authority)
	{
		NavSys->OnNavigationBoundsUpdated(this);
	}
#endif
}
void UNavLinkCustomComponent::OnUnregister()
{
	Super::OnUnregister();

	UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
	if (NavSys == NULL)
	{
		return;
	}

	// always try to unregister, even if not relevant right now
	NavSys->UnregisterCustomLink(this);
}
void ANavigationTestingActor::TickMe()
{
	UNavigationSystem* NavSys = GetWorld() ? GetWorld()->GetNavigationSystem() : NULL;
	if (NavSys && !NavSys->IsNavigationBuildInProgress())
	{
#if WITH_RECAST && WITH_EDITORONLY_DATA
		delete TickHelper;
		TickHelper = NULL;
#endif

		UpdatePathfinding();
	}
}
Esempio n. 20
0
void UNavigationQueryFilter::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
    Super::PostEditChangeProperty(PropertyChangedEvent);

    // remove cached filter settings from existing NavigationSystems
    for (const FWorldContext& Context : GEngine->GetWorldContexts())
    {
        UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(Context.World());
        if (NavSys)
        {
            NavSys->ResetCachedFilter(GetClass());
        }
    }
}
void USmartNavLinkComponent::OnOwnerRegistered()
{
	if (GetOwner() == NULL || GetWorld() == NULL || GetWorld()->GetNavigationSystem() == NULL)
	{
		return;
	}

	UNavigationSystem* NavSys = GetWorld()->GetNavigationSystem();
	if (NavLinkUserId == 0)
	{
		NavLinkUserId = NavSys->FindFreeSmartLinkId();
	}

	NavSys->RegisterSmartLink(this);
}
void ANavMeshBoundsVolume::PostEditChangeProperty( struct FPropertyChangedEvent& PropertyChangedEvent)
{
	Super::PostEditChangeProperty(PropertyChangedEvent);

#if WITH_NAVIGATION_GENERATOR
	UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
	if (GIsEditor && NavSys)
	{
		if (PropertyChangedEvent.Property == NULL ||
			PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(ABrush, BrushBuilder))
		{
			NavSys->OnNavigationBoundsUpdated(this);
		}
	}
#endif // WITH_NAVIGATION_GENERATOR
}
Esempio n. 23
0
EBTNodeResult::Type UATBTTask_MoveArea::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
	UNavigationSystem* NavigationSystem = UNavigationSystem::GetCurrent(GetWorld());
	AATCharacterAI* MyCharacter = Cast<AATCharacterAI>(OwnerComp.GetAIOwner()->GetPawn());

	if (NavigationSystem != nullptr && MyCharacter != nullptr)
	{
		FNavLocation RandomPointIn;
		if (NavigationSystem->GetRandomPointInNavigableRadius(MyCharacter->GetActorLocation(), MyCharacter->AreaRadius, RandomPointIn))
		{
			OwnerComp.GetBlackboardComponent()->SetValue<UBlackboardKeyType_Vector>(GetSelectedBlackboardKey(), RandomPointIn.Location);
			return EBTNodeResult::Succeeded;
		}
	}
	return EBTNodeResult::Failed;
}
void UNavMovementComponent::UpdateNavAgent(const UCapsuleComponent& CapsuleComponent)
{
	if (ShouldUpdateNavAgentWithOwnersCollision() == false)
	{
		return;
	}

	// initialize properties from navigation system
	UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
	if (NavSys != nullptr)
	{
		NavAgentProps.NavWalkingSearchHeightScale = NavSys->GetDefaultSupportedAgentConfig().NavWalkingSearchHeightScale;
	}

	NavAgentProps.AgentRadius = CapsuleComponent.GetScaledCapsuleRadius();
	NavAgentProps.AgentHeight = CapsuleComponent.GetScaledCapsuleHalfHeight() * 2.f;
}
void UNavLinkCustomComponent::OnRegister()
{
	Super::OnRegister();

	UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
	if (NavSys == NULL)
	{
		return;
	}

	if (NavLinkUserId == 0)
	{
		NavLinkUserId = INavLinkCustomInterface::GetUniqueId();
	}

	NavSys->RegisterCustomLink(this);
}
void FGameplayDebuggerCategory_Navmesh::CollectData(APlayerController* OwnerPC, AActor* DebugActor)
{
#if WITH_RECAST
	ARecastNavMesh* NavData = nullptr;

	APawn* PlayerPawn = OwnerPC ? OwnerPC->GetPawnOrSpectator() : nullptr;
	APawn* DebugActorAsPawn = Cast<APawn>(DebugActor);
	APawn* DestPawn = DebugActorAsPawn ? DebugActorAsPawn : PlayerPawn;
	if (DestPawn)
	{
		UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(OwnerPC->GetWorld());
		const FNavAgentProperties& NavAgentProperties = DestPawn->GetNavAgentPropertiesRef();
		NavData = Cast<ARecastNavMesh>(NavSys->GetNavDataForProps(NavAgentProperties));
	}

	if (NavData)
	{
		// add 3x3 neighborhood of target
		const FVector TargetLocation = DestPawn->GetActorLocation();

		TArray<int32> TileSet;
		int32 TileX = 0;
		int32 TileY = 0;
		const int32 DeltaX[] = { 0, 1, 1, 0, -1, -1, -1, 0, 1 };
		const int32 DeltaY[] = { 0, 0, 1, 1, 1, 0, -1, -1, -1 };

		int32 TargetTileX = 0;
		int32 TargetTileY = 0;
		NavData->GetNavMeshTileXY(TargetLocation, TargetTileX, TargetTileY);
		for (int32 Idx = 0; Idx < ARRAY_COUNT(DeltaX); Idx++)
		{
			const int32 NeiX = TargetTileX + DeltaX[Idx];
			const int32 NeiY = TargetTileY + DeltaY[Idx];
			NavData->GetNavMeshTilesAt(NeiX, NeiY, TileSet);
		}

		const int32 DetailFlags =
			(1 << static_cast<int32>(ENavMeshDetailFlags::PolyEdges)) |
			(1 << static_cast<int32>(ENavMeshDetailFlags::FilledPolys)) |
			(1 << static_cast<int32>(ENavMeshDetailFlags::NavLinks));

		NavmeshRenderData.GatherData(NavData, DetailFlags, TileSet);
	}
#endif // WITH_RECAST
}
bool AAIController::BuildPathfindingQuery(const FAIMoveRequest& MoveRequest, FPathFindingQuery& Query) const
{
    bool bResult = false;

    UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
    const ANavigationData* NavData = (NavSys == nullptr) ? nullptr :
                                     MoveRequest.IsUsingPathfinding() ? NavSys->GetNavDataForProps(GetNavAgentPropertiesRef()) :
                                     NavSys->GetAbstractNavData();

    if (NavData)
    {
        FVector GoalLocation = MoveRequest.GetGoalLocation();
        if (MoveRequest.IsMoveToActorRequest())
        {
            const INavAgentInterface* NavGoal = Cast<const INavAgentInterface>(MoveRequest.GetGoalActor());
            if (NavGoal)
            {
                const FVector Offset = NavGoal->GetMoveGoalOffset(this);
                GoalLocation = FQuatRotationTranslationMatrix(MoveRequest.GetGoalActor()->GetActorQuat(), NavGoal->GetNavAgentLocation()).TransformPosition(Offset);
            }
            else
            {
                GoalLocation = MoveRequest.GetGoalActor()->GetActorLocation();
            }
        }

        FSharedConstNavQueryFilter NavFilter = UNavigationQueryFilter::GetQueryFilter(*NavData, this, MoveRequest.GetNavigationFilter());
        Query = FPathFindingQuery(*this, *NavData, GetNavAgentLocation(), GoalLocation, NavFilter);
        Query.SetAllowPartialPaths(MoveRequest.IsUsingPartialPaths());

        if (PathFollowingComponent)
        {
            PathFollowingComponent->OnPathfindingQuery(Query);
        }

        bResult = true;
    }
    else
    {
        UE_VLOG(this, LogAINavigation, Warning, TEXT("Unable to find NavigationData instance while calling AAIController::BuildPathfindingQuery"));
    }

    return bResult;
}
void UNavigationInvokerComponent::RegisterWithNavigationSystem(UNavigationSystem& NavSys)
{
	if (IsActive())
	{
		AActor* Owner = GetOwner();
		if (Owner)
		{
			NavSys.RegisterInvoker(*Owner, TileGenerationRadius, TileRemovalRadius);
		}
	}
}
void UNavigationComponent::OnSmartLinkBroadcast(class USmartNavLinkComponent* NearbyLink)
{
	// update only when agent is actually moving
	if (NearbyLink == NULL || !Path.IsValid() ||
		PathFollowComp == NULL || PathFollowComp->GetStatus() == EPathFollowingStatus::Idle)
	{
		return;
	}

	UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
	if (NavSys == NULL || MyNavAgent == NULL || GetNavData() == NULL)
	{
		return;
	}

	const bool bHasLink = Path->ContainsSmartLink(NearbyLink);
	const bool bIsEnabled = NearbyLink->IsEnabled();
	if (bIsEnabled == bHasLink)
	{
		// enabled link, path already use it - or - disabled link and path it's not using it
		return;
	}

	const FVector GoalLocation = Path->PathPoints.Last().Location;

	FPathFindingResult Result = NavSys->FindPathSync(*MyNavAgent->GetNavAgentProperties(),
		FPathFindingQuery(GetNavData(), MyNavAgent->GetNavAgentLocation(), GoalLocation, StoredQueryFilter),
		bDoHierarchicalPathfinding ? EPathFindingMode::Hierarchical : EPathFindingMode::Regular);

	if (Result.IsSuccessful() || Result.IsPartial())
	{
		const bool bNewHasLink = Result.Path->ContainsSmartLink(NearbyLink);

		if ((bIsEnabled && !bHasLink && bNewHasLink) ||
			(!bIsEnabled && bHasLink && !bNewHasLink))
		{			
			SetPath(Result.Path);
			NotifyPathUpdate();
		}
	}
}
void UNavMovementComponent::UpdateNavAgent(const AActor& Owner)
{
	ensure(&Owner == GetOwner());
	if (ShouldUpdateNavAgentWithOwnersCollision() == false)
	{
		return;
	}

	// initialize properties from navigation system
	UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
	if (NavSys != nullptr)
	{
		NavAgentProps.NavWalkingSearchHeightScale = NavSys->GetDefaultSupportedAgentConfig().NavWalkingSearchHeightScale;
	}

	// Can't call GetSimpleCollisionCylinder(), because no components will be registered.
	float BoundRadius, BoundHalfHeight;	
	Owner.GetSimpleCollisionCylinder(BoundRadius, BoundHalfHeight);
	NavAgentProps.AgentRadius = BoundRadius;
	NavAgentProps.AgentHeight = BoundHalfHeight * 2.f;
}