I’ve recently put together a ‘PlayerTracker’ function that detects when a player enters a part, and I’m not ashamed to say I’ve spent a day or two trying to perfect it.
I’m making the function for a Hardpoint game that I am creating for fun, and to learn a little bit more about programming and best practices. If you do not know what a Hardpoint game is, here is an overview I found on a Call of Duty wiki page.
As you will see, I am not using the BasePart.Touched / BasePart.TouchEnded events, as I found early on that they arent very reliable. I also know that ZonePlus exists, but I would rather not use this in my game as I would only use it for what I am trying to do here, and so it would be a waste of performance.
local Players = game:GetService("Players")
local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
local function PlayerTracker()
local PlayersInPart = {}
for _, Part in pairs(CollectionService:GetTagged("Hardpoint")) do
local PlayersCurrentlyIn = {}
local TouchingParts = workspace:GetPartsInPart(Part)
for I, TouchingPart in pairs(TouchingParts) do
local Player
local Humanoid = TouchingPart.Parent:FindFirstChild("Humanoid")
if Humanoid then
local Player = Players:GetPlayerFromCharacter(TouchingPart.Parent)
if Player then
PlayersCurrentlyIn[Player] = true
end
end
end
PlayersInPart[Part] = PlayersCurrentlyIn
end
return PlayersInPart
end
local TrackPlayerHandle = RunService.Heartbeat:Connect(PlayerTracker)
The reason for this post is so I can ask if I am going about this the right way? My initial plan was to add the players to a table to keep track of them, but then I realised I needed to know what team they were on so that I could work out whether or not the zone was contested, and so that I can speed up the capture depending on how many people are in the zone.
What would be the best way of doing this? Do I keep the player table, then loop through it and get the players teams? Or create a new table and insert the players names under their team name?
I’d appreciate any help you can give on this, and any recommendations on where I can optimise my code.
local Team1, Team2 = 0, 0
for Player, Team in next, PlayersInPoint() do
if Team == "Team 1" then
Team1 += 1
elseif Team == "Team 2" then
Team2 += 1
end
end
print("Team 1: " .. Team1 .. " - Team2: " .. Team2)
if Team1 > 0 and Team2 > 0 then
print("Contested")
elseif Team1 > 0 and Team2 == 0 then
print("Team 1")
elseif Team2 > 0 and Team1 == 0 then
print("Team 2")
end
For some reason ‘Team1’ and ‘Team2’ aren’t being added to.
local Players = game:GetService("Players")
local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
local function PlayersInPoint()
local PlayersInPoint = {}
for _, Part in pairs(CollectionService:GetTagged("Hardpoint")) do
local PlayersCurrentlyIn = {}
local TouchingParts = workspace:GetPartsInPart(Part)
for I, TouchingPart in pairs(TouchingParts) do
local Player
local Humanoid = TouchingPart.Parent:FindFirstChild("Humanoid")
if Humanoid then
local Player = Players:GetPlayerFromCharacter(TouchingPart.Parent)
if Player then
PlayersCurrentlyIn[Player.Name] = Player.Team
end
end
end
PlayersInPoint[Part.Name] = PlayersCurrentlyIn
end
return PlayersInPoint
end
local TrackPlayerHandle = RunService.Heartbeat:Connect(function()
local Team1, Team2 = 0, 0
for Player, Team in next, PlayersInPoint() do
if Team == "Team 1" then
Team1 += 1
elseif Team == "Team 2" then
Team2 += 1
end
end
print("Team 1: " .. Team1 .. " - Team2: " .. Team2)
if Team1 > 0 and Team2 > 0 then
print("Contested")
elseif Team1 > 0 and Team2 == 0 then
print("Team 1")
elseif Team2 > 0 and Team1 == 0 then
print("Team 2")
end
end)
Oh right, you need to loop through all the points first
local Team1, Team2 = 0, 0
for _, Point in next, PlayersInPoint() do
for Player, Team in next, Point do
if Team == "Team 1" then
Team1 += 1
elseif Team == "Team 2" then
Team2 += 1
end
end
end
This would get you all the players on a team across every hardpoint location in your game. If you want it to be per location you’d need to loop through the points and move the Team1, Team2 variables inside of it and handle it separately.
Hello again, I’ve now decided this is what I’d like to do with my code:
This would get you all the players on a team across every hardpoint location in your game. If you want it to be per location you’d need to loop through the points and move the Team1, Team2 variables inside of it and handle it separately.
Though I don’t quite understand how I could do it as you mention above. Would I do this in my PlayersInPoint function or my loop?