Need help with KnockBack system

I need help with a knockback system where if you hit someone, they go in the direction you are facing. But this script makes them go in the direction they are facing, which makes it very awkward to use.
this is the localscript

local replicatedStorage = game:GetService("ReplicatedStorage")


local punchEvent = replicatedStorage:WaitForChild("PunchEvent")

local player = game.Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local humrootpart = character:WaitForChild("HumanoidRootPart")

local rightArm = character:WaitForChild("Right Arm")

local anim = script:WaitForChild("PunchAnim")
local punchAnim = humanoid:LoadAnimation(anim)

local damage = 100 
local canDamage = false
local debounce = false



script.Parent.Activated:Connect(function()
		if debounce == false then
			debounce = true
			punchAnim:Play()
			wait(0.25)
			canDamage = true
			punchAnim.Stopped:Wait()
			canDamage = false
			 rightArm.Touched:Connect(function(hit)
				local humanoid = hit.Parent:FindFirstChild("Humanoid")
				if humanoid and humanoid.Parent.Name ~= player.Name then
					if canDamage then
						punchEvent:FireServer(humanoid, damage, humrootpart)
						canDamage = false
					end
				end
			end)
			wait(1)
			debounce = false
		end  
end)

this is the serverscript

local RS = game:GetService("ReplicatedStorage")
local punchEvent = RS:WaitForChild("PunchEvent")
punchEvent.OnServerEvent:Connect(function(player,humanoid, damage, humrootpart)
	humanoid:TakeDamage(damage)
	local char = humanoid.Parent
	local hrp = char:WaitForChild("HumanoidRootPart")
	local Speed = 100
	local Force = math.huge

	local TotalForce = Force

	local KnockBack = Instance.new("BodyVelocity", humrootpart)
	KnockBack.MaxForce = Vector3.new(TotalForce,TotalForce,TotalForce)
	KnockBack.Velocity = humrootpart.CFrame.LookVector * Speed
	wait(0.1)
	KnockBack:Destroy()
end)

how do I fix this?

1 Like

Change the server script to this

local RS = game:GetService("ReplicatedStorage")
local punchEvent = RS:WaitForChild("PunchEvent")
punchEvent.OnServerEvent:Connect(function(player,humanoid, damage, humrootpart)
	-- End the function if the attacker doesn't have a character or a humanoid root part (Exploiters)
	if (not player.Character) or (player.Character:FindFirstChild("HumanoidRootPart") == nil) then
		print("Player Not Found")
		return
	end
	
	humanoid:TakeDamage(damage)
	local char = humanoid.Parent
	local hrp = char:WaitForChild("HumanoidRootPart")
	local Speed = 100
	local Force = math.huge

	local TotalForce = Force

	local KnockBack = Instance.new("BodyVelocity", humrootpart)
	KnockBack.MaxForce = Vector3.new(TotalForce,TotalForce,TotalForce)
	KnockBack.Velocity = (humrootpart.Position - player.Character.HumanoidRootPart.Position).Unit * Speed -- The first part of this line gets the direction from the attacker's HumanoidRootPart to the victim's HumanoidRootPart
	wait(0.1)
	KnockBack:Destroy()
end)
1 Like

It didnt work, the bodyvelocity is ot added

1 Like

Do you get any errors in output?

1 Like

I had same problem. Try:

  1. Make BodyVelocity’s parent a torso

  2. Turn torso’s (or all possible parts) CanCollide parameter false.

As an example, in toolbox I’ve found interactive blackhole asset. Script in it puts a BodyVelocity in character’s torso and turns CanCollide of all parts to false.

1 Like

There are no errors in the output.

1 Like

I think it wasn’t detecting the attacker’s player, try it now.

1 Like

First of all, you made this:

-- End the function if the attacker doesn't have a character or a humanoid root part (Exploiters)
if not player.Character or not player.Character:FindFirstChild("HumanoidRootPart") then return end

Which, yes, doesn’t allow exploiters to do a really basic thing, but you’re sending all the informations from the client. An exploiter could just send the punchEvent with parameters of a player of their choice, same thing with the damage. But besides that…
Is the humanoid even taking damage? I would check on the server for the enemy HRP with:
local humrootpart = humanoid.Parent.HumanoidRootPart;
There is nothing wrong in the script of the knockback that @rokoblox5 gave you, so I don’t see why it shouldn’t be working. Make also sure that the HRP of the enemy isn’t anchored. One last tip, instead of doing wait(0.1); use game.Debris:AddItem(KnockBack,0.1); for a more precise result.

1 Like

The client cannot specify the first argument player, it’s automatically assigned by the server to whoever fired the event.

For example, if the client fires a remote event giving 3 parameters, a, b, and c
The server will receive 4 parameters, player, a, b, and c, that’s why if you try doing OnServerEvent:Connect(function(a,b,c), you will keep getting erros, since you are receiving the player as a
Player → a
a → b
b → c
c → Not received

1 Like

I’m sort of new to scripting so I don’t know how to secure everything properly and yes the humanoid is taking damage

1 Like

I’m not talking about the player argument. It can’t be exploited. I’m talking about all the other parameters. An exploiter can send a “humanoid”, “damage”, and “humrootpart” of their choice if they wanted to as there’s no protection, on both client and server.

1 Like

I know, I was talking about errors, if an exploiter fires the remote event without a character the server will be flooded with errors, I know this can be caused from other lines in that script too, but I was trying to keep my part error-free.

1 Like

Yes I know that. I’m talking about the RemoteEvent parameters, what you’ve done there for the character check is fine. I think we were misunderstanding each others lol.

2 Likes

@offizen Could you try changing the script to this again, I think I might’ve fixed it, also tell me what does it print in output.

1 Like

Try doing:

local KnockBack = Instance.new("BodyVelocity");
KnockBack.MaxForce = Vector3.new(300000,300000,300000); -- (I'd keep this low, there's no need to use math.huge. It would just make the knockback jittery)
KnockBack.Velocity = (humrootpart.Position - player.Character.HumanoidRootPart.Position).Unit * Speed;
KnockBack.Parent = humrootpart;
1 Like

Sorry, I had a class so I couldn’t respond but it still just launches them in the direction the other player is facing

1 Like

Nothing is printing in the output

2 Likes

Could you try using this for debugging?

local KnockBack = Instance.new("BodyVelocity", humrootpart)
KnockBack.MaxForce = Vector3.new(TotalForce,TotalForce,TotalForce)
local Direction = (humrootpart.Position - player.Character.HumanoidRootPart.Position).Unit
KnockBack.Velocity = Direction * Speed
print("Knockback direction ", Direction)

It should print something in the output

1 Like

Oh yeah true, I know why. Do this:

KnockBack.Velocity = (humrootpart.Position - player.Character.HumanoidRootPart.Position).Unit * -Speed

(Speed is negative now, this should fix it)

1 Like

Did you try turning off colliding of all player parts?

1 Like