Give and Remove Tools with Teams

Hello, here’s what I’d like to do

  • I have a tool called ClassicSword in ServerStorage.
  • When they are on the Lobby Team (auto-assigned when they join the game and when they touch the lobby area parts), I don’t want them to have this tool
  • When they are on the Fighting Team (auto-assigned when they touch the game area parts), I want them to have tool (backpack)
    I think I have to clone the part from server storage and set its parent to the player’s backpack. Here is the script where the teams are assigned, perhaps you may want to use this?
local gamespawn = game.Workspace.Map.Floor
local lobbyspawn = game.Workspace.Lobby.Floor
local fighting = game.Teams.Fighting
local lobby = game.Teams.Lobby
local Sword = game.ServerStorage.ClassicSword
gamespawn.Touched:Connect(function(hit)
	local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
	if plr then
		plr.Team = fighting	
	end
end)
lobbyspawn.Touched:Connect(function(hit)
	local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
	if plr then
		plr.Team = lobby	
	end
end)

First problem, don’t use the .Touched event for detecting when people are in certain zones, it’s unreliable.
Instead you can use spacial queries to detect players in an area (although you’d have to use a loop)

Secondly, all you have to do if give the player the tool, or remove it, when the team gets switched.
For example:

(edited to remove a useless check because im dumb)

local sword = game:GetService("ServerStorage").Sword -- used for the example

local gamespawn = game.Workspace.Map.Floor
local lobbyspawn = game.Workspace.Lobby.Floor
local fighting = game.Teams.Fighting
local lobby = game.Teams.Lobby
gamespawn.Touched:Connect(function(hit)
		local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
		local humanoid = hit.Parent.humanoid
		if plr then
			plr.Team = fighting
			humanoid:EquipTool(sword:Clone()) -- clones the sword and puts it in the player's hand.
	end
end)
lobbyspawn.Touched:Connect(function(hit)
		local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
		if plr then
			plr.Team = lobby
			local findswordincharacter = hit.Parent:FindFirstChild("Sword") --checks if the player is currently holding the sword, if they are it will be inside their character.
			local findswordinbackpack = plr.Backpack:FindFirstChild("Sword") --checks if the player is not holding the sword, therefore it would be inside their backpack.
			if findswordincharacter then
				findswordincharacter:Destroy() --since we found the sword in the character we delete it.
			elseif findswordinbackpack then
				findswordinbackpack:Destroy() -- since we found the sword in the player's backpack we delete it.
			else
				print("no sword found!") -- In the scenario the player somehow doesnt have a sword (which is possible due to touch events sometimes not working!)
		end
	end
end)

1 Like

Great, thanks so much! I will look more into “spacial queries” and find a way to implement these. Once again, thank you!

Try cloning the tool to the player’s backpack when they touch the part
Example"

part.Touch:Connect(function(playerThatTouched)
    local sword = game.ReplicatedStorage.ClassicSword:Clone()
sword.Parent = game.Players[tostring(playerThatTouched)].PlayerBackpack
end)

No problem!
Basically what you’d do if use the GetPartsInBounds and check if some of them belong to a player character. This is much more precise than the .Touched event!

1 Like

Here’s a spatial query example.

local Game = game
local Workspace = workspace
local RunService = Game:GetService("RunService")
local Players = Game:GetService("Players")
local Teams = Game:GetService("Teams")
local RedTeam = Teams.RedTeam
local BlueTeam = Teams.BlueTeam
local RedSpawn = Workspace.RedSpawn --Transparent, uncollidable box.
local BlueSpawn = Workspace.BlueSpawn --Transparent, uncollidable box.

local function OnRenderStep()
	local RedParts = Workspace:GetPartsInPart(RedSpawn)
	for _, RedPart in ipairs(RedParts) do
		local Model = RedPart:FindFirstAncestorOfClass("RedModel")
		if not Model then continue end
		local Player = Players:GetPlayerFromCharacter(Model)
		if Player then Player.Team = RedTeam end
	end
	
	local BlueParts = Workspace:GetPartsInPart(RedSpawn)
	for _, BluePart in ipairs(BlueParts) do
		local Model = BluePart:FindFirstAncestorOfClass("RedModel")
		if not Model then continue end
		local Player = Players:GetPlayerFromCharacter(Model)
		if Player then Player.Team = BlueTeam end
	end
end

RunService.RenderStepped:Connect(OnRenderStep)

Here’s a slightly modified version:

local Game = game
local Workspace = workspace
local RunService = Game:GetService("RunService")
local Players = Game:GetService("Players")
local Teams = Game:GetService("Teams")
local RedTeam = Teams.RedTeam
local BlueTeam = Teams.BlueTeam
local RedSpawn = Workspace.RedSpawn --Transparent, uncollidable box.
local BlueSpawn = Workspace.BlueSpawn --Transparent, uncollidable box.

local function OnRenderStep()
	local RedParts = Workspace:GetPartsInPart(RedSpawn)
	local BlueParts = Workspace:GetPartsInPart(BlueSpawn)
	
	for _, Player in ipairs(Players:GetPlayers()) do
		local Character = Player.Character
		if not Character then continue end
		for _, Child in ipairs(Character:GetChildren()) do
			if not (Child:IsA("BasePart")) then continue end
			if table.find(RedParts, Child) then Player.Team = RedTeam break end
			if table.find(BlueParts, Child) then Player.Team = BlueTeam break end
		end
	end
end

RunService.RenderStepped:Connect(OnRenderStep)