Search Unity

Dynamic spawning system

Discussion in 'Entity Component System' started by emrys90, Mar 26, 2018.

  1. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    I have a dynamic spawning system where at runtime all the trees/rocks/etc are placed somewhere on the terrain. It's definitely a bit of a performance bottleneck at the moment for startup times, so would benefit greatly from being multithreaded. I'm struggling to think of how I would go about converting it to ECS/job systems though. Of course I understand some of these features may not be in ECS yet, nor is it production ready, so I don't intend to do this right away. Just thinking ahead a bit.

    So my spawning systems have a number of features
    • Min/max slope of the terrain
    • Min/max elevation
    • Terrain texture
    • Min distance from other objects
    The first three I get from a raycast at a random point on the terrain. From there I do an overlap sphere to check if there's anything near by. So basically I loop for a max number of iterations, picking a random vector position, and then run the other commands to see if that is a valid location.

    Can you run jobs within jobs without having to do them separately? If so then I can just do the raycast and overlap sphere in a new job where it's mostly identical to current code potentially. If not, then I'm kind of at a loss for how I would convert it over.

    My other concern is how to get it actually multithreaded, and not risk having two objects spawn in the same location.
     
  2. illinar

    illinar

    Joined:
    Apr 6, 2011
    Posts:
    863
    I think you cant schedule a job from within a job, but I think there is a simple solution to all your problems. Can you just logically split your map into a number of chunks and then schedule a job for each one? No overlap, same algorithm, just executed in parallel to itself on multiple parts of the map.
     
  3. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    Hmm yeah that could work, just have it check each quadrant a certain number of times to find a valid spot somewhere in there. I guess that would mean each quadrant could only spawn one thing though per iteration, otherwise still risk of overlaps? Also there would be potential for overlaps at the boundaries of the quadrants.
     
  4. illinar

    illinar

    Joined:
    Apr 6, 2011
    Posts:
    863
    Yes, I just thought about borders X) Well there can be a simple rule you can't place objects on X+ and Z+ borders if the distance to borders is < then your min dist. Or some such rules.
     
  5. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    Yeah, but then that could lead to lines of gap in a forest for example. If you look at it from the sky (which we do have flying as well), I think you'll start detecting a grid pattern pretty easily around the world.

    I wonder if you can use the Unity API within a job, or if it has to go through a specific job for it. I need to test that at some point I guess to see if it lets me do a raycast within a job. My guess is no and it has to go through a specific job for it. So I still have to figure out a good way to handle syncing up getting a valid position, doing a raycast, then do more logic based on that, and also an overlap sphere. That's quite a few jobs going back and forth, so it might take even longer to place everything I imagine since it has to wait on the results of the one job to then start another.
     
  6. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    First break it up into chunks using something like a quad tree so you can process it in chunks.

    Next step is create an index of objects placed with the key being x/z coordinates. You will want to normalize those to account for whatever your minimum distance allowed is. But assuming that is 1 unit then just integers representing the rounded or floored float coordinate values.

    Then when you go to place an object, you just check that index and potentially it's neighbors, which is a cheap operation.

    Even without chunking that would probably reduce your times by a considerable margin.