Intense CPU spikes and lag when entering scripted water

I have a script that turns all parts named “Water” into swimmable areas like terrain water, but my main issue is that my CPU spikes and my frames drop when I enter/exit the water. I’m not entirely sure what is causing this, so help would be appreciated. Thanks

I tried having the code be triggered by the player instead the water, but I couldn’t find a way to have it detect each limb of the player without using up several for loops

(script is located in StarterCharacterScripts)

local Workspace = game:GetService("Workspace")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local char = script.Parent
local hum = char:WaitForChild("Humanoid")
local hrp = char:WaitForChild("HumanoidRootPart")
local swim

local waterPart = {}

ReplicatedStorage.RunCharacterCreator.OnClientEvent:Connect(function()
	for i, part in pairs(Workspace:GetDescendants()) do
		if part.Name == "Water" and part:IsA("BasePart") then
			table.insert(waterPart, part)
		end
	end
end)


RunService.Heartbeat:Connect(function()
	for i=1, #waterPart do
		local isSwimming = false
		local isFloating = false
		waterPart[i].Touched:Connect(function() end)
		
		local touching = waterPart[i]:GetTouchingParts()
		for i=1, #touching do
			for _, part in pairs(char:GetDescendants()) do
				if part:IsA("BasePart") and touching[i] == part then
					isFloating = true
				end
			end
			if touching[i] == hrp then
				isSwimming = true
				break
			end
		end
		
		if isSwimming == true then
			if not swim then
				swim = Instance.new("BodyVelocity")
				swim.Parent = hrp
			end
			swim.Velocity = hum.MoveDirection * hum.WalkSpeed + Vector3.new(0,4,0)
			if hum:GetState() ~= Enum.HumanoidStateType.Swimming then
				hum:SetStateEnabled(Enum.HumanoidStateType.GettingUp, false)
				hum:ChangeState(Enum.HumanoidStateType.Swimming)
			end
		elseif swim and isSwimming == false and isFloating == true then
			swim.Velocity = hum.MoveDirection * hum.WalkSpeed * Vector3.new(1,0,1)
		elseif swim and isSwimming == true then
			swim.Velocity = hum.MoveDirection * hum.WalkSpeed
		elseif swim and isFloating == false then
			swim:Destroy()
			swim = nil
			hum:SetStateEnabled(Enum.HumanoidStateType.GettingUp, true)
		end
	end
end)
1 Like

it’s likely because you’re making a .Touched connection every frame which is unnecessary
it only needs to be done once in order for GetTouchingParts() to work on non-cancollide parts

1 Like

I agree. They could put that where they put the parts in the waterPart table in the first place.

ReplicatedStorage.RunCharacterCreator.OnClientEvent:Connect(function()
	for _, part in pairs(Workspace:GetDescendants()) do
		if part.Name == "Water" and part:IsA("BasePart") then
			table.insert(waterPart, part)
			part.Touched:Connect(function() end)
		end
	end
end)
1 Like

Does that actually create a new TouchInterest every frame? Crazy

Thanks :slight_smile:

(Also, I just realized that the RemoteEvent I was using didn’t trigger every time the player joined, so thanks for reminding me of that)

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