Help to improve this knockback punching system?

Hi, so I have this functioning piece of code that provides knockback to another player every time they get punched by someone. It’s nice but if you’re chasing someone around and they keep jumping, you can barely knock them back. I thought of increasing the magnitude but if you stand still, it will just reach them from so far away making it look wonky.

How could I improve this to make it a better more effective and cleaner knockback system? (Maybe even if it’s possible, make it so that you can only knockback players from the front instead of all around, but that’s out of my skill level)

Any help is appreciated, thanks!


game.ReplicatedStorage.knockback.knockback.OnServerEvent:Connect(function(player)
	for _, target in pairs(game.Workspace:GetDescendants()) do
		if target:IsA("Humanoid") and target.Parent.Name ~= player.Name then
			if (target.Parent.HumanoidRootPart.Position - player.Character.HumanoidRootPart.Position).magnitude < 6 then
				
				--print(target.Parent.Name, "was touched")
			
				local targetRootPart = target.Parent.PrimaryPart
				local playerRootPart = player.Character.PrimaryPart

				local velocity = Instance.new("BodyVelocity")
				velocity.MaxForce = Vector3.new(100000,100000,100000)

				local angle = ((targetRootPart.Position - playerRootPart.Position) * Vector3.new(10,0,10)).Unit * 50 + Vector3.new(0,25,0)	
				velocity.Velocity = angle
				velocity.Parent = targetRootPart

				game.Debris:AddItem(velocity, 0.1)
			
			end
		end
	end
end)


why not loop through all the players, so you don’t need to loop through every single thing in workspace

this would help a lot when it comes to lag

1 Like

Yeah I could do that, although, how would I find the humanoid from players?
Could something like this work?

for _, target in pairs(game.Players:GetChildren()) do
      if target.Character:FindFirstChild("Humanoid") and target.Parent.Name ~= player.Name then
for _, target in ipairs(game.Players:GetPlayers()) do
    if target:FindFirstChild("Character") then
        if target.Character:FindFirstChild("Humanoid") and target.Name ~= player.Name then
1 Like

If you want to check whether or not the player is Infront of your character you can do some easy trig for this.

We will use Dot Product.

local Angle = 90 --Players vision will be 90 in this case


-- Now check

local EnemyDirection = (EnemyPosition - PlayerPosition).Unit
local ForwardDirection = PlayerCframe.LookVector
local CosTheta = ForwardDirection:Dot(EnemyDirection)

if CosTheta > math.cos(Angle/2) then
    --Player is in FOV of 90 for the enemy
end
1 Like

you never defined Theta, did you mean CosTheta?

1 Like

Yes sorry. I changed the code after I looked at it. Forgot to remove it

1 Like

velocity.Velocity = HumanoidRootPart.CFrame.LookVector * 50

1 Like

You could possibly set the velocity to wherever the player is facing (not the target).

local angle = (targetRootPart.Position - playerRootPart.Position).Unit * 100 -- 100 means how far the velocity will be, in this case 100 studs.
1 Like

might I ask, what is PlayerCFrame defined as?

Player.Character.HumanoidRootPart.CFrame
pretty much that

like it says, it is the player’s cframe

1 Like

ah okay, I was a bit uncertain about the format, so thank you!

1 Like

why did u use remoteevent only for knockback you combine in1 script with ur punch script make new variable for combo value like local combo = 0

if combo == 1 then – your code end

you can use Magnitude <= 5 – for the punch script the 5 is max distance to hit <= mean if it below 5 or 5 it can take damage and play animation else it will not bc to far

1 Like

I would do that but I have an animation being played in the local punch script, as well as other remote events hooked up to it that needs the punch being detected. I didn’t want to do that since it would become messy in that one script so I kept everything separate.

you can move ur script code punch into serverscriptservice and use remoteevent if click firethe server and then in the serverscriptservice onServerEvent will run the code

1 Like

there problems if you keep separate script for the game make lag and confusing devs to know where the code

1 Like

Yeah I did that, it’s just part of the code you’re seeing, but you’re correct it does make it better to know where the code is.

i improved my new game in the serverscript service has less 4 script i make 1 main script and other is for cant be combine like for looping things and my remoteevent just 1 and 1 remotefunction

Hey, I tried this one but what exactly are you specifying with HumanoidRootPart, since my velocity = angle, the angle has the position of the target and character’s primary part position.

Well you can use Either The Torso, Head or HumanoidRootPart.

If you use the head or torso the way it lines up will be more accurate. If you use Hrp it will be a little easier for the player to control because then animations will not effect the Direction.

One small note. I see you are using BodyVelocity to push the player back. If you want it to feel more “real” or faster, then I highly recommend you use ApplyImpulse method instead.

ApplyImpulse is an force that is added instantly. If you want to get to a specific velocity you want you will have to do a little calculation.

image

or
J = Force * (T2 - T1)
I don’t think you need it in your case but you still might want to remember it for future reference. Impulse (physics) - Wikipedia

Something like this maybe?

PlayerToEnemy = (EnemyPosition - PlayerPosition) * Vector3.new(1,0,1)
EnemyCharacter.PrimaryPart:ApplyImpulse(PlayerToEnemy.Unit * EnemyMass * 10 + Vector3.new(0,EnemyMass * 20,0))
1 Like