Landscape loading / water trouble

Hello,
I’ve been working on a small proto to learn about UE for some time now. As I approach the goal I had fixed to myself, I’m trying to make a build of my proto to let my friends test it.
But I’m encountering some issues with my water.

I’m using UE 5.4.4, I’ve created a level with a river going though it and while working in the editor everything was fine.

The first issue happened when I starte trying to go from one level to the other.
When the game transition and my level (with the water) is loaded i can see the landscape poping out.


Interesting thing is that happens after the FCoreUObjectDelegates::PostLoadMapWithWorld callback, so it’s clearly visible even in packaged “shipping” mode.

That was ok as I just had to hide it with an extended loading screen.
But it was also causing issue with my river…
When I’m working on the level in the editor and I press play, it’s already in memory I guess, so the river is fine :

But when I’m coming from an other level (with Async Load Asset + Open level) this is what I get :

I figured out that the Landscape “popping” wasn’t doing great with the river generation. I’ve tryed a bunch of things that i can’t remember before deciding to go simple and just put a timer to reload the river by calling the node '“Synchronize And Broadcast Data Change” in the river BP.
It works fine and honnestly it’s good enough for my proto.
But sadly the trick doesn’t work when i package my game :cry:

I’ve Build All/Coocked All tryed obscure forum stuff but I can’t get it to work.
So if some of you have any idea of what I’m doing wrong I’ll be forever grateful.

After some digging I’ve found a way to make my water behave corectly.
It’s not really a robust solution but it’s the test I have so I’m posting it here for posterity ^^

I figured out after looking at the engine code that “Synchronize And Broadcast Data Change” was an editor only function. I ended up understanding that I needed the Water Zone to be recomputed, and I don’t think there is a proper way to do that in blueprint. So I’ve made i bit of code.

I created a class inheriting from AWaterBody river and creating a method to be able to mark the water zone as dirty.

#include "WaterBodyRiverActor.h"

UCLASS()
class MYPROJECT_API AMyWaterBodyRiver : public AWaterBodyRiver
{
	GENERATED_BODY()
	
/* ... */

protected:
    UFUNCTION(BlueprintCallable, Category = "Water")
    void RebuildWaterRendering();
};
#include "MyWaterBodyRiver.h"

#include "WaterSplineComponent.h"

/* ... */

void AMyWaterBodyRiver ::RebuildWaterRendering()
{
    Super::BeginPlay();

    GetWaterBodyComponent()->GetWaterZone()->MarkForRebuild(EWaterZoneRebuildFlags::All);
}

/* ... */

The I reparented by existing blueprint to that class and called the RebuildWaterRendering.
And it worked \o/

It’s still not perfect as I call the method after a timer following the OnBegin, it would be a lot better to have a callback after the true end of the landscape loading.
But well, as I said I’m just prototyping a small thing and that is good enough for me now.

I hope this will help somebody =)

1 Like