How to pick a random point on a union/part?

A new game I am working on, has a feature where coins randomly spawn in the lobby. I have done something like this before, but it was with a regular square area, not an area like seen here:

I do not want coins to spawn in the center area where there is nothing, obviously. How would I make a script that would do this?

Does anyone have any idea on how to do this?

You could try using something like a raycast or just create a part at the point and seeing if it overlaps, although I don’t know how you would do the raycast.

Here is an example with raycasts.

This script picks a random spawn location and casts a ray downwards from there.
If the ray does not hit anything then the position must be in the air and gets discarded.

If you wanted to guarantee that a coin actually spawns, you would retry with a new position rather than discard the spawn attempt.

function spawnCoin()
	local rand = Random.new()
	local spawnPosition = Vector3.new(
		rand:NextNumber(lobby.Position.X - lobby.Size.X/2, lobby.Position.X + lobby.Size.X/2),
		lobby.Position.Y + 1,
		rand:NextNumber(lobby.Position.Z - lobby.Size.Z/2, lobby.Position.Z + lobby.Size.Z/2)
	)
	
	local rayParams = RaycastParams.new()
	rayParams.FilterDescendantsInstances = {lobby}
	rayParams.FilterType = Enum.RaycastFilterType.Include
	
	local result = workspace:Raycast(
		spawnPosition,
		Vector3.new(0, -2, 0),
		rayParams
	)
	
	if result == nil then return end
	
	local coin = Instance.new("Part")
	coin.Shape = Enum.PartType.Ball
	coin.Anchored = true
	coin.Position = spawnPosition
	coin.Parent = workspace
end

Easy way: use raytracing from a random point above the part, check if it hits it, if it does, pass, if it doesnt, pick another random point until it does.
Might have to change some options with the union’s fidelity/hitbox