Spawning Mob with my distance code?

So im trying to spawn a mob when a player is within a certain distance of a part. My code is probably REALLY wrong haha but I get no errors, its just nothing happens.

My plan in the future is to detect the players level and spawn a different mob based on that level but for now im just trying to learn the basics of spawning the mob.

Here is my code.

local pos1 = workspace.Plots.Plots1.DistanceChcker.Position
local pos2 = game:GetService("Players").LocalPlayer

    local distance = (pos1 - pos2).Magnitude

    local monster = game:GetService("ReplicatedStorage").Mobs.Mobtest1

    local function SpawnMob()
    	local plateSize = workspace.Plots.Plot1.Size
    	local mob = monster:Clone()
    	
    	local randomX = math.random(plateSize.X / -2)
    	local randomZ = math.random(plateSize.Z / -2)
    	mob.Position = Vector3.new(randomX , 9, randomZ)
    	
    	if distance <= 25 then
    		print("hi")
    		SpawnMob()
    	end
	
end

You can’t run the same function inside the function.

didnt work outside function either, i moved it in just to test

Yeah, becuase it only runned once. Call the function inside a while loop and don’t forget wait().

I tried fixing up some of the mistakes you made within the code for you.


local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Monster = ReplicatedStorage.Mobs.Mobtest1
local Plate = workspace.Plots.Plot1
local Position = workspace.Plots.Plots1.DistanceChcker.Position

local Distance = 25
local Cooldown = 5

local function SpawnMob()
	local PlateSize = Plate.Size
	local CloneMonster = Monster:Clone()
	local RandomX = math.random( -- Randomize the spawn area by adding in the plate position and its size.
		math.floor(PlateSize.Position.X - PlateSize.X),  -- math.random won't work if the number has decimals in it. Using math.floor returns the largest integer less than or equal to a given number.
		math.floor(PlateSize.Position.X + PlateSize.X))
	local RandomZ = math.random(
		math.floor(PlateSize.Position.Z - PlateSize.Z), 
		math.floor(PlateSize.Position.Z + PlateSize.Z))
	CloneMonster.Position = Vector3.new(RandomX , 9, RandomZ)
end


local function CalculateResult()
	for _,Player in pairs(game.Players:GetChildren()) do
		if Player.Character -- Get all of the player within the game.
			and Player.Character:FindFirstChild("HumanoidRootPart")
			and (Position - Player.Character.HumanoidRootPart.Position).Magnitude <= Distance -- Check the distance of each player
		then
			return false -- return false if someone is in the zone
		end
	end
	return true  -- return true if someone is NOT in the zone
end

while wait(Cooldown) do
	local IsNotInPosition = CalculateResult() -- the functions either return true or false base on its condition
	if IsNotInPosition then
		print("hi")
		SpawnMob()
	end
end

Hope this helps!

Ahhh ok so 2 functions, 1 to spawn the mob the other much more complicated to determine if a player is within the correct distance, thanks so much for taking the time, I can learn a lot from this

something isn’t working, can’t figure out what it is. fixed afew typos but still nothing. It doesn’t seem to be detecting the player nearby

I think I kinda made a lot of mistakes, sorry. I kinda forgot to run the script because I overlooked at my scripting skill lol. Alright I’ve fixed up most of the stuff, here it is.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Monster = ReplicatedStorage.Mobs.Mobtest1
local Plate = workspace.Plots.Plot1
local Position = Plate.Position

local Distance = 25
local Cooldown = 1

local function SpawnMob()
	local PlateSize = Plate.Size
	local CloneMonster = Monster:Clone()
	local RandomX = math.random( -- Randomize the spawn area by adding in the plate position and its size.
		math.floor(Position.X - PlateSize.X/2),  -- math.random won't work if the number has decimals in it. Using math.floor returns the largest integer less than or equal to a given number.
		math.floor(Position.X + PlateSize.X/2))
	local RandomZ = math.random(
		math.floor(Position.Z - PlateSize.Z/2), 
		math.floor(Position.Z + PlateSize.Z/2))
	CloneMonster.HumanoidRootPart.CFrame = CFrame.new(RandomX , 9, RandomZ)
	CloneMonster.Parent = workspace
end


local function CalculateResult()
	for _,Player in pairs(game.Players:GetChildren()) do
		if Player.Character -- Get all of the player within the game.
			and Player.Character:FindFirstChild("HumanoidRootPart")
			and (Position - Player.Character.HumanoidRootPart.Position).Magnitude <= Distance -- Check the distance of each player
		then
			return false -- return false if someone is in the zone
		end
	end
	return true  -- return true if someone is NOT in the zone
end

while wait(Cooldown) do
	local IsNotInPosition = CalculateResult() -- the functions either return true or false base on its condition
	if IsNotInPosition then
		print("hi")
		SpawnMob()
	end
end

If you ever need an explanation on some of these stuff just message me. Once again I apologised for the mistakes that I’ve made :sweat_smile:.

Thanks for getting back to me, these threads often go dead after the first reply haha, ill try this out and see how things go. The big part i dont understand is that your calculating if the player is/isnot in range but then later in the code your “IsNotInPosition” is being called regardless of the calculated results? where is it determining that if the player is within range it then spawns.

while wait(Cooldown) do
	local IsNotInPosition = CalculateResult() 
	if IsNotInPosition then <- HERE it doesn't seem to matter if its true or false?
		print("hi")
		SpawnMob()
...
-- This is where it determines the range of each players and compare it to the appropriated distance.
and (Position - Player.Character.HumanoidRootPart.Position).Magnitude <= Distance 
...

Oh and IsNotInPosition does matter. It is a function that returns something to a variable. It is a bit confusing but once you’re get a hang of it, it is pretty useful yes. Here is a pretty simple example of a function that returns something to a variable.

local function ReturnValue()
	return true
end

print(ReturnValue()) --> true

if ReturnValue() then -- Only prints if ReturnValue() is true which it is.
    -- Same thing I used in the spawning mob code.
    print("True") 
end

Ohhh so I could use a similar setup whenever I want a function to execute if the condition is true?
I want my mobs to spawn if the player is inside the 25 radius, so i would swap the calculateresults to return true for ```
(Position - Player.Character.HumanoidRootPart.Position).Magnitude <= Distance’

Since nothing happens still regardless, I must have something wrong with how my players being detected, or would this only work on a live version of the game and not studio?

Ohhhh I see what you mean, If you’re planning to makes the mob spawn in the range if player is also in the range then you might need to do some small changes.


local function CalculateResult()
	for _,Player in pairs(game.Players:GetChildren()) do
		if Player.Character -- Get all of the player within the game.
			and Player.Character:FindFirstChild("HumanoidRootPart")
			and (Position - Player.Character.HumanoidRootPart.Position).Magnitude <= Distance -- Check the distance of each player
		then
			return true -- return true if someone is in the zone
		end
	end
	return false  -- return false if someone is NOT in the zone
end

while wait(Cooldown) do
	local IsInPosition = CalculateResult() -- the functions either return true or false base on its condition
	if IsInPosition then
		print("hi")
		SpawnMob()
	end
end

I switched the return true to false and vice versa, should do the trick.