How would I pause/stop a script

Hello DevFourm, I have recently started to help my friend script his fighting game for him. He wanted a platform where when you stand on it, it increases the “Time” IntValue in the leaderboard, and when you get off, it stops increasing the time. However, the time does not stop increasing when I step off the platform.

All I want to know is if there is a way you can stop a script.

Thank you :slight_smile:

1 Like

Break whatever loop the script is running to increase the time, you could show the script part related to the issue

1 Like

Hi Pie_exe, I’m going to give you a solution that probably won’t be the best but will work. I will try to explain how I achieved this. The blue texts will be links to the documentation so that you can read the description and maybe even learn to use them without needing our help!

There are several ways to detect the collision between two parts in Roblox. One of the most well-known, especially among those who are just starting, is the signals Touched and TouchEnded. But this evening I don’t really want to use them because we could make it simpler with something else.

We could use the method GetTouchingParts which, as written in his description, returns a table of all parts that are physically interacting with the desired part. If you would make your own tests, you would have noticed that just doesn’t work.

By reading the description of this method we can see that Roblox gives us alternatives to that like workspace:GetPartsInPart(), once again, in making your own tests, you would noticed that works this time, but not every time. This is due to the fact that as said in the name, this method detects the parts which are in the one we are checking, it does not check if there is a collision just if it overlaps.

Once again, the description of this method gives us alternatives. I was interested to workspace:GetPartBoundsInBox(). This method is similar to the last one but instead of using a part it uses its position and its size, which is interesting to achieve our objective. We could slightly adjust the position and size so that the specified area is above your platform and not within the platform.

Simple calculations can help us achieve this. I will use a variable to store the offset and in the same time using it to the size of the box. In this example the offset and size will be 0.2 stud.

local Offset = 0.2

I will now get the platform and get the size and position of it.

local Offset = 0.2 -- We will slightly raise the position of the part to make sure the player is detected

local Platform = script.Parent

local CurrPartCF = Platform.CFrame
local CurrPartSize = Platform.Size

Now that we have the foundation, we can move on to the calculations. We will create a new CFrame and a new Vector3 to edit the last one and get the good result. To do this, we will take the currPartCF.Y add its value with the half of CurrPartSize.Y and the half of Offset. We keep the same values on the X and Z axes.

local FinalPartCF = CFrame.new(CurrPartCF.X, CurrPartCF.Y + (CurrPartSize.Y / 2) + (Offset / 2), CurrPartCF.Z)

For the size, we keep the same X and Z axes but you will use the Offset for the Y axe like that:

local FinalPartSize = Vector3.new(CurrPartSize.X, Offset, CurrPartSize.Z)

We can create a part to see if we are good with these new values:

Yes we are correct! We can move for the next step.

We will make a loop to continuous cheking if a player touch the platform like that:

while true do
	local parts = workspace:GetPartBoundsInBox(FinalPartCF, FinalPartSize, OverlapParams.new()) -- Gets the table of players who touch the part
	
	task.wait(1) -- Wait 1 second before the next cycle
end

Know that you can adjust OverlapParams, but I’ll let you read the documentation for that.

The method we used returns a table, so we will use a generic loop to loop through it, you can also use a numeric loop if you wish.

for _, hit in pairs(parts) do
	-- We go through the table here element by element
end

We still have a few things to sort out but I’ll let you discover the final code and experiment for yourself. I also put comments to help you understand, but I explained the most complex part to you

-- Services
local PlayerService = game:GetService("Players")

-- Variables
local Offset = 0.2 -- We will slightly raise the position of the part to make sure the player is detected

local Platform = script.Parent

local CurrPartCF = Platform.CFrame
local CurrPartSize = Platform.Size

local FinalPartCF = CFrame.new(CurrPartCF.X, CurrPartCF.Y + (CurrPartSize.Y / 2) + (Offset / 2), CurrPartCF.Z)
local FinalPartSize = Vector3.new(CurrPartSize.X, Offset, CurrPartSize.Z)

-- Functions
local function GetPlayerFromHit(hit)
	local model = hit:FindFirstAncestorWhichIsA("Model") -- Find the first ancestor model of the instance
	local player = PlayerService:GetPlayerFromCharacter(model) -- Try to find if model is a player's character, return nil if model is nil
	return player
end

-- Loop
while true do
	local parts = workspace:GetPartBoundsInBox(FinalPartCF, FinalPartSize, OverlapParams.new()) -- Gets the table of players who touch the part
	
	local AlreadyGotHisTime = {} -- Stores players who have already had their time
	
	for _, hit in pairs(parts) do
		local player = GetPlayerFromHit(hit)
		local block = table.find(AlreadyGotHisTime, player) -- Checks that the player has not already obtained his time in cases where several parts are in the table obtained part GetPartBoundsInBox
		if player and (not block) then
			table.insert(AlreadyGotHisTime, player) -- Add the player to the list of players who have already obtained their times
			workspace.IntValue.Value += 1 -- Add 1 to the value
		end
	end
	
	task.wait(1) -- Wait 1 second before the next cycle
end

You now know how you must proceed to succeed in achieving what you want to do. I hope I helped you and if you have any questions please don’t hesitate to ask me.

1 Like

Hey there. I have tried scripting a system and it should work.

Put this script in the part they are suppose to touch

local TouchingPart = script.Parent
local TimeBetweenGivingScore = 2 -- Set this to the interval before giving another score
local Players = game:GetService("Players")

while true do
	
	wait(TimeBetweenGivingScore)
	
	local PlayersInBox = workspace:GetPartsInPart(TouchingPart)
	for _,Part in pairs(PlayersInBox) do
		

		
		if Part.Parent:FindFirstChild("Humanoid") and Part.Name == "Head" then
			local PlayerModel = Part.Parent
			local Player = Players:FindFirstChild(PlayerModel.Name)
			local PlayerTimeScore = Player:WaitForChild("leaderstats"):WaitForChild("Time")
			
			PlayerTimeScore.Value = PlayerTimeScore.Value + 1
			
		end
	end
end

Make a leaderboard with this script

game.Players.PlayerAdded:Connect(function(Plr) -- Fires when a new Player joins the server
	local Leaderstats = Instance.new("Folder",Plr) -- Adding a folder inside Player
	Leaderstats.Name = "leaderstats" -- Naming the folder to "leaderstats"

	local Kills = Instance.new("IntValue",Leaderstats) -- Adding a Integer Value inside leaderstats
	Kills.Name = "Time"
end)

Basically, How this works is that the part detects the part in it and should there be a part named Head and its parent contains a humanoid, it means it should be a player, and adds a score to that players leaderboard

1 Like