How to position a part randomly on a part?

im already giving you the base pos?

Looks like youā€™re not properly distinguishing object space and world space. In the code snippit here youā€™re treating pos as both object and world space. X and Z are treated as object space relative to baseā€™s size, but then treating Y as world space to counteract the baseā€™s size.Y

local ran = Random.new(tick()) -- prefer Random over math.random
local halfSize = base.Size * .5 -- cleans up code to move division by 2 outside of the V3 constructor
-- first we find our randomized position in object space
-- constant 2 replaced to offset base's size.Y and the meshpart's size.Y
local objPos = Vector3.new(ran:NextNumber(-halfSize.X, halfSize.X), halfSize.Y + rock.PrimaryPart.Size.Y/2, ran:NextNumber(-halfSize.Z, halfSize.Z))

-- position rock
rock:SetPrimaryPartCFrame(CFrame.new(base.CFrame * objPos))

You can use the pointToObjectSpace() method of CFrame as well, but as documented itā€™s the equivalent of CFrame * point Vector3; which happens to be easier to write. The method is handy if you have trouble keeping track.

Hope that helps clear things up!

1 Like

this does not work becuase it every ore has a script that places it, so the ores end up getting put inside eachotherā€¦

Thats an entirely different problem though?
The best practice would to have a single script that would handle all of the placing and have it remember placed places so it can try to not place multiple things too close to one another

my code, puts them at diff hights and makes like 500 of themā€¦ any idea whats wrong?

local ran = Random.new(tick())

for i,x in pairs(script.Parent:GetChildren()) do
if x ~= script then
print(x.Name)
for v=1,x.Amount.Value do
print(x.Name)
local dub = x:Clone()
dub.Parent = x
dub.Amount:Destroy()
dub.Defualt.Transparency = 0
for z,r in pairs(dub.Defualt:GetChildren()) do
r.Transparency = 0
end
dub.PrimaryPart = dub.Defualt
local base = workspace.Map:FindFirstChild(ā€œBaseā€ā€¦math.random(1,4)ā€¦ā€œā€)
local halfSize = base.Size * .5
local objPos = Vector3.new(ran:NextNumber(-halfSize.X, halfSize.X), 0, ran:NextNumber(-halfSize.Z, halfSize.Z))
dub:SetPrimaryPartCFrame(CFrame.new(base.CFrame * objPos))
end
x.ChildRemoved:connect(function(child)
print(ā€œgoā€)
local dub = x:Clone()
dub.Parent = x
dub.Amount:Destroy()
dub.Defualt.Transparency = 0
for z,r in pairs(dub.Defualt:GetChildren()) do
r.Transparency = 0
end
dub.PrimaryPart = dub.Defualt
local base = workspace.Map:FindFirstChild(ā€œBaseā€ā€¦math.random(1,4)ā€¦ā€œā€)
local halfSize = base.Size * .5
local objPos = Vector3.new(ran:NextNumber(-halfSize.X, halfSize.X), halfSize.Y + dub.PrimaryPart.Size.Y/2, ran:NextNumber(-halfSize.Z, halfSize.Z))
dub:SetPrimaryPartCFrame(CFrame.new(base.CFrame * objPos))
end)
end
end

I am extremely confused on why this is not working

its spamming rocks inside rocksā€¦

A lot of problems before I could even take a look, took too much effort on my part:

  • Formatting was non-existent, you want to make sure you wrap your code like so:

    ```lua
    YOUR CODE HERE
    ```
    
  • Iā€™ll just hope you space-out and indent your code.

  • Weird characters (ellipsis and incorrect quotation marks)

  • No comments, just posting code without any kind of guide is not going to draw in help.

  • Awkward variables, single letters should be used sparingly since they donā€™t describe anything when used in a larger context.

  • Youā€™re using FindFirstChild for no apparent reason.

  • Appending an empty string at the end for no valid reason.

  • Assigning variables that you never use in the iterators (just use _)

  • Youā€™re using the same code in multiple places, use a function.

  • You have the exact same prints near eachother, in this case it could make debugging difficult.

  • Youā€™d have the same print for each ChildRemoved, which may not make it clear whatā€™s being removed.

Much more clear to follow, and even debug (variable names need work, which is up to you):

local ran = Random.new(tick())

local function spawnRock(x)

	local dub = x:Clone()
	dub.Parent = x
	dub.Amount:Destroy()
	dub.Default.Transparency = 0
	
	for _, r in pairs(dub.Default:GetChildren()) do
		r.Transparency = 0
	end

	dub.PrimaryPart = dub.Default
	
	local base = workspace.Map["Base".. math.random(1, 4)]
	local halfSize = base.Size * .5
	local objPos = Vector3.new(ran:NextNumber(-halfSize.X, halfSize.X), 0, ran:NextNumber(-halfSize.Z, halfSize.Z))
	
	dub:SetPrimaryPartCFrame(CFrame.new(base.CFrame * objPos))
end

for _, x in pairs(script.Parent:GetChildren()) do
	if x ~= script then -- I don't like this, but that's an organizational thing

		local debugMsg = "spawning %d rocks"
		print(x.Name, debugMsg:format(x.Amount.Value))

		for v = 1, x.Amount.Value do
			spawnRock(x)
		end

		x.ChildRemoved:connect(function(child)
			print(x.Name, "go")
			spawnRock(x)
		end)
	end
end

See, now you can easily isolate the problem.

2 Likes

still can not find the problem.

got it to work!