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)