I want to make a flag capture system so whenever you stand in an area, it starts to capture it. I have done this so when a player touches a invisible part it captures the flag. Also, I want it to add a booster and take it away if that player isn’t still the one who has the flag captured.
The Issue is I cant get it to stop when the player leaves the zone or when someone if contesting the other player. How would I do this?
I have tried using .Magnitude by subtracting the flags base by the players HumanoidRootPart and I put this in a loop to check if they leave the zone but it didn’t work.
I am using a Tween to make the flag go up and down. I already have the booster being added to the player their is nothing in place to remove the booster from them if someone else captures the flag.
Code so far:
--//Services
local TS = game:GetService("TweenService")
--//Variables
local thumbType = Enum.ThumbnailType.AvatarBust
local thumbSize = Enum.ThumbnailSize.Size420x420
local touchPart = script.Parent.TouchPart
local flagMiddle = script.Parent.FlagMiddle
local flagSettings = flagMiddle.FlagSettings
local playerName = flagMiddle.Post.FlagDisplay.Frame.PlayerName
local raised = flagMiddle.Raised
local lowered = flagMiddle.Lowered
local playerImg1 = flagMiddle.FlagPart.Front.PlayerImg1
local playerImg2 = flagMiddle.FlagPart.Back.PlayerImg2
local claiming = false
local Info = TweenInfo.new(
10,
Enum.EasingStyle.Linear,
Enum.EasingDirection.In,
0,
true
)
touchPart.Touched:Connect(function(hit)
local char = hit.Parent
if char then
local plr = game.Players:GetPlayerFromCharacter(char)
local playerBoosts = plr:FindFirstChild("PlayerBoosts")
local activeBoosts = playerBoosts:FindFirstChild("ActiveBoosts")
local flagBoost = playerBoosts:FindFirstChild("FlagBoost")
if flagSettings.PlayerID.Value ~= plr.UserId then
if claiming == false then
claiming = true
local userId = plr.UserId
local content, isReady = game.Players:GetUserThumbnailAsync(userId, thumbType, thumbSize)
local LRtween = TS:Create(flagMiddle.FlagPart, Info, {Position = lowered.Position})
LRtween:Play()
playerName.Text = "Claiming..."
LRtween.Completed:Connect(function()
playerName.UnClaimed.Enabled = false
playerName.Claimed.Enabled = true
playerName.Text = plr.Name
playerImg1.Image = content
playerImg2.Image = content
flagSettings.PlayerName.Value = plr.Name
flagSettings.PlayerID.Value = plr.UserId
activeBoosts.Value += flagBoost.Value
claiming = false
end)
end
end
end
end)
Magntiude is being used correctly at the wrong place. Change the first .touched event into a while loop and check the distance of every player/entity capable of capturing. Adjust the capture progress according to who’s within distance of the capture point.
This is what I had originally getting everyone in the game and checking it based on that. I started out with having a local script that every render stepped it would fire the server and pass the player and char and on the server it would check if they are close enough based on that but I didn’t think firing the server that many times with the players would be good. I got this idea from the video attached but the problem with the scripts in that one is that their is no claim time or anyway to contest the flag. Changing the .Touched event wouldn’t allow me to get the character or the player unless I use the idea that I was talking about before. Is their maybe an alternative to get the players character or is the idea mentioned above the only way?
There are several ways to get the player’s character, the easiest is by going through the Players object.
local Characters = {}
for i,vPlayer in ipairs(game.Players:GetChildren())
if vPlayer.Character then
table.insert(Characters, vPlayer.Character)
end
end
This can be done on the server, preventing the need to use a local script at all.
I tried implementing what you said and it worked but I made a loop to check if the player leaves the zone and to pause the tween according to that. I can get it to pause but I cant figure out a way to break the loop whenever the Tween is done. I tried using Tween.Completed:Wait() but that would require another spawn function and would take it outside the while loop. How would I go about pausing the tween or maybe not even using a tween at all?
while true and wait(.2) do
for _, plr in ipairs(game.Players:GetChildren()) do
if plr.Character then
local char = plr.Character
local plr = game.Players:GetPlayerFromCharacter(char)
local playerBoosts = plr:FindFirstChild("PlayerBoosts")
local activeBoosts = playerBoosts:FindFirstChild("ActiveBoosts")
local flagBoost = playerBoosts:FindFirstChild("FlagBoost")
local LRtween = TS:Create(flagMiddle.FlagPart, Info, {Position = lowered.Position})
if (flagMiddle.Base.Position - char.HumanoidRootPart.Position).Magnitude <= 65 then
if flagSettings.PlayerID.Value ~= plr.UserId then
if claiming == false then
claiming = true
local userId = plr.UserId
local content, isReady = game.Players:GetUserThumbnailAsync(userId, thumbType, thumbSize)
LRtween:Play()
spawn(function()
while true and wait(.2) do
if not ((flagMiddle.Base.Position - char.HumanoidRootPart.Position).Magnitude <= 65) then
LRtween:Pause()
else
LRtween:Play()
end
end
end)
playerName.Text = "Claiming..."
LRtween.Completed:Connect(function()
playerName.Text = plr.Name
playerImg1.Image = content
playerImg2.Image = content
flagSettings.PlayerName.Value = plr.Name
flagSettings.PlayerID.Value = plr.UserId
activeBoosts.Value += flagBoost.Value
claiming = false
end)
end
end
end
end
end
end
You don’t need a loop within the loop to find out when a player leaves the capture radius. Just store all the players who were within capture distance last interval, and if they’re not within the capture distance in the current interval, cancel their capture progress.
You should also switch out tween.completed and instead check for a number value. Add to the capture number if the flag is being captured, subtract it if it isn’t. If the number goes over 100, that’ll count as fully captured.
I get what your saying and implemented the capture progress but I still cant find a way for the Tween to cancel. It says I’m canceling the tween but it doesn’t do anything because Im playing the tween inside of another if statement.
while true and wait(.2) do
for _, plr in ipairs(game.Players:GetChildren()) do
if plr.Character then
local char = plr.Character
local plr = game.Players:GetPlayerFromCharacter(char)
local playerBoosts = plr:FindFirstChild("PlayerBoosts")
local activeBoosts = playerBoosts:FindFirstChild("ActiveBoosts")
local flagBoost = playerBoosts:FindFirstChild("FlagBoost")
local LRtween = TS:Create(flagMiddle.FlagPart, Info, {Position = lowered.Position})
if (flagMiddle.Base.Position - char.HumanoidRootPart.Position).Magnitude <= 65 then
if not table.find(charsInRange, char) then
table.insert(charsInRange, char)
end
if flagSettings.PlayerID.Value ~= plr.UserId then
if not claiming then
LRtween:Play()
end
if table.find(charsInRange, char) then
claiming = true
end
local userId = plr.UserId
local content, isReady = game.Players:GetUserThumbnailAsync(userId, thumbType, thumbSize)
playerName.Text = "Claiming..."
captureProgress += 1
if captureProgress == 100 then
playerName.Text = plr.Name
playerImg1.Image = content
playerImg2.Image = content
flagSettings.PlayerName.Value = plr.Name
flagSettings.PlayerID.Value = plr.UserId
activeBoosts.Value += flagBoost.Value
claiming = false
end
end
else
claiming = false
captureProgress = 0
LRtween:Cancel()
if table.find(charsInRange, char) then
table.remove(charsInRange, table.find(charsInRange, char))
end
end
end
end
end