Roads for large worlds (using World Composition)

Hello! I am still very new to UE4 and the forums, so I’m not sure if I’m asking this question in the correct topic. If I should be posting this question in another topic, please educate me!

I’m a university student (Computer Science and Engineering Student) and I’m researching about how to simulate realistic terrains using a game engine and** GIS data**.

Now about the problem I’m facing:

TLDR: trying to dynamically loads roads, similar to how World Composition deals with tiled landscapes. Not sure how to do that: landscape splines? level streaming? extending the engine?

Since I’m creating a world based off on GIS data, the terrain itself is already done (with heightmaps + tiled landscape option from World Composition + distance streaming). I’m working with a terrain that is 5km x 5km so I could explore the different possibilities the engine gives me without being too ambitious.

The goal is to work with even bigger terrains (how this will be done, is for future research and not what I’m currently worried about).

Right now, I’m having trouble with creating roads. I am able to read Shapefiles with C++ code and I started experimenting with Spline Components first: a Blueprint that reads the information and creates different Spline Components for every road.

The problem with this is that it’s done in the Construction Script and since the goal is to apply this project to bigger terrains, doing everything in a Construction Script isn’t ideal. The point of using dynamic loading with distance streaming is to get a better performance and using the Construction Script to build such big roads seems… counterproductive.

I’ve been spending the last few days looking at the engine source code, trying to understand how the engine deals with distance streaming but not really getting anywhere.
The general idea I have is that maybe I will need to spawn different Blueprints (that will correspond to different roads).

So far, I have the following questions:

  • Will Landscape Splines be the solution to this problem? I admit I’m not really sure how Landscape Splines work or how they could be built with C++ code (building the splines manually is a big no and would defeat the purpose of this project).

  • Is there any way I could know when a level is visible the moment it becomes visible? Or will I have to use an Event Tick to know this (this doesn’t sound the best option when it comes to performance)?

  • Is there a way to extend the Engine without changing the source code? While looking the WorldComposition.cpp, I think the functions OnLevelAddedToWorld and OnLevelPostLoad are interesting and in the perfect world I could spawn the roads when one of these two functions are called, but that implies changing the engine source code.

Lastly, am I overcomplicating all of this and there’s a very simple way of handling this (an already existing plugin, a Blueprint/C++ function, etc)?
I’ve been working with UE4 for a while but I admit I don’t know much about its’ API or all the features that aren’t directly related to what I’ve used in this project.

If you read this big wall of text, thank you very much!

Greetings.

I am a post doctoral researcher and I have a similar project to complete. I only have to add paths to my landscape and I will probably do it manually but any jnfo on this matter would be really appreciated.

I’m also working on a project which includes large-scale roads. Right now I’m doing something similar to the “endless runner” tutorials, which I guess is like writing your own level streaming.

My road models are static mesh actors with trigger volumes at the ends. When a pawn enters the trigger, it calls a function to spawn the next section of road. At construction, enough road sections are loaded to appear to reach the horizon. This is all done in Blueprint, but if you want to add an interface to your GIS data format you’ll need your C++ code.

There is a simple way to know when streaming levels are being loaded.

Pseudocode:



// In your game instance under Init do this:

    FCoreUObjectDelegates::PostLoadMapWithWorld.AddUObject(this, &UMyGameInstance::PostLoadMap);

// PostLoadMap is being called when the persistent level is loaded.
// Under PostLoadMap do this:
for (ULevelStreaming* StreamingLevel : GetWorld()->GetStreamingLevels())
{
    StreamingLevel->OnLevelLoaded
    StreamingLevel->OnLevelUnloaded
    StreamingLevel->OnLevelShown
    StreamingLevel->OnLevelHidden
}

As for roads, landscape splines work pretty well for that. Make sure the correct level is selected when placing splines. If roads transition between levels, place a new spline in the adjacent level and align both very close to the end of the landscape. That will make the transition very smooth.