So I’m trying to make a script which automatically duplicates a single enemy and moves it to somewhere random on the map here’s the script:
local Template = script.Parent:FindFirstChildWhichIsA("Model")
local PP = Template.HumanoidRootPart
local x = PP.Position.X
local y = PP.Position.Y
local z = PP.Position.Z
local minx = x - 500
local maxx = x + 500
local minz = z - 750
local maxz = z + 750
local rolls = 0
local maxrolls = 100
local isStudio = false
local RunService = game:GetService("RunService")
if RunService:IsStudio() then
isStudio = true
end
local studiomaxrolls = 5
if isStudio == true then
while true do
if rolls >= studiomaxrolls then
Template:Destroy()
script:Destroy()
end
rolls = rolls + 1
local ranx = math.random(minx, maxx)
local ranz = math.random(minz, maxz)
print (ranx)
print (ranz)
local Clone = Template:Clone()
Clone.Parent = script.Parent
Clone:SetPrimaryPartCFrame(CFrame.new(ranx, y, ranz))
end
end
Now the script works fine, however all the location of all the “randomly placed” zombies are equal excluding the first time the zombie gets cloned (eg. zombie1 coordinates = 5,0,2; zombie 2 coordinates = 27,0,72; zombie 3 coordinates = 27,0,72; zombie 4 coordinates = 27,0,72…), as shown in the output here:
NOTE: Red underline = x coordinate, blue/black underline = z coordinate
I would like to know why the “random” values are always the same
This is weird, maybe there is something I am missing, but the only thing I can think of is putting the if studio == true inside the while loop instead of the other way around.
local Template = script.Parent:FindFirstChildWhichIsA("Model")
local PP = Template.HumanoidRootPart
local x = PP.Position.X
local y = PP.Position.Y
local z = PP.Position.Z
local minx = x - 500
local maxx = x + 500
local minz = z - 750
local maxz = z + 750
local rolls = 0
local maxrolls = 100
local RunService = game:GetService("RunService")
local studiomaxrolls = 5
local ranx,ranz
if RunService:IsStudio() then
while true do
if rolls >= studiomaxrolls then
Template:Destroy()
script:Destroy()
break
end
rolls += 1
ranx = math.random(minx, maxx)
ranz = math.random(minz, maxz)
print(ranx)
print(ranz)
local Clone = Template:Clone()
Clone:SetPrimaryPartCFrame(CFrame.new(ranx, y, ranz))
Clone.Parent = script.Parent
end
end
I removed the isStudio variable since you can check RunService:IsStudio() directly
The other thing you could do is put the everything in a function and call that function from a while loop. Sometimes calling the function multiple times works.
Hmmm … this is super weird. Maybe try using this code to get a random number?
math.random()*(maxx-minx) + minx
-- and
math.random()*(maxz-minz) + minz
The math.random function with no parameters returns a random between [0.0,1.0), so this is the equivalent of your random code but it will not always return an integer number.
I’m honestly pretty stumped. I guess you could try messing with your randomseed (using math.randomseed), but other than that I don’t have any other ideas.
UPDATE: I tried making it super random by randomizing the maxx, minx, minz, and maxz, and THEN making the random number using the newer values, however it still didn’t work, here’s the relevant snippet from the code:
if isStudio == true then
while true do
if rolls >= studiomaxrolls then
Template:Destroy()
script:Destroy()
end
rolls = rolls + 1
local minx2 = math.random(minx - 50, minx + 50)
local maxx2 = math.random(maxx - 50, maxx + 50)
local minz2 = math.random(minz - 50, minz + 50)
local maxz2 = math.random(maxz - 50, maxz + 50)
local ranx = math.random(minx2, maxx2)
local ranz = math.random(minz2, maxz2)
-- print (ranx .. "," .. y .. "," .. ranz)
local Clone = Template:Clone()
Clone:SetPrimaryPartCFrame(CFrame.new(ranx, y, ranz))
Clone.Parent = script.Parent
end
end
Yep! It returns numbers in the range [0.0,1.0) that aren’t integers. With some math, those numbers can be turned into non-integer numbers between the given range.
local Template = script.Parent:FindFirstChildWhichIsA("Model")
local PP = Template.HumanoidRootPart
local x = PP.Position.X
local y = PP.Position.Y
local z = PP.Position.Z
local minx = x - 500
local maxx = x + 500
local minz = z - 750
local maxz = z + 750
local rolls = 0
local maxrolls = 100
local isStudio = false
local RunService = game:GetService("RunService")
if RunService:IsStudio() then
isStudio = true
end
local studiomaxrolls = 5
if isStudio == true then
while true do
if rolls >= studiomaxrolls then
Template:Destroy()
script:Destroy()
break
end
rolls = rolls + 1
math.randomseed(rolls)
local ranx = math.random()*(maxx-minx) + minx
local ranz = math.random()*(maxz-minz) + minz
print (ranx)
print (ranz)
local Clone = Template:Clone()
Clone.Parent = script.Parent
Clone:SetPrimaryPartCFrame(CFrame.new(ranx, y, ranz))
end
end
Output:
10:23:33.064 430.65828231356 - Server - test:50
10:23:33.065 -648.23510747763 - Server - test:51
10:23:33.066 -240.17694369361 - Server - test:50
10:23:33.067 494.14353829081 - Server - test:51
10:23:33.068 -337.13953443904 - Server - test:50
10:23:33.069 683.58567313776 - Server - test:51
10:23:33.070 -482.2025176584 - Server - test:50
10:23:33.070 -99.756102696435 - Server - test:51
10:23:33.071 316.29626754092 - Server - test:50
10:23:33.071 -489.27393228615 - Server - test:51
There’s still one more problem though, after the NPC is teleported, the HumanoidRootPart doesn’t move “in sync” with the rest of the body, causing the NPC to break.
See, I cut off a bit of the code to make it simpler to read. So basically what the full code does is it checks to see if I’m in studio or the client, and if I’m in the studio it basically duplicates the zombies 5x instead of 100x. This is the case because when you test things in studio, it turns your PC into the server, and my PC quite frankly isn’t as powerful as the big one at Roblox (their own servers)