Procedural placement on landscape issue

Once you have a possible spot, what about doing 3 other traces for the land from a triangle which incorporates most of the base of the object? If they are roughly the same height, then place the object.

Something along these lines:

Those are the 3 values to compare.

Hi,

So I’m procedurally (via blueprint) placing ruins and other POI’s on a landscape and have a blueprint which manages this but because the ruins themselves are quite big the line/sphere trace I’m doing to check for a valid spot succeeds based on the origin of the POI I’m placing, but this can quite often be on the edge of a hill or other terrain variation.

like the above image.
What I need is for the trace I’m doing to check a radius on impact for the slope angle of the terrain at the projected point to make sure it is ‘flat-ish’. I’ve tried doing a ‘GetSlopeDegreeAngle’ after breaking the Vector from the ‘ImpactPoint’ of the Sphere trace but not sure I’m doing it right as it keeps placing them like this.

Anyone have a good solution to modify the results of the sphere trace to include checking the landscape for flatness underneath the prospective object please?

Thanks,
Daz

Hey, Thanks for the idea. Looks interesting, though are the traces contained within the functions?
Which bit compares the heights and decides it’s ‘flat-ish’?
Sorry, it’s quite different to what I have already and I’m trying to find the best way to incorporate the idea into my existing trace etc.

So, you do your current trace to find the variable ‘Possible location’. Then you go through the process above.

The ‘downward trace’ function is just a placeholder ( didn’t actually write the contents ), but it’s just a vertical downward line trace from the position given, looking for the landscape. It returns that distance.

Then, all you have to do, is compare the floats that come back. It’s really up to you how you do that, but you’re looking for them all to be roughly the same, and a suitable distance from the asset you’re placing ( I don’t know your specifics ).

In the example you gave, the test would fail because one ( or two ) or the downward traces would return a much larger distance ( the drop you see ).

Gotcha. Thanks mate I’ll give it a go :slight_smile:

Here, I made a cube with the trace:

335072-cubetrace.gif

The ball on top goes red when the traces are in good range. You can see the 3 traces as red dots.

All I said was:

335073-screenshot-3.jpg

( but you’d need to tune that to your case ).

a good solution to modify the results
of the sphere trace

I don’t think a single sphere trace is enough, you will need several hits to get this going. Consider the following:

  • we fire a line trace from each corner of the mesh bounds
  • if we exceed the slope, we break the loop early
  • best case scenario, you get a result after 1st trace, worst case scenario, you’ll need all 4
  • to make it more reliable, you’ll need even more traces and account for orientation of the mesh to boot

Image from Gyazo

This may or may not be enough, though. Depending on how accurate are the desired results.

This looks ideal as an extension of what @Clockworkocean suggested.
Quick question though, I am actually not placing Static Meshes, I’m taking an ‘InstancedStaticMesh’ and as I place the object I set the Child actor class to a BP (a Blueprint that is a collection of Static meshes that make up my object to place). This means that the object doesn’t know what it is until further down the chain so I’m not sure if I need some extra steps to take that into account?

You will not be able to able to use Get Component Bounds of ISM since that would mean the bounds of all instances of that ISM - definitely not what we want. But you know at this point which mesh is going to be placed down, right?

It’s a matter of knowing the dimensions. Do you have that info?

roughly, though I can probably get that info accurately with a bit of effort

I’ll get some grabs of it but I’ll probably undo what I’ve done since your last post as it’ll just confuse matters.
You said above “It’s a matter of knowing the dimensions. Do you have that info?”
What was your plan for if I have the dimensions?

I tried a few things to modify this to get it working but I keep getting infinite loops so I’m being stupid. I put a box around the object inside the blueprint with the plan to use that as it matches the dimensions of the exterior edges of the object. But in doing something wrong.

Pretty much impossible to tell what goes wrong without seeing the script.

The main issue above is that you’re terminating the function prematurely, it never runs more than 1 trace.


I’ve modified it to be a bit more complete:

  • generating random locations and checking whether the area underneath is flat under

  • the desired data can now be piped in
  • note how this is not returning when isFlat turns out to be True

For the ground to be considered flat, all 4 traces must be successful.

Image from Gyazo


To sum up:

  • have location to spawn and XY dimension of the mesh
  • run trace from above towards the ground for each corner
  • if ground is not flat or we hit nothing, terminate and don’t place the mesh
  • if all 4 traces are successful, this area is flat, place mesh at the initial location

Also, while doing this, I run into 2 bugs:

  • one with renaming variables (can be seen above Spawn Point Abovet)
  • and one even more funky:

335215-screenshot-1.png

It’s both, a 2d & 3d vector :slight_smile:

It’s just a vector, you can split pins by right clicking them:

Image from Gyazo

So @Everynone here’s the current Blueprint for defining the SpawnBox that the randomly placed objects will spawn within.
Hopefully it’s clear enough, but I’ve taken an overview screenshot too to help readability of the zoomed in shots.
Then I’ve took one of your Blueprint that I have copied.
The problem is that I’m not using a Static Mesh object and i think in here it doesn’t have any bounds for the ‘POI’ object. Anyway, hopefully it’ll make it clearer for you what I’m doing wrong.
Thanks!

P.S - I tried adding all the images and it wouldn’t post so I’m gonna try them as separate posts…