Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

CFrame help needed! How to make a CFrame outside a box, but within a boundary at the same time?

So the title is probably very confusing and I dont blame you. My head hurts, and Im very tired so im probably not in my prime at the moment, and this is very confusing. Basically I have this script

	if mode == 'q' and d == false then
		d = true
		for i = 1, 180 do
			local r = Instance.new("Part")
				r.Size = Vector3.new(3, 6, 3)
				r.BrickColor = BrickColor.new("Eggplant")
				r.CFrame = (pc.Torso.CFrame * CFrame.new(10, 0, 10)) + Vector3.new(mr(-30, 30), -15, mr(-30, 30))
				r.Anchored = true
			local t = script.QSCRIPT:clone()
				t.Parent = r
				r.Parent = workspace
				wait()
		end

And I need the parts to spawn outside of a -0x10 box around my torso, but within a 30x30 radius around the torso (not within the box). I have no idea how to do this and you can see my random gibberish on line 7. Help is greatly appreciated

1 comment

0

I fixed it myself but am curious to hear your guys' solutions, so if you want to post them below.

1 answer

To accomplish this, I would first choose a random point on the outside of the rectangular bounds. Then I would calculate the distance from the origin to the chosen point and generate a random number between the distance found and the maximum distance (circle radius). Then the random point inside the volume would be the unit vector (direction) of the point times the random distance plus your offset.

local function randPos(origin, bounds, maxDist)
	-- Get point on edge of bounds	
	local face = math.random(0, 5)
	local axis = face%3
	local x, y, z
	if axis == 0 then
		x = face > 2 and -bounds.X/2 or bounds.X/2
		y = math.random()*bounds.Y - bounds.Y/2
		z = math.random()*bounds.Z - bounds.Z/2
	elseif axis == 1 then
		x = math.random()*bounds.X - bounds.X/2
		y = face > 2 and -bounds.Y/2 or bounds.Y/2
		z = math.random()*bounds.Z - bounds.Z/2
	else
		x = math.random()*bounds.X - bounds.X/2
		y = math.random()*bounds.Y - bounds.Y/2
		z = face > 2 and -bounds.Z/2 or bounds.Z/2
	end	
	local point = Vector3.new(x, y, z)	

	local dist = point.magnitude -- distance from origin to point
	local r = math.random()*(maxDist - dist) + dist -- random distance between dist and maxDist
	
	return origin + point.unit*r
end

Here is a usage example:

local origin = Vector3.new(0, 20, 0)
local bounds = Vector3.new(10, 10, 10)
local maxDist = 15

local part = Instance.new("Part")
part.Anchored = true
part.BrickColor = BrickColor.new("Eggplant")
part.Size = Vector3.new()
part.Parent = game.Workspace

while wait(0.5) do
	part.CFrame = CFrame.new(randPos(origin, bounds, maxDist))
end

###Edit

Turns out I misread your question, This calculates a random position in a sphere out side of a 3D bounds. Calculating this is 2D simplifies the problem and you can use the same approach:

local function randPos(origin, bounds, maxDist)
	-- Get point on edge of rectangle
	local edge = math.random(0, 3)
	local axis = edge%2
	if axis == 0 then
		x = edge > 2 and -bounds.X/2 or bounds.X/2
		z = math.random()*bounds.Z - bounds.Z/2
	else
		x = math.random()*bounds.X - bounds.X/2
		z = edge > 2 and -bounds.Z/2 or bounds.Z/2
	end
	local point = Vector3.new(x, 0, z)

	local dist = point.magnitude
	local r = math.random()*(maxDist - dist) + dist

	return origin + point.unit*r
end

Usage Example:

local origin = Vector3.new(0, 20, 0)
local bounds = Vector3.new(10, 0, 10)
local maxDist = 15

part.CFrame = CFrame.new(randPos(origin, bounds, maxDist))

This discussion is preserved as it was. New answers, comments, and votes are closed.