Velocity script sends then above, or behind me sometimes

	Remote.OnServerEvent:Connect(function(Player,Character,NextAnim)
		if NextAnim == 1 then
		 local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
			 local BodyVelocity = Instance.new("BodyVelocity", HumanoidRootPart)
            BodyVelocity.Velocity = Vector3.new(0,10,0) + HumanoidRootPart.CFrame.LookVector *  105
	
            wait(0.5)

            BodyVelocity:Destroy()

Sometimes not all the times it’ll send them above me, or behind me not sure why. this happens when the third hit in a combo I have, a kick hits the opponent.

What should happen normally? Knock back?

1 Like

Yup Tryna have the enemy that gets hit just get launched back. Sometimes they get launched above us, or behind for some reason

Can you show a video of the bug happening? I am suspecting that due to the animation playing, the HumanoidRootPart is rotated at that moment. If that is the case make sure to stop the animation, do a wait() (yes without arguments) and then calculate the BodyVelocity. This might work.

1 Like

Sorry for taking so long.

https://i.gyazo.com/b911e822c3e560c62dfab6b221a2d7fe.mp4 This happens

It does this sometimes which is what I want it to do
https://i.gyazo.com/03a8a7f1212156b17e5bb22be5ca9184.mp4

Are you using the player doing the launching or the player being launched as the reference for the lookVector? If you’re using the player being launched, they can just turn and be launched in a different direction, and it’s not consistent launching. I would recommend using the player doing the launching as the reference if you’re not already. If you are, are you able to take a video with the Torsos transparent and the HumanoidRootParts visible so we can see if there’s a difference?

1 Like

Here
https://i.gyazo.com/c5cedfddec0e7e1c9dbba531a9e46b64.mp4 Watch this slowly, I feel like for some strange reason its applying the knockback on hit two dont you think? sometimes. watch it slowly it looks to me like they get launched back on the second hit before the foot even comes out idkkkk.

When it applies normally to hit 3 they get launched forward but for some reason sometimes the yget launched on hit two. If u want the rest of the script let me know

Yeah, I would say post the rest of the script. That one they were definitely launched on hit two like you said.

local Remote = game.ReplicatedStorage.AttackEvent


Remote.OnServerEvent:Connect(function(Player, Character)
	if Character:FindFirstChild("Humanoid") then
		Character.Humanoid:TakeDamage(10)
		
		Remote.OnServerEvent:Connect(function(Player,Character,NextAnim)
		if NextAnim == 1 then
		 local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
			 local BodyVelocity = Instance.new("BodyVelocity", HumanoidRootPart)
            BodyVelocity.Velocity = Vector3.new(0,10,0) + HumanoidRootPart.CFrame.LookVector *  200
				
					            wait(1)

				
			 BodyVelocity:Destroy()
				
				
	end
		end)
		end
end)```
heres the one in the server script.

and this is the one in our local
```lua
local Player = game.Players.LocalPlayer
local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
local Mouse = Player:GetMouse()
local PunchAnim = Humanoid:LoadAnimation(script:WaitForChild("Punch1Anim"))
local PunchAnim2 = Humanoid:LoadAnimation(script:WaitForChild("Punch2Anim"))
local KickAnim = Humanoid:LoadAnimation(script:WaitForChild("Kick1Anim"))
local RightArm = game.Players.LocalPlayer.Character["Right Arm"]
local LeftArm = game.Players.LocalPlayer.Character["Left Arm"]
local LeftLeg = game.Players.LocalPlayer.Character["Left Leg"]



 

local CanDamage = false
local Table = {RightArm, LeftArm, LeftLeg}
local NextAnim = 1 
local Cooldown = false

Mouse.Button1Down:Connect(function()
	if not Cooldown then
		Cooldown = true
		CanDamage = true

		if NextAnim == 1 then
			NextAnim = 2
			PunchAnim:Play()
					wait(0.5)	
				
	
		elseif NextAnim == 2 then
			NextAnim = 3
			PunchAnim2:Play()
					wait(0.5)	
				
			
		elseif NextAnim == 3 then
			NextAnim = 1
		  KickAnim:Play()
			wait(1)
   
		end
		
		
		local CurrentNextAnim = NextAnim
		
		Cooldown = false
		CanDamage = false
		wait(0.5)
		if CurrentNextAnim == NextAnim then 
			NextAnim = 1
		end
	end
end)

for i,v in pairs(Table) do
	v.Touched:Connect(function(h)
		if h.Parent:FindFirstChild("Humanoid") and CanDamage then
			CanDamage = false
			game.ReplicatedStorage.AttackEvent:FireServer(h.Parent, NextAnim)
			
			
			
			
			
		end
	end)
end```

I would revise the serverside to

local Remote = game.ReplicatedStorage.AttackEvent

Remote.OnServerEvent:Connect(function(player, character, animation)
	if Character:FindFirstChild("Humanoid") then
		Character.Humanoid:TakeDamage(10)
		if Animation == 3 then --Removed the connection within the connection, because that would make a new connection every time they got hit, and wouldn't work right.
			local HumanoidRootPart = character:FindFirstChild("HumanoidRootPart")
			local BodyVelocity = Instance.new("BodyVelocity", HumanoidRootPart)
			BodyVelocity.Velocity = Vector3.new(0,10,0) + HumanoidRootPart.CFrame.LookVector *  200
			wait(1)
			BodyVelocity:Destroy()
		end
	end
end)

and the clientside to

local UserInputService = game:GetService("UserInputService") --Modern service instead of GetMouse

local Player = game.Players.LocalPlayer
local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")

local PunchAnimationOne = Humanoid:LoadAnimation(script:WaitForChild("Punch1Anim")) --Made animation names consistent
local PunchAnimationTwo = Humanoid:LoadAnimation(script:WaitForChild("Punch2Anim"))
local KickAnim = Humanoid:LoadAnimation(script:WaitForChild("Kick1Anim"))

local RightArm = game.Players.LocalPlayer.Character["Right Arm"]
local LeftArm = game.Players.LocalPlayer.Character["Left Arm"]
local LeftLeg = game.Players.LocalPlayer.Character["Left Leg"]

local CanDamage = false
local Table = {RightArm, LeftArm, LeftLeg}
local Animation = 1 --We just know what animation we're on, instead of trying to predict them
local Cooldown = false

PunchAnimationOne.Stopped:Connect(function() --These only advance to the next stage once the animation is complete
	CanDamage = true --Reset CanDamage so they can take damage again.
	Animation = 2
	PunchAnimationTwo:Play()
end)

PunchAnimationTwo.Stopped:Connect(function() --Plays the kick animation
	CanDamage = true --Reset CanDamage again.
	Animation = 3
	KickAnimation:Play()
end)

KickAnim.Stopped:Connect(function() --Now that we've kicked, we can reset everything and then turn off cooldown after a bit.
	Animation = 1
	CanDamage = false
	wait(0.5)
	Cooldown = false
end)

UserInputService.InputEnded:Connect(function(input, processed) --Allows for crossplatform and making sure it's not a gui click
	if input.UserInputType == Enum.UserInputType.MouseButton1 and not processed then --It's a left click
		if not Cooldown then
			Cooldown = true
			CanDamage = true
			PunchAnimationOne:Play() --We don't need to do any wait timing or anything
		end
	end
end)

for i,v in pairs(Table) do
	v.Touched:Connect(function(part)
		if CanDamage then --Might as well do the cheap check first instead of doing the expensive find every time the player walks into or on anything.
			local hit
			if part.Parent:FindFirstChild("Humanoid") then
				hit = part.Parent
			elseif part.Parent.Parent:FindFirstChild("Humanoid") --Stop hats blocking the hits. Looking at you, Festive Narwhal.
				hit = part.Parent.Parent
			end
			game.ReplicatedStorage.AttackEvent:FireServer(hit, Animation)
			CanDamage = false
		end
	end)
end

I’ve tried to explain what I did at every step, but let me know if you have any questions.


I forgot to change an Instance of NextAnim to Animation at the end, edit reflects that.

1 Like