Swing System Code

Hello, recently I made a swing system and I would like to have someone to review my code. It has some bugs such as if you spam swing it just breaks. But, ignoring that I would like to see how I can improve my code. Thank you.

Client:

-- Service
local UserInputService = game:GetService("UserInputService")

local SwingEvent = script:WaitForChild("SwingEvent")

-- Variables
local debounce = false
local cooldown = 0.25

-- Parts that are in field of view
local visible_parts = {}

-- Find parts in view
local function getParts()
	for _, v in pairs(workspace.Trees:GetDescendants()) do
		if v.Name == "Climable" then
			
			local _, OnScreen = workspace.CurrentCamera:WorldToScreenPoint(v.Position)

			if OnScreen then
				if #workspace.CurrentCamera:GetPartsObscuringTarget({workspace.CurrentCamera.CFrame.Position, v.Position},{v}) == 0 then
					table.insert(visible_parts, v)
				end
			end
		end
	end
end

local function inputBegan(input, gameProceed)
	if gameProceed then return end
	
	if input.KeyCode == Enum.KeyCode.R and not debounce then
		debounce = true
		getParts()
		SwingEvent:FireServer(true, visible_parts)
		table.clear(visible_parts)
	end
end

local function inputEnded(input, gameProceed)
	if gameProceed then return end

	if input.KeyCode == Enum.KeyCode.R and debounce then
		SwingEvent:FireServer(false)
		task.wait(cooldown)
		debounce = false
	end
end

UserInputService.InputBegan:Connect(inputBegan)
UserInputService.InputEnded:Connect(inputEnded)

Server:

local RunService = game:GetService("RunService")

local SwingEvent = script.Parent:WaitForChild("SwingEvent")

local character = script.Parent.Parent.Parent.Parent
local humanoid = character:WaitForChild("Humanoid")
local rootPart = character:WaitForChild("HumanoidRootPart")
local arm = character:WaitForChild("Right Arm")

local attach0 = Instance.new("Attachment")
attach0.Name = "Attach0"
attach0.Parent = rootPart

-- Variables
local connection
local maxDistance = 50
local distance = maxDistance
local target = nil
local attach1
local force
local fakeAttach

local rope = Instance.new("RopeConstraint")
rope.Visible = false
rope.Attachment0 = attach0
rope.Parent = rootPart

-- Find that parts that you can swing on
local swingable = {}

for _, v in pairs(workspace.Trees:GetDescendants()) do
	if v.Name == "Climable" then
		table.insert(swingable, v)
	end
end

-- Create beam just for visuals
local function createBeam()
	if not fakeAttach then
		fakeAttach = Instance.new("Attachment")
		fakeAttach.Name = "FakeAttach"
		fakeAttach.Position = Vector3.new(0, -1, 0)
		fakeAttach.Parent = arm
	
		local beam = Instance.new("Beam")
		beam.Attachment0 = fakeAttach
		beam.Attachment1 = attach1
		beam.FaceCamera = true
		beam.Width0 = 0.2
		beam.Width1 = 0.2
		beam.Transparency = NumberSequence.new(0)
		beam.Parent = fakeAttach
	end
end

-- Disable Swing Function
local function disableSwing()
	if connection then
		connection:Disconnect()
	end
	local debris = 	game:GetService("Debris")
	debris:AddItem(force, 0.1)
	debris:AddItem(attach1, 0.01)
	debris:AddItem(fakeAttach, 0.01)
	
	target = nil
	force = nil
	attach1 = nil
	fakeAttach = nil
	
	distance = maxDistance
end

local function createVelocity(pos)	
	if not force then
		force = Instance.new("LinearVelocity")
		force.Attachment0 = attach0
		force.MaxForce = 100000
		force.Parent = rootPart
	end
	
	if humanoid.MoveDirection ~= Vector3.new(0, 0, 0) then
		force.VectorVelocity = humanoid.MoveDirection * 50
	else
		force.VectorVelocity = rootPart.Position + rootPart.CFrame.LookVector * 50
	end
end

local function onEvent(player, enabled, parts)
	if enabled and parts then
               -- Find closest tree that you can swing to
		for _, tree in pairs(swingable) do
			local currentDistance = (tree.Position - rootPart.Position).Magnitude
			if currentDistance < distance and table.find(parts, tree) then
				distance = currentDistance
				target = tree
			end
		end
		
		if target then
			local position = target.Position * Vector3.new(1, 0, 1) + Vector3.new(0, target.Size.Y, 0)
			rope.Length = (position - attach0.WorldPosition).Magnitude
			
			attach1 = Instance.new("Attachment")
			attach1.Name = "Attach1"
			attach1.Parent = target
			attach1.WorldPosition = position
			
			createBeam()
			
			connection = RunService.Heartbeat:Connect(function()
				if rope.Length > 3 and rope.Length < maxDistance then
					rope.Length = (position - attach0.WorldPosition).Magnitude
					createVelocity(position)
				else
					disableSwing()
				end
			end)
			
			rope.Attachment1 = attach1
		end
	else
		disableSwing()
	end
end

SwingEvent.OnServerEvent:Connect(onEvent)

Please just handle character movement on the client. It replicates anyways.

1 Like

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