Adding Knockback to Combat System

Hey everyone,

I need some insight on a feature I’m trying to add to a combat system I’m making. I want to add a “knockback system” and the ways that I’ve tried to do so haven’t worked.

To clarify, I want both the attacker and the victim to be moving. When the player hits the victim, the victim will move back a bit and the player will advance towards the victim to continue the combo.

Things I've Tried So Far

I’ve tried two things so far,

  • Changing Velocity of the HumanoidRootParts
-- Basic Idea, not actual code
local HitHRP = hit.Parent.HumanoidRootPart
local PlrHRP = plr.Character.HumanoidRootPart

HitHRP.Anchored = true

HitHRP.Velocity = PlrHRP.CFrame.lookVector*45
PlrHRP.Velocity = PlrHRP.CFrame.lookVector*45

HitHRP.Anchored = false

This approach kinda worked. The knockback was delayed on the victim, but it still moved the player. On the other hand, the player didn’t move at all. No clue why.

  • Adding BodyVelocity Objects
-- Basic Idea, not actual code
local HitHRP = hit.Parent.HumanoidRootPart
local PlrHRP = plr.Character.HumanoidRootPart

HitHRP.Anchored = true

local HitBV = Instance.new("BodyVelocity")
HitBV .MaxForce = Vector3.new(math.huge, math.huge, math.huge)
HitBV .P = 100
HitBV .Velocity = PlrHRP.CFrame.lookVector*45

local PlrBV = HitBV:Clone()

HitBV.Parent = HitHRP
PlrBV.Parent = PlrHRP

game.Debris:AddItem(HitBV, .5)
game.Debris:AddItem(PlrBV, .5)

HitHRP.Anchored = false

This approach didn’t work at all, neither the player or the victim moved.

I don’t know whether my attempts were implemented wrong or if something else is going on behind the scenes.

Hopefully, someone can give me an idea on how to best add this “knockback system”

Any and all help is appreciated :grin:

Thanks.

25 Likes

Just something quick. You do know that the variable that holds your bodyvelocity is named “HitBV” and when you try to reference it you use “BV” for some reason. Instead of HitBV.Velocity you use BV.Velocity

edit: Don’t know if your real code has that problem. but this code right here has it. Also, I usually set the P value to math.huge

4 Likes

Thanks, for pointing that out.

On topic of the P value, do you think that a P value of 100 would do nothing at all?

1 Like

The code that I tested and worked is this

local target = game.Players.LocalPlayer.Character.HumanoidRootPart

local BV = Instance.new("BodyVelocity")

BV.P = math.huge

BV.MaxForce = Vector3.new(math.huge, math.huge, math.huge)

BV.Velocity = target.CFrame.lookVector * 45

BV.Parent = target

game.Debris:AddItem(BV, 0.5)

I think one of your problems is the anchoring of HitHRP. Anchoring pretty much disables physics of the object. The BodyVelocity won’t move it.

6 Likes

Oh, the anchoring is the problem. Thanks!

I have a quick question though. Do you know how I could keep the players standing while they move?

1 Like
local Speed = 40
local Force = 80000

local TotalForce = Force

local KnockBack = Instance.new("BodyVelocity")
KnockBack.Parent = part.Parent:FindFirstChild("HumanoidRootPart")--part is the target of the knockback/ the opponent

KnockBack.MaxForce = Vector3.new(TotalForce,TotalForce,TotalForce)
KnockBack.Velocity = Character:FindFirstChild("HumanoidRootPart").CFrame.LookVector * Speed -- based on the direction YOUR character is facing.

This is how I made my knockback, hope it helps, even if its crude.

80 Likes

Just want to note that, P on BodyMovers also takes into account the mass of the entire object they are moving. So you’ll either want to make the object Massless or take into account the mass of the object.

4 Likes

this works but laggy with animatino

To be honest you might prefer to use the AssemblyLinearVelocity from the client’s perspective, which is way better than bodyvelocity

Edit:
if you need help regarding it, it’s a value inside every part, I usually add a remote event which triggers a local scripts with a text similar to:

game:GetService("ReplicatedStorage").RemoteEvents.Knockback.OnClientEvent:Connect(function(VECTOR3)
game:GetService("Players").LocalPlayer.Character.HumanoidRootPart.AssemblyLinearVelocity = VECTOR3
end)

(naturally VECTOR3 is a vector3 from the server script which triggers the knockback if you’re trying to add knockback, however you don’t have to use a vector3 from outside the script if you feel like the knockback is always gonna be the same, even if I think it’s really unlikely)

also sorry for the many edits and mistakes, it’s the first time I post something on the forum please be merciful lol

6 Likes

What should I put for the VECTOR3 variable in your code?

2 Likes

math.huge,math.huge,math.huge that what to add

2 Likes

The velocity you want the player to have, for example if I want him to go fly up I’d put:
game:GetService(“Players”).LocalPlayer.Character.HumanoidRootPart.AssemblyLinearVelocity = Vector3.new(0,100,0)
However this is only if you don’t another player to trigger it, in which case you should use a remote event to trigger it and put the variable inside it, so unless you want the player who uses the script to trigger it you should just leave it as it is.
(if you don’t know what a event is I suggest you look it up and watch a tutorial)

3 Likes

ok thanks! (and yes i know what are events lol you can check my profile)

2 Likes

My bad, just wanted to make sure lol. Anyways I’m happy to help

2 Likes

very helpful, thank you. But, I am having a problem with knocking the player actually back.

heres the script (module script) ive made:

local knockback = {}
	local function knockback(force, hitcharacter, caster)
		local hum = hitcharacter:FindFirstChild("Humanoid")
		
		local ws = hum.WalkSpeed
		local jh = hum.JumpHeight
		
		hum.WalkSpeed = 0
		hum.JumpHeight = 0
		
		hitcharacter.HumanoidRootPart.AssemblyLinearVelocity = Vector3.new(0, force * 0.5, caster.HumanoidRootPart.CFrame.LookVector * 50)
		
		task.wait(0.2)
		hum.WalkSpeed = ws
		hum.JumpHeight = jh
	end
return knockback

please help me out

1 Like

Hello! I would personally use BasePart:ApplyImpulse()
Here is the documentation: BasePart | Documentation - Roblox Creator Hub

You can replace that hit character line with this:

local upForce = Vector3.new(0, 250, 0) -- Replace 250 with whatever value works
local knockbackForce = caster.HumanoidRootPart.CFrame.LookVector * 1000 -- Replace 1000 with your value
hitcharacter.HumanoidRootPart:ApplyImpulse(knockbackForce + upForce)

What this code does is first get the vector for the upForce. This is what will knock the enemy character upward. That 250 is the force applied, NOT the velocity. Second, it gets the knockbackForce. This is the direction the caster is facing, multiplied by the force. Change it to your liking. Lastly it combines the knockback and the up force and applies it to the character. This is what will move the character.

I hope this helps!

6 Likes

use CFrame.LookVector of the attacker, for example

the force of your function would look like this:
force = caster.HumanoidRootPart.CFrame.LookVector*Vector3.new(200,0,200)
^ if the Caster is a character object and you want the player to be knockbacked in front of them with a speed of 200 and without moving upwards or downwards.

(Using my method)

Couldn’t exploiters completely negate any knockback by tampering with this?

1 Like

They can change it anyways and bodyvel is kind of outdated

3 Likes