Why is this script lagging me so much?

I used this script for my game in a sword fighting arena, but whenever there’s someone in the actual arena the game lags BADLY. To where people teleport around and randomly die

script -
local SwordFightArea = workspace:WaitForChild(“SwordFightArea”)
local Area = SwordFightArea:WaitForChild(“Area”)

local Players = game:GetService(“Players”)
local ReplicatedStorage = game:GetService(“ReplicatedStorage”)
local Tools = ReplicatedStorage:WaitForChild(“Tools”)
local Sword = Tools:WaitForChild(“ClassicSword”)

local InArea = {}

– Check For Any Players In The Area
function checkArea()

local Touching = Area:GetTouchingParts()
local TouchingPlayers = {}
for _, v in pairs(Touching) do
	local Parent = v.Parent
	
	if Parent:IsA("Model") then
		local Player = Players:GetPlayerFromCharacter(Parent)
		
		if Player then
			table.insert(TouchingPlayers, Player)
		end
	end
end

return TouchingPlayers

end

function onTouch(Hit)
local Parent = Hit.Parent

if Parent:IsA("Model") then
	local Player = Players:GetPlayerFromCharacter(Parent)
	
	if Player then
		local AreaCheck = checkArea()
		
		for _, p in pairs(AreaCheck) do
			if p == Player then
				table.insert(InArea, Player)
			end
		end
	end
end

end

Area.Touched:Connect(onTouch)

coroutine.resume(coroutine.create(function()
while wait(0.1) do
for index, player in pairs(InArea) do
local Backpack = player:FindFirstChild(“Backpack”)
local Character = player.Character
local CheckArea = checkArea()
local StillInArea = false

		for i,v in pairs(CheckArea) do
			if v == player then
				StillInArea = true
			end
		end
		
		if StillInArea then
			if not Backpack:FindFirstChild(Sword.Name) and not Character:FindFirstChild(Sword.Name) then
				local newSword = Sword:Clone()
				newSword.Parent = Backpack
				
				Character:FindFirstChildWhichIsA("Humanoid"):EquipTool(newSword)
			end
		elseif not StillInArea then
			if Character:FindFirstChild(Sword.Name) then
				Character:FindFirstChildWhichIsA("Humanoid"):UnequipTools()
			end
			
			if Backpack:FindFirstChild(Sword.Name) then
				Backpack:FindFirstChild(Sword.Name):Destroy()
			end
			
			table.remove(InArea, index)
		end
	end
end

end)

1 Like

The checkArea() function seems to be ran an unnecessarily large amount of times, perhaps you should change the code to not use it as much (it seems weird that you use it in the .Touched event)

3 Likes

Im pretty new to scripting tbh, i’ll try to change that

1 Like

yea im pretty garbage at scripting, idk how to do that lol

Can you say what the script is doing?

checking if a player is in a certain zone (A transparent part with can collide off) and when they are, giving them a classic sword, taking it from them when they are not in the zone

1 Like

Just add more task.wait()s within the script so it isn’t looping itself so many times.

2 Likes

Thats what I tried first, it then just gave 1 sword and stopped working

1 Like

Are there any errors in the script when it stops working, after adding task.wait()s?

Make sure you aren’t accidentally adding too many in, like adding 10 task.wait()s with 10 seconds each remaining, because that would make the script significantly slow.

No it might actually work for where i added, ima get my alt to see if it gives a sword

Its kinda working, ima play around with the wait value a little

1 Like

I would suggest using the new spatial query methods instead of get parts in part. If your using a box, specifically the GetPartsInBound method. Spatial queries will allow you to whitelist only the players characters instead of checking every part in the proximity of your area object.

You technically don’t even need to use spatial queries and could simply check the character:GetPivot().Position and make sure the characters position is within the bounds of areaPart.Position.X (±) areaPart.Size.X/2. Same for Y,Z.

In terms of your methodology you could use the touched event on the area object to detect when the player enters the area, then task.spawn off a loop check making sure that specific player is in the area. When they exit the area, the loop stops and you again wait for them to enter with another touched event. This would make sure you’re only polling with constant position checks when you know the player is in the area.

1 Like

I decided instead to use 2 parts, one for enter, and one for exiting. It works, thanks for everyones help anyways though!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.