Download

Random location to spawn objects

I have a landscape that I made and have placed foliage everywhere, what I’m now trying to do is place houses in random locations on the landscape. I would like to specify general locations where they would be but not have to place a bunch of spawners (I would like it to be pretty random). I was thinking of maybe making a volume and generating a grid from the bounds of it, save all the grid locations to a datatable. I could then turn off grid locations where I wouldn’t want stuff to spawn (this way I could have it so stuff doesn’t spawn at the very tip of a mountain or in a river, etc). I’m not sure if this is the best way (or easiest way) to do this.

Does anyone have any suggestions or maybe another way I could do this?

Bumping up

@throtr

A Volume isn’t that useful at detecting good spawn sites / bases, especially in undulating landscapes / detailed cityscapes.
A different approach is drop a ‘Probe’ or invisible mesh with collision onto the landscape / city-mesh, until it makes contact.
Then keep a list of all those locations, and spawn actors afterwards. Or run it all one-time inside a spawn loop of some sort.

Start with getting bounds of a landscape/terrain mesh. Then add / subtract random amounts from a Vector within the bounds.
Trace down to the ground @ 90 degree angle to ensure there’s terrain (BP bounds node is blunt/just a square around mesh).
If there’s no ground, then keep calc’ing random vectors until you get a good hit. Then drop a probe onto that and rinse/repeat.
Overlapping events will also help to take a survey / get a sense of how densely populated potential spawn points already are.

As regards detecting rivers or mountain peaks… That might be as simple as getting Z-bounds of the mesh or peak min / max.
But also look into ‘landscape materials’, and how you can infer terrain-type from materials. Cant help more, haven’t tried it yet.
However, the answer lies within ‘Physical Materials’ / uses the same trick as inferring which Character footstep sounds to play.

@franktech
I think I see what you are saying. So, grab the bounds of my landscape, do a linetrace from the sky, if it doesn’t hit landscape, try again. Calculating random vectors and doing a trace for each one, wouldn’t that take a lot of cpu time if it cant find anything? Would it be better to do a grid trace (so start at x0, y0 fire a trace, increase the x, fire a trace, etc until you hit the end and go down a line, etc) and save it into a datatable or something? The datatable might be huge, but then you could log if the trace hit, and where it hit, plus then you would have instant data to work with and would only have to be rebuilt if you change stuff on the landscape. But this is just me trying to think ahead.

1000’s of traces in Tick are an issue, think RTS battles etc. However, this is different as it should be a one-time-op at startup… Also, you’re in the prototyping phase, so just get something working… Then focus on improving it. Otherwise there’s a risk of getting frozen in thought lock. And besides, there’s always more gotchas that you haven’t thought of yet… :stuck_out_tongue:

That would work… The random suggestion before, was just one approach, but its one that would be fully dynamic, and doesn’t require a location list. This is actually a pretty complex problem, hence the number of academic papers written on it. If your terrain is mostly rectangular / circular shaped landmass and not L-shaped, you could start by getting the bounds and just reduce that by a factor, so you’re always over land etc. Next, divide up the landscape into zones relative to the size of objects you’re spawning, being careful to leave space around them.

If so, then tracing maybe isn’t really required, unless you’re spawning other objects afterwards. Traces are important if you have to go back and spawn lots of other dynamic objects next to each other in layers etc. Having a pre-computed list then isn’t enough. You’d have to keep doing passes to check. Anyway, start by building up an array of possible locations or zones. Then remove those that have been used from the array. If you have to go back to spawn a car and dog and cat next to each house, then do another trace-pass within each possible zone.

Depending on the landscape terrain, if you’ve lots of forests or rocks or other obstacles already, then things are going to get complex quickly. Otherwise, you can pre-calc all of this offline, and store a list of locations in a save-file that you can just load at runtime…

I think a sphere trace would be a lot better than a simple linetrace.

Indeed, I have been thinking about this for a week, I just want a process down instead of going in circles. :stuck_out_tongue:

If I do the grid layout, I could paint a sacrificial phys/material where I want stuff to spawn (or not to spawn), run the trace over the entire map and log the hit locations (if it hits the material) to a file, then I don’t have to do it again unless I change the terrain/paint more locations. I will only have one type of object, and they will be spaced from each other by a large margin. I want this as simple as I can get, but its already pretty complicated.

Sphere trace would indeed be better, I meant just using a trace in general.

Dunno if this would work for your situation BUT you could just place like target points manually on your map where you would like to spawn houses and then at run-time get all target points, and have a function that loops through a random number of times to a random index in the array of points and pulls out the location of the target point and spawns a house at that location. It would be more manual work placing the points but you could ensure that you would have the room for a house at each position and it saves you from the complexity of traces and such to determine an appropriate location.