Hello everyone, I am trying to create a capture the flag game, and I only want the opposite team to be able to pick up the other teams flag. For example, Red team can pick up the blue teams flag but blue team cant pick up their own flag. I’m not really sure on how to do this as I am fairly new to scripting.
Usually The logic script is on ServerScriptService and you need to use Script (not LocalScript)
You can use the if statement to determine the Player.Team instance property
Like .
-- I dont know what your logic and way is
-- This is how to check which team Player is in
local Players = game:GetService("Players")
local tool = workspace:WaitForChild("XXX") -- your tool name
-- Then Code Prompt Logic
However, it’s a best practice to look through the API documentation
Tool | Document - Roblox Creator Hub
Lua 5.0 Reference Manual - contents
is your flag just a simple TouchInterest tool or does it use a ClickDetector or some other method?
My flag is just a touch intrest tool
just use BasePart.Touched event connect to get Character’s part and check from Players:GetPlayerFromCharacter()
I tried to make it but it doesnt work, here is the script that i made(sorry for the late response I was on a trip and didn’t have wifi):
local players = game:GetService(“Players”)
local Red_flag = workspace:WaitForChild(“RedFlag”)
local teams = game:GetService(“Teams”)
Red_flag.Touched:connect(function(hit)
local Humanoid = hit.Parent:FindFirstChild("Humanoid")
if hit.Parent == Humanoid then
local player = players:GetPlayerFromCharacter("RedFlag")
if Humanoid.Team == teams.Blue and not player:FindFirstChild("Red_flag") then
local Flag = game.ServerStorage:FindFirstChild("Red_flag")
Flag.Parent = player.Backpack
elseif Humanoid.Team == teams.Red then
player.Backpack:WaitForChild("Red_flag")
if player.Backpack:WaitForChild("Red_flag") then
player.Backpack:WaitForChild("Red_flag"):Destroy()
end
end
end
end)
oops Humanoid does not have the attribute Team, it is in a Player instance in Players and also you can get player’s character from Players:GetPlayerFromCharacter() (You need finding its parent) But as for I know. BasePart.Touched will return a basepart instance and maybe it doesnt hava parent. so replace your code
local Humanoid = hit.Parent:FindFirstChild("Humanoid") with
local hit_parent = hit:FindFirstAncestorWhichIsA("Model")
local Humanoid = hit_parent and hit_parent:FindFirstChild("Humanoid") or nil
You can do it like so:
tool.Touched:Connect(function(hit)
local hum = hit.Parent:FindFirstChild(“Humanoid”)
if hum then
local char = hum.Parent
local player = char:GetPlayerFromCharacter()
local team = player.Team
if team.Name == “Red” then
local newTool = tool:Clone()
newTool.Parent = player.Backpack
end
end
end)
This should work and im sorry if it doesnt and ill try to help more ![]()
I tried this, but it still kept on giving the flag to Red team, even after I changed the if statement to:
if team.Name == “Blue”
I tried this but it still didn’t work.
Here is a video of the problem
Disable the default picked up functionality of the tool, and add a script to the handle of the tool.
Use a part.Touched event and check if it is a player and of the correct team, and if so, parent the tool to their character model.
Put this script in a part that the players touch to get a flag, and change the requiredTeam and givenTool variable as needed
--[[ Variables ]]--
-- Services --
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Teams = game:GetService("Teams")
-- Giver --
local requiredTeam = Teams["team name here"] -- The team that can pick up the flag
local givenTool = ServerStorage["tool name here"]
local function playerHasTool(player : Player) : boolean
local backpackTool = player.Backpack:FindFirstChild(givenTool.Name)
if backpackTool ~= nil then
return true
end
local characterTool = player.Character:FindFirstChild(givenTool.Name)
if characterTool ~= nil then
return true
end
return false
end
local function onTouched(hitPart : BasePart) : ()
-- Check for a valid player character
local player = Players:GetPlayerFromCharacter(hitPart.Parent)
if player == nil or player.Team ~= requiredTeam then
return
end
-- Don't give out a flag if they already have one
if playerHasTool(player) then
return
end
-- Give out the tool
local tool = givenTool:Clone()
tool.Parent = player.Backpack
end
script.Parent.Touched:Connect(onTouched)
can you show your code now?
I think it’s the problem of if
But now that it can be picked up, it’s also a step forward
uhh I read your previous code and I recommend you to learn the unified code style and don’t overdesign. There’s a lot of your code that baffles me
local Players = game:GetService("Players")
local RedFlag = workspace:WaitForChild("RedFlag")
local RedFlagName = RedFlag.Name
local Teams = game:GetService("Teams")
local RED_FLAG = 0
local BLUE_FLAG = 1
local function PlayerCanHaveWhichATool(player: Player)
if player.Team == Teams.Blue then
return RED_FLAG
else
return BLUE_FLAG
end
end
local function PlayerEquipTool(player: Player, tool: Tool)
tool.Parent = player.Backpack
end
local function GetPlayerFlag(player: Player, flagName: string)
local backpack = player.Backpack
local character = player.Character
local equippedRedFlag = character:FindFirstChild(flagName)
local unequippedRedFlag = backpack:FindFirstChild(flagName)
return equippedRedFlag or unequippedRedFlag
end
local function RedFlag_onTouched(hitPart: BasePart)
local hitPart_Parent = hitPart:FindFirstAncestorWhichIsA("Model")
local humanoid = hitPart_Parent and hitPart_Parent:FindFirstChild("Humanoid") or nil
if not humanoid then
return
end
local player = Players:GetPlayerFromCharacter(hitPart_Parent)
if PlayerCanHaveWhichATool(player) == RED_FLAG then
local ThisPlayer_hasRedFlag = GetPlayerFlag(player, RedFlag.Name)
if ThisPlayer_hasRedFlag then
ThisPlayer_hasRedFlag:Destroy()
end
return
else
if GetPlayerFlag(player, RedFlag.Name) then
return
end
PlayerEquipTool(player, RedFlag)
end
end
RedFlag.Touched:Connect(RedFlag_onTouched)
The bad of your code:
- Your goal is to get another Workspace tool in ServerStorage, it’s redundant, you either destroy the Workspace tool and make a copy of the ServerStorage tool, or just use the Workspace tool
- Don’t overdo it
- Your code logic is not clear enough
- Unknown destruction of Team Red player Flag when Team Red player touched
- Abusing FindFirstChild and WaitForChild is a bad thing
workspace.ToolThis will point to the original Tool, it is a pointer- The original Tool will only be deleted when equipped
- The children and parents of the instance tree are pointers because Roblox can only give pointers to instances
- RobloxService name according to CamelCase
- Sometimes hit is not necessarily a child under the player
- Need to check the parent of the hit This will be good for you in future updates Often a lot of errors are caused by the early stages
This worked! Also is there any documentation I can read to get some better understanding of the code?
If there’s anything in particular you’d like me to explain, I can do so
just this function and I am also wondering why did you use colons in the argument and what they do :local function playerHasTool(player : Player) : boolean
local backpackTool = player.Backpack:FindFirstChild(givenTool.Name)
if backpackTool ~= nil then
return true
end
local characterTool = player.Character:FindFirstChild(givenTool.Name)
if characterTool ~= nil then
return true
end
return false
end
In simple terms, it’s type checking notation. It doesn’t do anything except tell the autocomplete what you’re working with.
local player : Player = ... --// The autocomplete will treat this variable as a player
local playerHumanoid : Humanoid = player.Character.Humanoid --// Ditto, but with humanoids
It’s not something I’d say is necessary to learn, but I like doing it because it saves me some time.
Learn more here
If you’re going to critique someone’s code, at least be constructive. None of your bullet points are explained very well, if at all.
Really? Do better.
