Description

Context

Recast lets you configure multiple agent types in Project Settings > Navigation System > Supported Agents. When agents have unique settings such as agent radius, building a nav mesh results in multiple nav meshes contained in the level as separate Recast-AgentName actors.

Problem

After changing agent settings, the next time nav meshes are built new Recast actors are created for the new agent configurations. Recast actors targeting agent configurations that no longer exist should be cleaned up. Currently this happens when the map is loaded in editor or at runtime, by UNavigationSystem::ProcessRegistrationCandidates() destroying obsolote Recast actors.

However for maps with one-file-per-actor enabled (World Settings > Use External Actors): this does not result in the external actor asset being deleted even when the map is saved. That obsolete Recast actor will keep getting loaded at editor or game runtime and then being deleted in the session. Ideally the asset is deleted from the file system once the level is saved.

Suggestion

Deleting the obsolete Recast actor requires that its external actor package is found and marked for cleanup inside

>    UnrealEditor-UnrealEd.dll!InternalPromptForCheckoutAndSave(const TArray<UPackage *,TSizedDefaultAllocator<32>> & FinalSaveList, bool bUseDialog, TArray<UPackage *,TSizedDefaultAllocator<32>> & OutFailedPackages) Line 4167    C++
     UnrealEditor-UnrealEd.dll!FEditorFileUtils::PromptForCheckoutAndSave(const TArray<UPackage *,TSizedDefaultAllocator<32>> & InPackages, FEditorFileUtils::FPromptForCheckoutAndSaveParams & InOutParams) Line 4576    C++
     [Inline Frame] UnrealEditor-UnrealEd.dll!InternalSavePackages(const TArray<UPackage *,TSizedDefaultAllocator<32>> &) Line 3831    C++
     UnrealEditor-UnrealEd.dll!FEditorFileUtils::SaveCurrentLevel() Line 4110    C++
     [Inline Frame] UnrealEditor-LevelEditor.dll!Invoke(void(*)() &) Line 47    C++
     [Inline Frame] UnrealEditor-LevelEditor.dll!UE::Core::Private::Tuple::TTupleBase<TIntegerSequence<unsigned int>>::ApplyAfter(void(*)() &) Line 309    C++
     UnrealEditor-LevelEditor.dll!V::TBaseStaticDelegateInstance::ExecuteIfSafe() Line 777    C++
     [Inline Frame] UnrealEditor-Slate.dll!TDelegate<void __cdecl(void),FDefaultDelegateUserPolicy>::ExecuteIfBound() Line 570    C++
     UnrealEditor-Slate.dll!FUIAction::Execute() Line 139    C++ 

This has three requirements:

  • The external actor package must be findable at user save-time (long after map load) inside FEditorFileUtils::SaveCurrentLevel() where Level->GetLoadedExternalObjectPackages() is called.
  • The package must be considered for resave.
  • Ultimately InternalSavePackages() should decide to delete that file.
Steps to Reproduce
  • Create a ThirdPersonTemplate project
  • Create and save a Map
    • Does not need to be world partition
    • Does require external actors so check World Settings > Use External Actors
  • Open Project Settings > Navigation System
    • Rename Default to AgentA
    • Add another type AgentB with a different agent radius like 60.0
  • Place a NavMeshBoundsVolume in the map
  • Build > Build Paths
  • Observe that the map contains two nav mesh actors:  Recast-AgentA, Recast-AgentB
  • Save the map
  • Use a file explorer search tool like "Everything" (external tool) to scan the project's ExternalActors folder:
    • Search for files containing Recast
    • Observe two files: these assets represent the Recast actors on disk with one-file-per-actor enabled
  • Go to Project Settings > Navigation System
    • Modify AgentB's agent radius to a new value like 80.0
  • Build > Build Paths
  • Observe a third Recast actor (the old AgentB nav mesh isn't deleted). This is the first problem: ideally it's cleaned up already in this editor session for that map.
  • Save the map anyway.
  • Re-open the map
  • You will only see two Recast actors
  • Observe the log message
LogNavigation: Warning: NavData RegistrationFailed_AgentNotValid, NavData instance contains navmesh that doesn't support any of expected agent types. 

The third Recast nav mesh actor has been destroyed by UNavigationSystemV1::ProcessRegistrationCandidates().

  • Save the map
  • In the file system and using Everything (external tool), search the ExternalActors folder again for files containing Recast.
  • Observe: Three assets exist representing Recast NavMesh actors
  • Expected: Since there are only two agent types and they have unique settings, only two should exist
  • Other way to confirm: saving the level and reloading again the LogNavigation warning still appears. The obsolete NavMesh actor keeps getting loaded and then ignored at runtime but never deleted from the file system.

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-229996 in the post.

0
Login to Vote

Unresolved
ComponentUE - AI - Navigation
Affects Versions5.4
Target Fix5.6
CreatedNov 8, 2024
UpdatedDec 10, 2024
View Jira Issue