My combat system doesnt work and doesn't show any error

  1. What do you want to achieve? Keep it simple and clear!
    I wanted to make when you hit someone it played the effects he would take damage and get stunned

  2. What is the issue? Include screenshots / videos if possible!

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    Rescripting the entire code
    and using other features

local Remote = game.ReplicatedStorage:WaitForChild("Punch")

local StunHandler = require(game.ServerScriptService.StunHandlerV2)

local Debris = game:GetService("Debris")

IsBeingTouched = false

local Damage = math.random(11,12)

Remote.OnServerEvent:Connect(function(plr)
	local Character = plr.Character or plr.CharacterAdded:Wait()
	local HumanoidRoot = Character:WaitForChild("HumanoidRootPart")
	local Humanoid = Character:WaitForChild("Humanoid")
	
	local Part = game.ReplicatedStorage:WaitForChild("PunchHitBox"):Clone()
	local Effect = game.ReplicatedStorage:WaitForChild("HitEffect"):Clone()
	
	Part.Parent = workspace
	
	Part.CFrame = HumanoidRoot.CFrame * CFrame.new(Vector3.new(0,0,-4))
	

	Part.Touched:Connect(function(hit)
		if hit.Parent == Character then return end 
		
		if hit.Parent:FindFirstChild("Humanoid") and not IsBeingTouched then
			hit.Parent:WaitForChild("Humanoid"):TakeDamage(Damage)
			hit.Parent.Stunned.Value = true
			Effect.Parent = workspace
			Effect.CFrame = hit.Parent:WaitForChild("UpperTorso").CFrame
			StunHandler.Stun(hit.Parent:WaitForChild("Humanoid"),0.4)
			wait(0.4)
			Effect:Destroy()
			hit.Parent.Stunned.Value = false
		end
	end)	
	
	
	
	
wait(0.4)
Part:Destroy()
end)

So what doesn’t work right now? Does Part.Touched fire? Maybe try putting some print statements to see

2 Likes

As @yes35go said, your Part.Touched event isn’t firing. This is because BasePart.Touched events don’t fire if you CFrame a part to overlap with another.

You can learn more about the BasePart events in the documentation here:
https://create.roblox.com/docs/reference/engine/classes/BasePart#Touched

You could instead weld a hitbox to the player, and connect Touched and unTouched events to that hitbox (as it is a part of the Player not anchored). Then anytime a part touches the hitbox as is a Humanoid add it to a table, if it stops touching (unTouch) then remove it. When the player clicks send an event to the server that loops through the table and damages any humanoids within it.

There are many issues in your code. First of which is the fact that HitBox by itself is being created every time you punch, which in some cases may be a good idea but in some cases not. I suggest you creating a separate script in ServerScriptService, that instead welds HitBox to Character and functions whenever needed to.

game.Players.PlayerAdded:Connect(function(Player)
    Player.CharacterAdded:Connect(function(Character)
        local HRPart = Character:WaitForChild("HumanoidRootPart")
    
	    local HitBox= game.ReplicatedStorage:WaitForChild("PunchHitBox"):Clone()
        HitBox.Anchored = false
        HitBox.CanCollide = false
        HitBox.Parent = Character
        HitBox.CFrame = HRpart.CFrame * CFrame.new(0,0,-4)
        
        local WeldC = Instance.new("WeldConstraint")
        WeldC.Part0 = HitBox
        WeldC.Part1 = HRPart
        WeldC.Parent = HitBox
    end)
end)

Now the next issues is that Damage is actually not random with the way you done it. To make it random, you should declare damage variable inside the event script

Remote.OnServerEvent:Connect(function(plr)
    local Damage = math.random(number, number)
end)

Next issue is that you’re creating “Effect” object every time the Event is being fired and not every time the hit is being registered. That way it won’t destroy “Effect” object if the hit isn’t being registered, therefore it’ll just be in-game parented as nil.

As of why your damage is not being registered. It’s simply because humanoid you’re trying to attack doesn’t moves, has it’s collision disabled completely or anchored together with HitBox. You could instead use GetTouchedParts() to register hits.

local IsHitting = false -- this will work ONLY if this script is player specific. Ex. it's inside StarterCharacterScripts and so is the RemoteEvent.
--[[To put simply, if this script is inside ServerScriptService, I recommend
instead creating BoolValue, parenting it inside the Character and checking
whenever IsHitting is false or true through the BoolValue inside the OnServerEvent]]
Remote.OnServerEvent:Connect(function(plr)
    if not IsHitting then
        local Damage = math.random(11, 12)
        local TouchingParts = HitBox:GetTouchingParts()

        for _, part in pairs(TouchingParts) do
            local Humanoid = part.Parent:FindFirstChildWhichIsA("Humanoid")

            if part:IsA("BasePart") and Humanoid then
                IsHitting = true
                hit.Parent.Stunned.Value = true
                local Effect = game.ReplicatedStorage:FindFirstChild("HitEffect"):Clone()
                Effect.Parent = workspace
			    Effect.CFrame = hit.Parent:WaitForChild("UpperTorso").CFrame
                Humanoid:TakeDamage(Damage)
                StunHandler.Stun(hit.Parent:WaitForChild("Humanoid"),0.4)
			    wait(0.4)
			    Effect:Destroy()
                hit.Parent.Stunned.Value = false
                IsHitting = false
                break
            end
        end
    end
end)

This should work now, tho I’m not sure, I haven’t tested it, so I suggest you to read about BasePart:GetTouchingParts() function. If there’s any issue, message me and I’ll see what I can do

1 Like

WorldRoot:GetPartsBoundInBox() seems like a better pick instead of GetTiuchingParts.

1 Like