I have a respawning crate, that when broken, respawns (obviously) So I need to get all characters in the game, and make sure none of them are within 10 studs of the crate. (so the crate doesn’t spawn on them) I have some code, but not enough - my code -
local PlrCount = nil
for i, plr in ipairs(game.Players:GetChildren()) do
PlrCount += 1
local Character = plr.Character
local position = Character.HumanoidRootPart.Position - script.Parent.MainOrigin.Position
local magnitude = position.magnitude
print(magnitude)
end
local PlrCount = nil
for i, plr in ipairs(game.Players:GetChildren()) do
PlrCount += 1
local Character = plr.Character
local position = Character.HumanoidRootPart.Position - script.Parent.MainOrigin.Position
local magnitude = position.magnitude
print(magnitude)
if magnitude <= 10 then -- only for one player, not all, right?
--put code here
end
end
Your looping through the players so it will check each player’s magnitude one by one.
--// Services
local Players = game:GetService("Players")
--// For Loop
for _, player in ipairs(Players:GetPlayers()) do
if player and player:IsDescendantOf(Players) then
local Character = player.Character
local Magnitude = (Character.HumanoidRootPart.Position - script.Parent.MainOrigin.Position).magnitude
if Magnitude <= 10 then
-- In range!
end
end
end
Here’s a slightly cleaned up version of your code:
local Players = game:GetService("Players")
local mainOrigin = script.Parent.MainOrigin
local DISTANCE_THRESHOLD = 10
for _, player in ipairs(Players:GetPlayers()) do
local character = player.Character
if not character then
continue
end
local distanceFromOrigin = (character.PrimaryPart.Position - mainOrigin.Position).Magnitude
if distanceFromOrigin <= DISTANCE_THRESHOLD then
--put code here for players that are close to mainOrigin
end
end
return will exit the function without continuing if it’s inside a function, but will throw an error if it’s not in a function. continue is the right keyword I wanted. Good catch! (Fixed my code snippet now)
Here’s an example of how you can integrate this into a spawning system:
A spawning system using Magnitude checks:
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DISTANCE_THRESHOLD = 10
local spawns: { BasePart } = Workspace.Spawns:GetChildren()
local cratePrefab: BasePart = ReplicatedStorage.Crate
local crateContainer = Workspace
local function spawnCrate(spawnPart: BasePart)
local crate = cratePrefab:Clone()
crate.CFrame = spawnPart.CFrame
crate.Parent = crateContainer
end
local function getNearbyPlayer(position: Vector3, maxDistance: number)
for _, player in ipairs(Players:GetPlayers()) do
local character = player.Character
if not character then
continue
end
local distanceFromOrigin = (character.PrimaryPart.Position - position).Magnitude
if distanceFromOrigin <= maxDistance then
return player
end
end
-- No players are within maxDistance of position
return nil
end
local function getValidSpawn()
for _, spawnPart in ipairs(spawns) do
local nearbyPlayer = getNearbyPlayer(spawnPart.Position, DISTANCE_THRESHOLD)
if not nearbyPlayer then
return spawnPart
end
end
-- No valid spawn was found, default to a random spawn
return spawns[math.random(#spawns)]
end
-- Usage:
spawnCrate(getValidSpawn())
Alternatively, you can do it with :GetPartBoundsInRadius():
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DISTANCE_THRESHOLD = 10
local spawns: { BasePart } = Workspace.Spawns:GetChildren()
local cratePrefab = ReplicatedStorage.Crate
local crateContainer = Workspace
local overlapParams = OverlapParams.new()
overlapParams.FilterType = Enum.RaycastFilterType.Whitelist
overlapParams.MaxParts = 1
local function getHumanoidRootParts()
local humanoidRootParts = {}
for _, player in ipairs(Players:GetPlayers()) do
if player.Character then
table.insert(humanoidRootParts, player.Character.PrimaryPart)
end
end
return humanoidRootParts
end
local function spawnCrate(spawnPart: BasePart)
local crate = cratePrefab:Clone()
crate.CFrame = spawnPart.CFrame
crate.Parent = crateContainer
end
local function isPlayerNearby(position: Vector3, maxDistance: number)
overlapParams.FilterDescendantsInstances = getHumanoidRootParts()
local nearbyPlayerRootParts = Workspace:GetPartBoundsInRadius(position, maxDistance, overlapParams)
return #nearbyPlayerRootParts ~= 0
end
local function getValidSpawn()
for _, spawnPart in ipairs(spawns) do
if not isPlayerNearby(spawnPart.Position, DISTANCE_THRESHOLD) then
return spawnPart
end
end
-- No valid spawn was found, default to a random spawn
return spawns[math.random(#spawns)]
end
-- Usage:
spawnCrate(getValidSpawn())
So when testing, It works, (yay) but when 2 player testing, I moved the second player right next to the crate, destroyed it, and it respawned. I think it respawned because the first player was farther than 10 studs, and the second was inside 10 studs. The code checked and made sure that the first player was further than 10 studs, then proceeded with code. :\
Close, I could do that, but then I would have to make a part surrounding the crate, correct, And There will be lots of crates in the game, so the surrounding parts would get annoying when developing, Though I could spawn a part around the MainOrigin…
in this code, the char.PrimaryPart is the part you want to find right? Is there a way to do that but with all parts named HumanoidRootPart?
function getParams(char,parameterpart)
if table.find(workspace:GetPartsInPart(parameterpart),char.PrimaryPart) then
print(Char.Name.." found in "..parameterpart.Name)
return true
end
end
if getParams(character,part) == true then
-- does what i want the script to do here
end
function getParams(char,parameterpart)
if table.find(workspace:GetPartsInPart(parameterpart),char.PrimaryPart) then
print(Char.Name.." found in "..parameterpart.Name)
return true
end
end
for _,Player in pairs(game.Players:GetPlayers()) do
local character = Player.Character
if getParams(character,part) == true then
-- does what i want the script to do here
end
end
local Enumeration = Enum
local Game = game
local Workspace = workspace
local Players = Game:GetService("Players")
local Radius = 10 --Change to desired radius.
local function CheckDistanceFromCrate(Crate) --This function expects the 'crate' being spawned as an argument.
local Parameters = OverlapParams.new()
Parameters.FilterDescendantsInstances = {Crate}
Parameters.FilterType = Enumeration.RaycastFilterType.Blacklist
local Parts = Workspace:GetPartsBoundsInRadius(Crate.Position, Radius, Parameters)
for _, Part in ipairs(Parts) do
local Model = Part:FindFirstAncestorOfClass("Model")
if not Model then continue end
local Humanoid = Model:FindFirstChildOfClass("Humanoid")
if (not Humanoid) or Humanoid.Health <= 0 then continue end
local Player = Players:GetPlayerFromCharacter(Model)
if not Player then continue end
local Delta = (Model:GetPivot().Position - Crate.Position) --Gets difference of two vectors.
local Direction = Delta.Unit --Gets direction of crate to player's character.
local Distance = Delta.Magnitude --Gets distance between crate and player's character.
Model:PivotTo(Model:GetPivot() + (Direction * (10 - Distance))) --Moves character away from the crate so that they are 10 studs away.
end
end