I am fully aware of Instantiate() function and know how to spawn prefabs at runtime.
Does anyone know how to spawn objects at different points at different intervals and have specific (or random) distance between each other. It should look very random like so:
These dots has been randomly placed by me, I expect same results but computer generated.
You’re probably looking for something along the lines of a low discrepancy sequence. Specific examples of such algorithms are the Sobol Sequence and the Halton Sequence. See the linked pages for graphical examples of their results.
Maybe simpler (but also maybe less satisfying) might be to just divide your plane up into a grid of smaller regions (based on the number of points you’re going to place) and then drop a point at a random location within each region.
I would randomly choose the x and z coordinates within the screen space and keep each object in a list. Then, when a new object is created, test against the list by distance. If both are above a minimum on all objects, then place the dot.
I got it working, it’s basically what @fire7side said: randomly choose x and y locations, check if there is appropriate distance to the closest object and check if distance to player is far enough. This spawns an object and then repeats the procedure.
Hmmm… That sounds highly inefficient - at least if you’re attempting to place very many points (place point, iterate through all previous points to find closest, new point too close, repeat). But, if it’s working satisfactorily - that’s great. Glad you solved it.
The main problem with the system described is the more dots placed, the longer it will take to find a valid dot location. There is also a point at which no valid dot location exist. At which point your code enters an infinite loop and freezes up completely.
@Kiwasi The actual implementation only tests for the ground layer and then offsets the green cube (leaves) a little bit so there’s no z fighting. It’s still possible, but less likely. Darn, I thought I found a system that was both interesting AND inefficient.
The idea comes from having a forest that follows the player. The transform follows the player around and rains trees within a max and minimum range from the player so you start in a clearing but proceed into a chaotically generated forest. Trees beyond 60 meters from you are deleted and new ones rain down
If that’s the case then why not prepare a grid of possible locations as a list and then set your positions from random positions in that list, removing a spot when you use it. Then you can place them as efficiently as possible
That’s true. The method I have listed sounds inefficient because as @Kiwasi mentioned, the more dots are placed the more time it takes to find a “perfect” location.
Making a grid of possible locations will not make it look less “random”. Getting random x and y coordinates gives me more random points. Besides I have tried doing that, which took too much time to setup.
I have made a test by increasing limit to 500 instances. Spawns all obstacles in less than a second with same FPS and no lag! I don’t even need to “remove spot” because it checks if any other obstacle or a player is at that point by measuring a distance.
Just 1 last awful suggestion, because why not. Have your spawner object in the center of the area you want to spawn things in. Make a prefab with a rigid body and a script on it that gets launched from the spawner object with x and z offsets that cover the range of the area you want to spawn things in. When the rigid body lands (velocity=0), attach a sphere collider to it that has the radius of the minimum distance to spawn things between other things. Continue this process and when ever a spawnpoint is heading for another one, it’ll hit the sphere collider and bounce off, so it will get as close as the minimum distance. When all of your objects have been fired (you can probably speed this up by shooting a bunch of them at once per iteration), have the script iterate over them and replace the fired spawn body with the object you’re trying to instantiate
@Kiwasi did I finally have a poorly performing idea?
Create a predetermined list of grid points and store them in a list or array
Randomly select an index in the “grid point” list or array
Generate your next random point by creating a point that’s within some radius (maybe 1/3 to 1/2 of the distance between grid points) of the selected grid point. To do that, just create a random x/y vector with a maximum magnitude of your radius, then add it to the selected point’s coordinates.
Remove the selected point from your list/array
While you need more points, go to #2
Obvious advantages over your current method are:
Each new point is guaranteed to be valid
No slow distance checks required
You still get a reasonably even distribution of seemingly random points
And, it’d be really easy and clean to code. Actually, this is nearly the same method as my final suggestion in my original post.