Download

Procedurally Generated Map Lag

I have created a hex map that is procedurally generated using construction script and I am experiencing issues with lag when I have generated maps with more than 200-400 static meshes. It both takes several minutes to generate and then also lags my system pretty hard when trying to view it in the components view.

My initial generation is a map with 20x10 hexes, which works just fine. The problem becomes when I go 40x20 or 100x50 hexes. The game basically lags out either immediately after increasing the variable, or when I click the components tab to view the generation.

All the hexes are blank static meshes with dimensions of 115x100x0.

Size of the hexes doesn’t seem to change anything.

I turned off collision and overlap with no effect.

My computer is fairly decent with an i7, SSDs, GTX 550, 12GB ram, etc.

Anyone have an idea?

Hey Zeustiak,
You’ll probably want to look into Instanced Static Mesh components. I’m currently using them in a similar side project for generating a rogue like dungeon with 16384+ grid spaces.

Unlike at Static Mesh, you’ll need to “Add an Instance” to that component and provide a transform.

instances.jpg&stc=1

These are much faster to generate and won’t hit your performance nearly as hard as they are all one draw call.

Their primary draw back is they have to be a single mesh and a single material. But even if you have 20 different hex types (so 20 different instanced static mesh components), you’d still be looking at 20 draw calls vs the 200-400 you were seeing before.

edit: I guess it didn’t want to remove my example image, well, it’s 8 static meshes forming a 32x32 grid, runs smooth even on my mid range computer:

stuff.jpg&stc=1

As an aside, you can also create instanced static mesh components in your components view, then add, remove & edit the transforms of those instances in the details panel there. You can also drag the instances around in the viewport like you would other components.

Ah, I had found the spawn instanced static mesh but I hadn’t gotten it to work. I will try the other forms of instancing and keep working at it. Thanks for the tip! :slight_smile:

Having trouble getting my InstancedStaticMeshComponent variable to reference to a static mesh. When I click the dropdown to select a mesh nothing is available. I have tried dragging meshes from my content browser but a red outline appears around the box where you would normally select meshes.

Compiled it, saved it, and tried restarting the engine but still nothing.

You will need to add an InstancedStaticMeshComponent somehow, either in the Components view or somewhere in your construction script. Just creating a variable will not allow you to set the default value of the Static Mesh.

Heres how you would do this in your construction script:

Finally got them to instance, thanks!

I still don’t get anything in the dropdown for the variable itself, but I did manage to drop it onto the blueprint using Set and then ran the AddInstanceStaticMeshComponent to it. I then selected the AddInstanceStaticMeshComponent and changed it’s mesh to what I needed(instead of leaving its target on Self).

I still get a fair amount of lag when viewing a 100x50 map which is between a standard and a large sized map in games like this. You don’t normally view the entire map at one time though, so my view angle may contribute to that.

The bigger issue I have right now is that if I click the map in components view it crashes the engine…

Hey Zeustiak,

Are you adding a number of InstancedStaticMeshComponents? You only need one per static mesh, then you use the AddInstance node to create a mesh within that InstancedStaticMeshComponent.

I’m seeing a few other posts dealing with procedural generated stuff, so I went ahead and put together this larger example on using the InstancedStaticMeshComponent:

Image Link

Which results in this:

Image Link

The small square there is a single static mesh, while the larger one is a grid of 32x32 of that same static mesh.

Let’s walk through the graph:

  • Set our GridX and GridY Size to 32 (which I should only use one cause the math later should fail on non-square grid)
  • Add our InstancedStaticMeshComponent at 0,0,0 in the Blueprint (by trying to connect a vector3 to a transform, you get that handy conversion node)
  • Then we set the mesh to our grid space
  • Store the InstancedStaticMeshComponent as a variable for easy reference down the line
  • Start a for loop that starts at 0, and ends at (GridX * GridY) - 1 or 1023
  • We then divide and mod our index to get an X and Y coordinate, multiply by 100 because that is the size of the tile, then put those into a vector3 (dragging off an into to float creates that conversion node)
  • Then we Add an instance to that InstancedStaticMeshComponenet at the vector we created (handy transform node again)

Finally here is a link to an image where I multiplied by 105 instead of 100 so the grid expanded outwards.

Sounds great. Is is possible to run such a Blueprint in the editor itself to modify the level afterwards and save it to the scene (instead of running it at runtime)? I’m asking because I’d like to load a tile map from a file into the editor and not directly into the running game.

Thanks Ian! I am going to see how much I can learn from your example, though I have had to do things a bit differently for my hex map. I am still looking at how I can make the generation in one simple motion instead of using 2 sets of 2 ForLoops.

At the top I define my variables and apply the static mesh to each.

Then the first ForLoop pair creates the first half of the map:
The first ForLoop increments the X-Axis for the second ForLoop. The second ForLoop places 10(TinyMap variable) hexes along the Y axis for each run of the first ForLoop.

The second ForLoop pair does the same thing but with an offset to mesh the hex tiles together.

One thing I want to work on shortly is randomizing the meshes and giving functionality to each tile type.

And Randomized:

Hello,
I have just try the instanced mesh creation system set and it goes great but only the 128 first instances have collision. Is it normal or something i did wrong ? I tried changing static/movable and collision complexity as seen in other threads but without a change.

It depends on what you want to use the instances for. Generally you use them exclusively for rendering and not collision or things requiring actors/classes.

Ian gave some pretty good pointers in my thread:
Map Generator- Please Critique! - Blueprint Visual Scripting - Unreal Engine Forums!

Thanks for fast reply.
Yes, i have seen this thread too and it helps me a lot but i don’t understand why the 128 first instances i create have collision and the others no. I’d really like to understand ^^

( those are pillars on room tiles for a square rooms/corridors maze.)

I don’t remember having that exact problem when I was trying to get the instances to work, but I only ever touched a handful of the tiles each play session as I tested trace hits on them. Which method are you using to create the instances exactly?

I tried the method Ian Shadden shown upon with the small square and the 32 x 32 grid, quite a copy paste and i got the same result on two meshes.

You may be in the same boat as me then. Just duplicate your generation by laying an invisible layer of collision tiles over your rendered instances. If you aren’t doing anything to the collision tiles other than walking on them or colliding with them it is a pretty simple process.

But yeah I don’t know why 128 work and the rest don’t. Ghosts I say! :slight_smile:

Hi again,

i, now, have a bit something to show. This is a dungeon floor random generator with three kind of rooms (large plan, room and corridors) which can be set one by one or all.
I added a loop to not have isolated rooms and as it is instanced it can be bigger without long time generation time. I now have to go on with doors lights stuff events and mobs ^^

35760ea61f316eebdf542d424bbcbba6c37f04cd.jpeg

I did everything as per http://i.imgur.com/Ik3oz3y.jpg Ian Shadden, but I only see the one tile I placed in the scene, no others.

Not entirely sure about the setting up prior to the blueprint shown.

I created a primitive cube, converted it to a static mesh.
Created a blueprint of the actor type.

I don’t see it getting fired though.

Any ideas?

Cheers,
Max