I’m currently working on a horror game inspired by apple pie, but I’ve ran into a issue. I’m not sure how to have the monster spawn at either certain parts, to simulate it having a 360 range around the player that it can spawn from. Or have it spawn randomly around the player using math.random of some sort.
I’m not sure what would be the better practice, or how to do either. So how would I go about doing either one? Either way, Thank you to anyone who helps.
As in this picture, you have points, [ spawn 1, spawn 2, spawn 3, spawn 4 ], I’m trying to make a monster randomly spawn on one of those 4 points.
In the picture below, you have a circle of which the monster can spawn anywhere along it.
Create a Part named CampCenter in Workspace
Move the monster to ReplicatedStorage and name it Monster
Create a Script in ServerScriptService containing this code:
local Workspace = game:GetService("Workspace")
local CollectionService = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local campCenter = Workspace.CampCenter
local monster = ReplicatedStorage.Monster
local AMOUNT_OF_SPAWNS = 16
local AMOUNT_OF_MONSTERS = 4
local RADIUS = 32
local random = Random.new()
local function createSpawnParts(amount, radius)
for i = 1, amount do
local spawnPart = Instance.new("Part")
spawnPart.Anchored = true
spawnPart.CanCollide = false
spawnPart.Size = Vector3.new(1, 1, 1)
local angle = math.rad((360 / amount) * i)
local x = radius * math.cos(angle)
local y = radius * math.sin(angle)
spawnPart.CFrame = CFrame.new(campCenter.Position + Vector3.new(x, 0, y))
spawnPart.Transparency = 1
spawnPart.Name = "MonsterSpawnPart"
spawnPart.Parent = Workspace
spawnPart:AddTag("MonsterSpawnPart")
spawnPart:SetAttribute("MonsterUsingSpawn", false)
end
end
local function spawnMonsters(amount)
local monsterSpawnPoints = CollectionService:GetTagged("MonsterSpawnPart")
for _ = 1, amount do
local attempts = 0
while attempts < (#monsterSpawnPoints) * 2 do
local randomIndex = random:NextInteger(1, #monsterSpawnPoints)
local randomSpawn = monsterSpawnPoints[randomIndex]
local isMonsterUsingSpawn = randomSpawn:GetAttribute("MonsterUsingSpawn")
if not isMonsterUsingSpawn then
local monsterClone = monster:Clone()
randomSpawn:SetAttribute("MonsterUsingSpawn", true)
monsterClone:PivotTo(randomSpawn.CFrame)
monsterClone.Parent = Workspace
monsterClone.HumanoidRootPart.Anchored = false
break
else
attempts = attempts + 1
end
end
if #monsterSpawnPoints == 0 then
break
end
end
end
monster.HumanoidRootPart.Anchored = true
createSpawnParts(AMOUNT_OF_SPAWNS, RADIUS)
spawnMonsters(AMOUNT_OF_MONSTERS)
You must’ve copied my script wrong because I never used anything called TimerService
Can you show what you pasted in the Script
Possible reasons why the script can’t find CampCenter
CampCenter is supposed to be a Part If it’s not a part, it won’t work.
CampCenter is supposed to have .Anchored set to true and .CanCollide set to false
CampCenter might have been spelled incorrectly like campCenter, camp center, Camp Center. It is supposed to be CampCenter with no spaces in between the words.
CampCenter must be a child of the Workspace service. Even if it’s a descendant but not a child, the script won’t work. So it must be a direct child of the Workspace service
If you could provide the Script, Explorer Window (showing CampCenter), Properties Window (Highlighting CampCenter), I will be able to help more.
Ah yes I see the problem.
Line 4
That’s not how you use :WaitForChild()
Moreover, you don’t even need :WaitForChild() in this case as this script is running with ServerRunContext
So all you want to do is change that line
Before:
local campCenter = game:WaitForChild(Workspace.CampCenter)
After:
local campCenter = Workspace.CampCenter
If you do want to use :WaitForChild() to learn how it works (which you should because it does have important uses)
:WaitForChild() basically has a name paramater and should be used like this Parent:WaitForChild(name)
So in this case you could do:
local campCenter = Workspace:WaitForChild("CampCenter")
The name parameter should be a string, strings should be surrounded by quotation marks.
To learn more about this topic check these resources:
Change the code to this as I was using a deprecated feature, sorry.
local Workspace = game:GetService("Workspace")
local CollectionService = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local campCenter = Workspace.CampCenter
local monster = ReplicatedStorage.Monster
local AMOUNT_OF_SPAWNS = 16
local AMOUNT_OF_MONSTERS = 4
local RADIUS = 32
local random = Random.new()
local function createSpawnParts(amount, radius)
for i = 1, amount do
local spawnPart = Instance.new("Part")
spawnPart.Anchored = true
spawnPart.CanCollide = false
spawnPart.Size = Vector3.new(1, 1, 1)
local angle = math.rad((360 / amount) * i)
local x = radius * math.cos(angle)
local y = radius * math.sin(angle)
spawnPart.CFrame = CFrame.new(campCenter.Position + Vector3.new(x, 0, y))
spawnPart.Transparency = 1
spawnPart.Name = "MonsterSpawnPart"
spawnPart.Parent = Workspace
spawnPart:AddTag("MonsterSpawnPart")
spawnPart:SetAttribute("MonsterUsingSpawn", false)
end
end
local function spawnMonsters(amount)
local monsterSpawnPoints = CollectionService:GetTagged("MonsterSpawnPart")
for _ = 1, amount do
local attempts = 0
while attempts < (#monsterSpawnPoints) * 2 do
local randomIndex = random:NextInteger(1, #monsterSpawnPoints)
local randomSpawn = monsterSpawnPoints[randomIndex]
local isMonsterUsingSpawn = randomSpawn:GetAttribute("MonsterUsingSpawn")
if not isMonsterUsingSpawn then
local monsterClone = monster:Clone()
randomSpawn:SetAttribute("MonsterUsingSpawn", true)
monsterClone:PivotTo(randomSpawn.CFrame)
monsterClone.Parent = Workspace
monsterClone.HumanoidRootPart.Anchored = false
break
else
attempts = attempts + 1
end
end
if #monsterSpawnPoints == 0 then
break
end
end
end
monster.HumanoidRootPart.Anchored = true
createSpawnParts(AMOUNT_OF_SPAWNS, RADIUS)
spawnMonsters(AMOUNT_OF_MONSTERS)
The problem with the original code was that I was using :SetPrimaryPartCFrame() which is deprecated and also doesn’t work if Model.PrimaryPart is set to nil. I changed it to :PivotTo() which uses the pivot tools and works for parts, models, and other PVInstances. Even if the model’s PrimaryPart is set to nil, :PivotTo() still works.
Done! Thank you again, it means a lot. I’ll give the documentations a look to hopefully understand it better!
Side note, you did a great job explaining by the way, and amazing job helping me. By far one of the most wonderful users I’ve seen on devforum, not only kind, but helpful. I appreciate it a lot, and I hope you have a wonderful day.
Also, I’m going to try and add somethings to the script, would it be okay if I ask for some help regrading the script in dms if I can’t figure it out?