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 section. If I should be posting this question in another section, 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!

This sounds very similar to the problems our current projects face. I’ve reached out to the people at https://terraformpro.com/ to see if there are any updates, as that seems like it would fit the bill.

Failing that, I’ve been investigating Landscape Splines myself. If you’ve got the Shapefiles in you’re a step ahead of me, but by applying them to a Landscape Spline you should then be able to get the terrain to conform to the road accurately. I’m not sure at the moment how exposed they are to manipulation from automated tools, but I’ll hopefully have more info soon.

A better option than the construction script would be to do the road generation as a function that is callable in the editor. You would set it up to generate the road as a different actor. The resultant road would then be saved as part of the level, and you would only have to do it once, before runtime. You wouldn’t then have to worry about spawning the roads on level load; they’d be an inherent part of them. There is probably a way more efficient way to do this in C++, but that is not my area of expertise.

As for your question about level visibility, there’s a couple of blueprint nodes under the game category for checking if a level is loaded or visible. You’d need to reference a specific streaming level, and, yes, you’d need to trigger the check. You don’t have to do this on an event tick, however. You could set it on a timer. A simpler alternative is to have an actor that is dedicated to checking for level visibility, but with a longer tick interval. You can set this in the class defaults (and it’s a lifesaver for when you have hundreds of actors that all need regular updates!)

Let me know if you have any luck with your roads.