Dear Epic (and Miezsko),
I am really wanting to know when the nav mesh updates itself during runtime to respond to newly spawned level geometry.
My AI characters avoid newly created geometry beautifully (thank you!), since nav mesh generatoin is set to be fully dynamic in project settings.
However the delegate made available to find out when a Recast nav mesh updates does not seem to be firing off!
DECLARE_MULTICAST_DELEGATE(FOnNavMeshUpdate);
I am adding new UObject in Begin play, after waiting 0.3 seconds just to be sure.
UNavigationSystem* NavSys = GetWorld()->GetNavigationSystem();
if(!NavSys) return;
for (int32 Idx = 0; Idx < NavSys->NavDataSet.Num(); Idx++)
{
ARecastNavMesh* EachRecast = Cast<ARecastNavMesh>(NavSys->NavDataSet[Idx]);
if (EachRecast)
{
EachRecast->OnNavMeshUpdate.AddUObject(this, &AJoyWorld::JoyNav_NavMeshUpdated);
VSCREENMSG("Dynamic Added!");
}
}
void AJoyWorld::JoyNav_NavMeshUpdated()
{
VSCREENMSG("NAV MESH UPDATED WOOHOO!!!");
}
#My test
My screen message fires off to tell me a delegate was added (only 1 for my test level, the Main Recast Nav Mesh)
During runtime I spawn new colliding geometry that I know is updating respective RecastNavmeshes because the AI avoids the new geometry and I also draw the polys of nav mesh and so I know they are reshaping just fine.
Yet that delegate is never firing off so I can’t easily know when to update my own internal structures after UE4 has finished.
#My Research For You
I have some good news!
I made my own UNavigationSystem subclass and can now capture updates!
But when I make a delegate in my custom subclass, the delegate does not fire even though it is bound, only the screen messages fires!
Conclusion: Somehow delegates not working properly in this particular class.
Enjoy!
/*
By Rama
*/
#pragma once
#include "VictoryCore.h"
#include "JoyNavSys.generated.h"
/** Delegate to let interested parties know that Nav Data has been registered */
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FJoyNavSysUpdate);
UCLASS()
class UJoyNavSys : public UNavigationSystem
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintAssignable, Transient)
FJoyNavSysUpdate OnJoyNavSysUpdated;
virtual void Tick(float DeltaSeconds) override
{
//Check before all arrays emptied of pending updates
bool PendingUpdate = PendingNavAreaRegistration.Num() > 0
|| PendingNavBoundsUpdates.Num() > 0
|| PendingOctreeUpdates.Num() > 0
|| DirtyAreas.Num() > 0;
//Super
Super::Tick(DeltaSeconds);
//Broad Cast
if(PendingUpdate && OnJoyNavSysUpdated.IsBound())
{
VSCREENMSG("Joy Nav Sys Updated!"); //Works
OnJoyNavSysUpdated.Broadcast(); //doesnt fire even though bound!
}
}
};
#Thank You For UE4!
#
Rama