Is there a way to generate a point inside a set of hallways

I have a horror game enemy that I want to appear in random points INSIDE a hallway. I used a random in bounds point generator for a collider, but even with a mesh collider it can generate a point outside a hallway. is there a good way to generate a point and guarantee it’ll be inside a hallway? should I be using a navmesh function to reliably find a point?

Depends on what your definition of “hallway” is relative to everything else inside the region that you’re considering.

Note that in your computer world there is no concept of these fairly standard terms we may use in every day language. Your job is to determine a definition for it that can be represented algorithmically.

And considering that you haven’t shown us what your region looks like, or described it in any detail outside of “hallway”… it’s going to be very hard for us to guess what you mean specifically.

This isn’t to say we couldn’t come up with potential solutions. But it’s pure happenstance if any one of those solutions actually would meet your needs.

For example… why define a region that is everything, and instead define a sub region that is JUST the hallway. Have box colliders in ONLY the spawnable region that is your hallways. Then pick one of those regions (hallways), then a point inside of that chosen region, randomly.

But this might not work for you because maybe hallways bend and turn and can’t be easily represented as a series of box colliders. Maybe your world is randomly generated so how would you get those colliders in there? (thusly requiring another layer of complexity where you must generate those as well as the world itself) Or maybe why even have colliders at all? Why are we creating instances of physics objects for something that isn’t really physically required? Can’t we just define them implicitly as a point and size relative to other things that exist already in the world?

Point is… what is a “hallway” in your game?

1 Like

That’s a very good point, I apologize. The hallway is a pre-made area that is entirely 90 degree angles, much like a traditional maze, and the player interacts with it through a mesh collider. I’ve tried generating a random point inside the mesh collider but it looks like “In bounds” even in terms of a mesh collider means the outermost points of the collider, not necessarily the “inside” as we’d typically define in normal every day life. I suppose I could use a series of box colliders that match the geometry of the hallway area. Is there a way, if I were to attach multiple colliders to the same object, to

Do you happen to be using the NavMesh system? If so, you can pick a random point, then query for the closest point on a navmesh. Very convenient (albeit biased towards the edges of the hallway, so you might need some more adjusting!)

Generating a random point over an area of rectangles is pretty straightforward.
Well without more details it’s hard to give a clear unity solution so I’ll give an abstract solution.
Since we know hallways are 90 degree angles we can break this problem up into two steps of randomization.
Step 1 pick one of the rectangle sections to get random point in randomly. Step 2 is figuring out how to get a random point in a rectangle.
Let’s define a rectangle as a length an width and a root position that sits at the bottom left corner.
We can get a random point in our proposed rectangle via the following.
X = Random(0,length) + position.X
Y = Random(0,width) + position.Y

So step 2 is done. But now we have to pick a random section. If every section is the same size then we can just pick a rectangle randomly. Assuming the rectangles are stored in an array it could be as simple as
Rectangle = Rectangles[Random.Range(0, Rectangles.length -1)];

If the rectangles are not all the same size then you need to weight which rectangle is selected by their area (length x width).

For this you could do something like get the total area of all rectangles.
Then pick a random value between 0 and the totalOfAllWeights.

float totalWeight = 0.0f;
foreach (var rect : Rectangles)
     totalWeight+=(rect.length * rect.width);

float selectedW= Random.Range(0, totalOfAllWeights);

float currentW=0.0f;
Rectangle rectangle;
foreach(var rect : Rectangles)
{
     currentW += (rect.length * rect.width);
     if (selectedW <= currentW)
     {
          rectangle = rect;
          break;
     }
}

X = Random.Range(0.0f,rectangle.length) + rectangle.position.x;
Y = Random.Range(0.0f, rectangle.width) + rectangle.position.y;

I like to just author this stuff: author the hallway prefab with 10 possible spawnpoints, then pick ONE randomly.

Yes it is some more work but it gives you so much power and flexibility… like perhaps you will find that it is lame if the enemy appears too close to a bend in the hallway, or perhaps you WANT him near the end as a jumpscare, and you can just adjust the prefab, no code changes necessary.

Or if you want more chance to be near a particular place you just put a bunch of spots all in that same space so they have a higher chance of being picked.

Data for the win!!

1 Like

I was about to suggest the same thing. Wide open randomness is pretty dangerous because it can break your game in unpredictable ways and you may not catch them while testing. With a specific number of spawn points, though. You can play-test them all.

2 Likes

That’s a really good idea, I think I’ll do that. better to tailor the experience with. Thanks!