How can I optimize this melee combat script:
-
What does the code do and what are you not satisfied with?
- It is very laggy and the hitbox debounce (when hit you cannot be hit again until animation is done) is not consistent and sometimes doesn’t do any damage.
- The code isn’t very optimized.
-
What potential improvements have you considered?
- I do not know how to fix my hitbox debounce. Maybe I’m just overcomplicating it. I just need someone coming from another perspective to help.
-
How (specifically) do you want to improve the code?
- I want the hit debounce consistent all the time and the code to run smoothly if possible.
Here is the code (it is a module script in
serverScriptService
):
If there is anything unclear please ask!
local module = {name="MeleeFramework"}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local function len(t)
local n = 0
for _ in pairs(t) do n=n+1 end
return n
end
function module:new(tool, stat)
local hitbox = tool:WaitForChild("HitBox")
local data = {
equipped = false,
canSwing = true,
swinging = false,
animations = {},
attacks = stat.animations.Attacks,
currentAttack = 1,
hitHumans = {},
}
function data:stopAnimations()
for _, v in pairs(self.animations) do
v:Stop()
end
end
function data:touchedHitBox(hit, callback)
if self.equipped and self.swinging then
local humanoid = hit.Parent:FindFirstChild("Humanoid")
if humanoid then
if not table.find(self.hitHumans, humanoid) then
table.insert(self.hitHumans, humanoid)
humanoid:TakeDamage(stat.damage)
hitbox.hit:Play()
if callback then coroutine.wrap(callback)(humanoid) end
end
end
end
end
function data:equip()
local humanoid = tool.Parent:WaitForChild("Humanoid")
self:stopAnimations()
self.animations.Idle = humanoid:LoadAnimation(stat.animations.Idle)
for i, v in pairs(stat.animations.Attacks) do
self.animations[i] = humanoid:LoadAnimation(v[1])
end
self.animations.Idle:Play()
self.equipped = true
end
function data:unequip()
self.equipped = false
self:stopAnimations()
end
function data:playAttackAnimation()
local anim = self.animations["Attack" .. self.currentAttack]
local rootAnim = stat.animations.Attacks[anim.Name]
anim:Play()
if self.currentAttack < len(stat.animations.Attacks) then
self.currentAttack+=1
else
self.currentAttack=1
end
coroutine.wrap(function()
task.wait(rootAnim[3])
self.canSwing = true
end)()
coroutine.wrap(function()
task.wait(rootAnim[2])
for i, v in pairs(self.hitHumans) do table.remove(self.hitHumans, i) end
self.swinging = false
hitbox.Trail.Enabled = false
end)()
if rootAnim[2]>rootAnim[3] then
warn("MeleeFramework_Warning: Never make attackLength longer than cooldown!")
end
end
function data:swing(player, callback)
if self.equipped and self.canSwing then
self.swinging = true
self.canSwing = false
self:playAttackAnimation()
hitbox.swing:Play()
hitbox.Trail.Enabled = true
if player then ReplicatedStorage.Events.EditStamina:FireClient(player, false, 0.05) end
if callback then coroutine.wrap(callback)() end
end
end
return data
end
function module:effect(effect, args)
if effect=="burn" then
local burn = script.burnScript:Clone()
burn.damage.Value = args.Damage
burn.length.Value = args.Length
burn.Parent = args.Character
burn.Disabled = false
end
end
return module