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.
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.
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?
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
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```
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.