How do I make an NPC/Player move in the direction they were hit in with a BodyVelocity?

Hello there! This is my first time really posting on the devforum so sorry if I’m doing anything wrong.

1.What do you want to achieve?

I am making a combat type system and I’m trying to figure out a way how when a hitbox (Part) touches a player, it moves the npc/player using a bodyvelocity

  1. What is the issue?

I want the npc/player to move in the direction they were hit in
here’s a video to show the issue https://gyazo.com/63a88831648637f7e2ba01cb9e1b7168
I had another issue but I fixed it by adding a wait()

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I’ve tried googling it up but couldn’t find anything :skull:, and I’ve tried putting a variable to detect what the hitbox’s CFrame was but it was pretty delayed compared to when I remove the part that uses the hitbox CFrame

Heres the full script (Server Script) :

game.ReplicatedStorage.Attack.OnServerEvent:Connect(function(Player)
	
	-- Variables
	
	local PlayerWhoPressed = Player.Character.Name
	local Character = Player.Character
	local HRP = Character.HumanoidRootPart
	local Part = Instance.new("Part")
	
	-- Spawn Hitbox
	
	wait(0.2)
	Part.Parent = game.Workspace
	Part.CFrame = HRP.CFrame + HRP.CFrame.LookVector * 2.35
	Part.Anchored = true
	Part.BrickColor = BrickColor.new("Really red")
	Part.Transparency = 0.75
	Part.CanCollide = false
	Part.Size = Vector3.new(5, 5, 4.5)
	
	Part.Touched:Connect(function(Hit)
		
		-- Variables
		
		local Sound = math.random(1,2)
		local PartCFrame = Part.CFrame
		local Humanoid = Hit.Parent:FindFirstChild("Humanoid")
		
		if Humanoid and Humanoid.Parent.Name ~= PlayerWhoPressed then
			local HitHRP = Humanoid.Parent.HumanoidRootPart
			local BodyVelocity = Instance.new("BodyVelocity")
			
			BodyVelocity.MaxForce = Vector3.new(1,0,1) * 30000
			BodyVelocity.Velocity = HitHRP.CFrame.LookVector * -100
			BodyVelocity.Parent = HitHRP
			Humanoid.WalkSpeed = 0
			
			for i= 1,8 do
				wait(0.1)
				Humanoid.Health -= 0.3
				BodyVelocity.Velocity *= 0.7
				wait()
			end
			
			wait(1.5)
			Humanoid.WalkSpeed = 16
			BodyVelocity:Destroy()
			Part:Destroy()
			
		else
			wait()
			Part:Destroy()
		end
	end)
	wait(0.1)
	Part:Destroy()
end)
end)

This is relatively simple to achieve,
the line that is causing this issue in the code is this one:


The line works fine, but you need to use a different equation to calculate velocity from the Player (hitting the other person) to the person they hit.
I’ve simplified your code a little bit and changed the equation so as to resolve your issue.

Essentally, it takes the Player’s HumanoidRootPart position and subtracts the position of the person who got hit. It then gets the Unit of the negative Vector3 value to calculate the direction.
Here is the full code:

game.ReplicatedStorage.Attack.OnServerEvent:Connect(function(Player)
	local PlayerWhoPressed = Player.Name
	local Char = Player.Character
	local Root = Char:WaitForChild("HumanoidRootPart", 1)
	if Root == nil then return end
	local Part = Instance.new("Part")
	wait(0.2)
	Part.Parent = game.Workspace
	Part.CFrame += Root.CFrame.LookVector * 3
	Part.Anchored = true
	Part.BrickColor = BrickColor.new("Really red")
	Part.Transparency = 0.75
	Part.CanCollide = false
	Part.Size = Vector3.new(5, 5, 3.5)
	Part.Touched:Connect(function(Hit)
		local Humanoid = Hit.Parent:FindFirstChild("Humanoid")
		if Humanoid ~= nil and Humanoid.Parent.Name ~= PlayerWhoPressed then
			local BodyVelocity = Instance.new("BodyVelocity")
			BodyVelocity.MaxForce = Vector3.new(1,0,1) * 30000
			BodyVelocity.Velocity = (-(Root.Position - Humanoid.Parent.HumanoidRootPart.Position).Unit * 2.5)
			BodyVelocity.Parent = Humanoid.Parent.HumanoidRootPart
			Humanoid.WalkSpeed = 0
			for i= 1,10 do
				Humanoid.Health -= 0.5
				BodyVelocity.Velocity *= 0.7
				wait()
			end
			wait(1.5)
			Humanoid.WalkSpeed = 16
			BodyVelocity:Destroy()
			Part:Destroy()
		else
			wait()
			Part:Destroy()
		end
	end)
	wait(0.1)
	Part:Destroy()
end)

Another Alternative way is to get the direction the player hitting is facing.
This is a lot simpler, and you can use this method instead of my other one if you decide to.
image
(Root is the PlayerWhoPressed’s HumanoidRootPart)
FULL CODE:

game.ReplicatedStorage.Attack.OnServerEvent:Connect(function(Player)
	local PlayerWhoPressed = Player.Name
	local Char = Player.Character
	local Root = Char:WaitForChild("HumanoidRootPart", 1)
	if Root == nil then return end
	local Part = Instance.new("Part")
	wait(0.2)
	Part.Parent = game.Workspace
	Part.CFrame += Root.CFrame.LookVector * 3
	Part.Anchored = true
	Part.BrickColor = BrickColor.new("Really red")
	Part.Transparency = 0.75
	Part.CanCollide = false
	Part.Size = Vector3.new(5, 5, 3.5)
	Part.Touched:Connect(function(Hit)
		local Humanoid = Hit.Parent:FindFirstChild("Humanoid")
		if Humanoid ~= nil and Humanoid.Parent.Name ~= PlayerWhoPressed then
			local BodyVelocity = Instance.new("BodyVelocity")
			BodyVelocity.MaxForce = Vector3.new(1,0,1) * 30000
			BodyVelocity.Velocity = Root.CFrame.LookVector * 100
			BodyVelocity.Parent = Humanoid.Parent.HumanoidRootPart
			Humanoid.WalkSpeed = 0
			for i= 1,10 do
				Humanoid.Health -= 0.5
				BodyVelocity.Velocity *= 0.7
				wait()
			end
			wait(1.5)
			Humanoid.WalkSpeed = 16
			BodyVelocity:Destroy()
			Part:Destroy()
		else
			wait()
			Part:Destroy()
		end
	end)
	wait(0.1)
	Part:Destroy()
end)

Hi there, I’ve tried both of your solutions, however, when I run it in game, it doesn’t seem to be working? also PlayerWhoPressed is supposed to be the player character because if the player somehow is inside the hitbox which happens a lot, they won’t take damage from their own attack, it’s not supposed to be the Player.

Edit: I’ve also updated my script so it’s more organized/redable

1 Like

Ah, I managed to make it work by using this line of code,
image
I’ll make sure to mark that as the solution!

Instead of making a Body Velocity since its deprecated, you could use linear velocity and use the line modifier

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.