Procedural Tools in Unreal Engine 5.3
This is an overview of various procedural tools I created for Duck Side of the Moon while at Starbrew Games.
These tools were developed throughout 2024 using Unreal Engine 5.3 with Geometry Script, PCG & Blueprints. All tools work entirely inside Unreal Engine, with no need for external software such as Houdini.
Geometry Script Spline Tools
The spline-based tools for this project were all made using Geometry Script - a set of Blueprint nodes and utilities that allows for basic procedural modelling inside UE5.
Most of these tools follow very similar set-ups involving mesh(es) swept along the editable spline, with additional objects spawned along the spline. These tools have a variety of user inputs, such as objects to scatter, scatter density, and materials for any generated geometry.
Geometry Script, in my experience, isn’t as flexible or robust as solutions like Houdini Engine, and as a result isn’t very suited for complex procedural modelling. However, the fact that the entire tool can be made using Blueprints and interface with other Blueprints and Unreal components makes it very nice for simple, user-friendly tools such as these spline tools.
A section of a spline tool Blueprint, which resamples the input spline to generate a sweep mesh and create points to spawn other meshes on.
Dynamic Mesh Actor Baking
The meshes generated by the spline tools mentioned above are generally editor-only. (There is a variant class that can be used in builds as well, but it is several times more expensive than a static mesh, and should be avoided wherever possible.)
So, to make sure the geometry created by these tools shows up in game, these meshes have to be baked to static meshes. Unreal provides several functions as part of Geometry Script that can do this, accessible in Blueprints, C++ & Python.
Logically, this baking step would preferably be automated on all relevant meshes before building the project, to ensure all meshes are accounted for. To achieve this, I set up a Python script that iterates over all relevant meshes in all levels included in the build. Unfortunately, automating these operations tended to make the engine somewhat unstable, resulting in the engine freezing around 40% of the time. This made the script not suitable for the project’s build pipeline. A C++ solution might have been a more stable alternative, however due to limited experience with C++ and project time constraints, I was unable to pursue this option.
Instead, I resorted to adding a call-in-editor function to each tool, giving the user a button that would create static mesh copy of the dynamic mesh. This function also overrides any previous static meshes generated by the instance of the tool, and deletes them from the project’s files - this way directories and level outlines remain organized.
Making this a manual function has the obvious downside that the conversion of meshes can be skipped or forgotten; to combat this, I set the dynamic mesh to be hidden in-game in the editor, making meshes without a valid static equivalent easier to spot during development.
The Blueprint function that handles the static mesh generation for one of the spline tools. (Graph rearranged for the image.)
Editable Object Scattering Using PCG & Blueprints
This system started as a relatively simple set-up using Unreal’s PCG graphs to scatter objects -in this case rocks- on the level landscape. This system scatters points on the landscape based on it’s curvature and adjusts point density based on the size of the scattered objects.
However, while general results were acceptable, especially given the development time invested at that point, I noticed some instances of objects that were somewhat interfering with the play space or obstructing interactable objects. Additional point pruning based on intersections with existing meshes in the level solved some of these issues, but I still wanted a solution that allowed for some more artistic control.
The solution I landed on involved wrapping the PCG system in a Blueprint which not only handles any input parameters such as density and randomization seed, but can also spawn helper Blueprint actors. These helper Blueprints can be moved around in the level to transform or delete any spawn points they overlap with. This allows a user to individually move, rotate, scale, or delete any scattered objects.
This approach allows manual overrides to compensate for some of short-comings of this version of the PCG toolset in UE5.3.
These are the various actors that combine to create this editable scatter system: The overarching Blueprint that a user places in the level and interacts with, The helper BPs to remove and transform points, the function for point transformation, and the PCG graph that handles the point scattering & mesh instancing.
Procedural River & Lake Meshes
The mesh generation for the procedural river & lake systems is based on the same principals as the spline tools described above, only at a larger scale. They also use splines as their primary inputs, but have more complex geometry with multiple layers, as well as more user parameters.
This is combined with advanced shader and VFX set-ups to create assets with more visual interest and customizability than the simpler spline tools.
Continuous Actor Spline Movement & Spawning
The logic for moving and spawning objects over splines -created specifically for use with the river system- is fully built using Blueprints. The system spawns objects at the start of the spline and deletes them once they reach the other end, before spawning a new, randomized object at the start of the spline. This gives the illusion of a continuous stream of unique objects, with each having a unique starting transform. The objects & their transforms can also be saved; this was a requirement from the design team to avoid gameplay exploits using the system.
The system can also be triggered to spawn specific objects at specific times, using a timer or from another actor using a function call. This allows the system to be used by certain quests, spawning relevant objects when certain quest requirements are met.
Closing Thoughts
The fact that Houdini wasn’t available to use throughout this project made for a very interesting challenge, that forced me to get a lot more familiar with some of the systems that have been added to Unreal Engine over the past few years. It also forced me to reinvent some workflows I took for granted in Houdini and find interesting work-arounds for limitations, which greatly helped my skills for procedural modelling in any software
And while I’ve encountered plenty of moments where I felt like the lack of Houdini made my work a lot more difficult, I’m very impressed by what Geometry Script, PCG & Blueprints have enabled me to create.
Throughout my involvement with this project, the response & feedback from the rest of the team has been instrumental in improving each of these tools and I’m glad we ended up with a toolkit that will speed up & support the rest of the project’s development.
Lastly, I’m sure that with more time, effort, and knowledge I could have pushed these tools even further, and that will only get better as these systems mature over the next few years.