You can write your topic however you want, but you need to answer these questions:
-
What do you want to achieve? Keep it simple and clear!
I’m making a combat system for my indie fighting game. I’m using a localscript for detecting the inputs, and a server script for hitboxes, vfx, and damage. -
What is the issue? Include screenshots / videos if possible!
When I punch someone, for some reason they die after a few seconds, even if they’ve only been punched once. -
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
- I have read through the documentation for the
TakeDamage()
event. - I have asked ChatGPT (who, as always, is terrible at luau)
- I have looked for people with the same issue as me on the dev forum.
- I have tried different methods of taking away health.
Even after all of that, I’m getting the same result.
After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!
CombatHandler (server)
local CollectionService = game:GetService("CollectionService")
local TweenService = game:GetService("TweenService")
local CombatRemote = game.ReplicatedStorage.Remotes.Combat
local Debris = game:GetService("Debris")
local combatTimers = {}
-- Handle InCombat tagging and timeout
local function addInCombatTag(character)
if not CollectionService:HasTag(character, "InCombat") then
CollectionService:AddTag(character, "InCombat")
end
if combatTimers[character] then
task.cancel(combatTimers[character])
end
combatTimers[character] = task.delay(10, function()
if character and character:IsDescendantOf(workspace) and CollectionService:HasTag(character, "InCombat") then
CollectionService:RemoveTag(character, "InCombat")
end
combatTimers[character] = nil
end)
end
-- Make DamageMarker float up and fade out
local function createFloatingDamage(damageMarker)
if not damageMarker or not damageMarker:IsA("BillboardGui") then return end
local tweenInfo = TweenInfo.new(0.8, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
-- Move up
local startPosition = damageMarker.StudsOffset
local goalPosition = startPosition + Vector3.new(0, 2, 0)
local moveTween = TweenService:Create(damageMarker, tweenInfo, {StudsOffset = goalPosition})
-- Fade out text and UIStroke
local damageLabel = damageMarker:FindFirstChild("Damage")
if damageLabel and damageLabel:IsA("TextLabel") then
local fadeTextTween = TweenService:Create(damageLabel, tweenInfo, {TextTransparency = 1})
local stroke = damageLabel:FindFirstChildOfClass("UIStroke")
if stroke then
local fadeStrokeTween = TweenService:Create(stroke, tweenInfo, {Transparency = 1})
moveTween:Play()
fadeTextTween:Play()
fadeStrokeTween:Play()
else
moveTween:Play()
fadeTextTween:Play()
end
-- Clean up after
Debris:AddItem(damageMarker, 1.5)
end
end
-- Main Combat Remote Event
CombatRemote.OnServerEvent:Connect(function(plr, arg)
local character = plr.Character
if not character or not character:FindFirstChild("HumanoidRootPart") then return end
if arg == "M1" then
local hitRange = 5
local damage = 5
for _, target in ipairs(workspace:GetChildren()) do
if target:IsA("Model") and target:FindFirstChild("Humanoid") and target ~= character then
local targetHRP = target:FindFirstChild("HumanoidRootPart")
if targetHRP then
local distance = (character.HumanoidRootPart.Position - targetHRP.Position).Magnitude
if distance <= hitRange then
-- Always damage if in range
addInCombatTag(character)
addInCombatTag(target)
if CollectionService:HasTag(target, "Block") then
-- Blocked hit
local blockEffectTemplate = game.ReplicatedStorage.Effects.Block:FindFirstChild("Attachment")
if blockEffectTemplate then
local blockEffect = blockEffectTemplate:Clone()
blockEffect.Parent = targetHRP
-- DamageMarker Text
local damageMarker = blockEffect:FindFirstChild("DamageMarker")
if damageMarker and damageMarker:FindFirstChild("Damage") then
damageMarker.Damage.Text = "-Blocked-"
createFloatingDamage(damageMarker)
end
-- Block sound
local blockSoundTemplate = game.ReplicatedStorage.Effects.Block:FindFirstChild("Block")
if blockSoundTemplate then
local blockSound = blockSoundTemplate:Clone()
blockSound.Parent = targetHRP
blockSound:Play()
Debris:AddItem(blockSound, 3)
end
Debris:AddItem(blockEffect, 3)
task.spawn(function()
for _, emitter in ipairs(blockEffect:GetChildren()) do
if emitter:IsA("ParticleEmitter") then
emitter:Emit(emitter:GetAttribute("EmitCount") or 5)
end
end
end)
end
else
-- Normal hit
target.Humanoid:TakeDamage(damage)
local hitEffectTemplate = game.ReplicatedStorage.Effects.Hit:FindFirstChild("Attachment")
if hitEffectTemplate then
local hitEffect = hitEffectTemplate:Clone()
hitEffect.Parent = targetHRP
-- DamageMarker Text
local damageMarker = hitEffect:FindFirstChild("DamageMarker")
if damageMarker and damageMarker:FindFirstChild("Damage") then
damageMarker.Damage.Text = "-" .. tostring(damage)
createFloatingDamage(damageMarker)
end
-- Hit sound
local hitSoundTemplate = game.ReplicatedStorage.Effects.Hit:FindFirstChild("Hit")
if hitSoundTemplate then
local hitSound = hitSoundTemplate:Clone()
hitSound.Parent = targetHRP
hitSound:Play()
Debris:AddItem(hitSound, 3)
end
Debris:AddItem(hitEffect, 3)
task.spawn(function()
for _, emitter in ipairs(hitEffect:GetChildren()) do
if emitter:IsA("ParticleEmitter") then
emitter:Emit(emitter:GetAttribute("EmitCount") or 5)
end
end
end)
end
end
end
end
end
end
elseif arg == "BlockOn" then
if not CollectionService:HasTag(character, "Block") then
CollectionService:AddTag(character, "Block")
end
elseif arg == "BlockOff" then
if CollectionService:HasTag(character, "Block") then
CollectionService:RemoveTag(character, "Block")
end
end
end)
CombatClient (LocalScript)
local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local uis = game:GetService("UserInputService")
local m1debounce = false
local blockdebounce = false
local m1Left = char:WaitForChild("Humanoid"):LoadAnimation(game.ReplicatedStorage.Animations.M1Left)
local m1Right = char:WaitForChild("Humanoid"):LoadAnimation(game.ReplicatedStorage.Animations.M1Right)
local Block = char:WaitForChild("Humanoid"):LoadAnimation(game.ReplicatedStorage.Animations.Block)
local currentPunch = 1
local currentAnim
uis.InputBegan:Connect(function(i, e)
if e then return end
if i.UserInputType == Enum.UserInputType.MouseButton1 and m1debounce == false then
m1debounce = true
print("m1")
if currentPunch == 1 then
m1Left:Play()
currentAnim = m1Left
currentPunch = 2
elseif currentPunch == 2 then
m1Right:Play()
currentAnim = m1Right
currentPunch = 1
end
currentAnim:GetMarkerReachedSignal("Hit"):Connect(function()
game.ReplicatedStorage.Remotes.Combat:FireServer("M1")
end)
task.delay(0.7, function()
m1debounce = false
end)
end
if i.KeyCode == Enum.KeyCode.F and blockdebounce == false then
game.ReplicatedStorage.Remotes.Combat:FireServer("BlockOn")
char:WaitForChild("Humanoid").WalkSpeed = 6
Block:Play()
end
end)
uis.InputEnded:Connect(function(i, e)
if e then return end
if i.KeyCode == Enum.KeyCode.F and blockdebounce == false then
game.ReplicatedStorage.Remotes.Combat:FireServer("BlockOff")
blockdebounce = true
char:WaitForChild("Humanoid").WalkSpeed = 32
Block:Stop()
task.delay(1, function()
blockdebounce = false
end)
end
end)
I will be thankful for any help, as this is a very bad bug to have in a fighting game.