What can I do to make this swimming script better/less laggy?

Please review this code and tell me what I can do to make it more optimized/more lag friendly in any way. Also please keep in mind that this script is being used in 35 different entities.

local Swim = script.Parent.Parent.Animations.Swim
local SwimAnimation = script.Parent.Parent:WaitForChild("Humanoid"):WaitForChild("Animator"):LoadAnimation(Swim)
local AnimationTracks = script.Parent.Parent:WaitForChild("Humanoid"):GetPlayingAnimationTracks()
local PlayerHRP
local PlayerNear = false

while wait() do
	local Swim = script.Parent.Parent.Animations.Swim
	local players = game.Players:GetPlayers()
	
	if PlayerNear == true then
		script.Parent.BodyPosition.D = 100		
		script.Parent.BodyPosition.P = 150
		script.Parent.BodyPosition.Position = PlayerHRP.Position
		script.Parent.Parent.HumanoidRootPart.CFrame = CFrame.new(script.Parent.Parent.HumanoidRootPart.Position, PlayerHRP.Position)
		
		repeat
			if (PlayerHRP.Position - script.Parent.Parent.HumanoidRootPart.Position).Magnitude < 8.5 then
				PlayerHRP.Parent.Humanoid.Health -= 20
				script.Parent.Bite:Play()
				script.Parent.BodyPosition.Position = PlayerHRP.Position
				script.Parent.Parent.HumanoidRootPart.CFrame = CFrame.new(script.Parent.Parent.HumanoidRootPart.Position, PlayerHRP.Position)
				wait(2.5)
			end
			
			for i, v in pairs(players) do
				local Character = game.Workspace:WaitForChild(v.Name)
				local CHRP = Character:WaitForChild("HumanoidRootPart")
				if (Character.HumanoidRootPart.Position - script.Parent.Parent.HumanoidRootPart.Position).Magnitude > 30 then
					PlayerNear = false
				end
			end
			
			local State = PlayerHRP.Parent.Humanoid:GetState()
			if State ~= Enum.HumanoidStateType.Swimming then
				PlayerNear = false
				break
			end
			
			script.Parent.BodyPosition.Position = PlayerHRP.Position
			script.Parent.Parent.HumanoidRootPart.CFrame = CFrame.new(script.Parent.Parent.HumanoidRootPart.Position, PlayerHRP.Position)
			wait()
		until PlayerHRP.Parent.Humanoid.Health == 0 or PlayerNear == false
	else
		script.Parent.BodyPosition.D = 380
		script.Parent.BodyPosition.P = 80
		local Part
		local random = math.random(1, 2)
		if random == 1 then
			Part = game.ReplicatedStorage.Regions.CrenacBorder.WholeArea1Underwater
		else
			Part = game.ReplicatedStorage.Regions.CrenacBorder.WholeArea2Underwater
		end
	
		local Pos = Part.CFrame * CFrame.new(math.random(-Part.Size.X/2, Part.Size.X/2),math.random(-Part.Size.Y/2, Part.Size.Y/2),math.random(-Part.Size.X/2, Part.Size.X/2))
		
		script.Parent.BodyPosition.Position = Pos.Position
		script.Parent.Parent.HumanoidRootPart.CFrame = CFrame.new(script.Parent.Parent.HumanoidRootPart.Position, Pos.Position)
		repeat
			for i, v in pairs(players) do
				local Character = game.Workspace:WaitForChild(v.Name)
				local CHRP = Character:WaitForChild("HumanoidRootPart")
				if (Character.HumanoidRootPart.Position - script.Parent.Parent.HumanoidRootPart.Position).Magnitude < 30 then
					PlayerNear = true
					PlayerHRP = v.Character.HumanoidRootPart
				end
			end
			
			if PlayerNear == true then
				break
			end
			
			wait()
		until (script.Parent.Parent.HumanoidRootPart.Position - script.Parent.BodyPosition.Position).Magnitude < 25
	end
end

that can be shortened into

local random = math.random(1, 2)
Part = game.ReplicatedStorage.Regions.CrenacBorder["WholeArea"..random.."Underwater"]
1 Like

You can also use RunService instead of a while loop.