I’m making a knockback system, and the player loses velocity mid-air, I’m not open to use physics state or anything like that as that basically cancels all animations the humanoid is playing, and I want a animation to play mid knockback, can anyone help me?
I struggled with a similar issue where the player could stop or turn mid-jump in a low gravity environment which seemed goofy. Physics was a mess and never worked. This code takes the players initial velocity, sets them to freefall, moves them in the right direction under gravity, then hands control back to the player when landed. It might work for your needs. It unbinds keyboard movement to prevent the player stoping or changing direction mid-flight.
The code checks which movement keys are down when landed and moves the player in that direction. This is important because presses are not sensed during the jump when the keys are unbound. It keeps watching until all the movement keys have been released.
Workspace gravity is set to 5.78 in my experience to simulate moon’s gravity if you want to test it out. I am not sure if freefall will work with your animations or not. Maybe the code would work without freefall.
--
-- Prevent player turns mid-jump and stopping too soon in lower gravity
--
local UserInputService = game:GetService("UserInputService")
local ContextActionService = game:GetService("ContextActionService")
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)
humanoid:SetStateEnabled(Enum.HumanoidStateType.Climbing, false)
local jumpVertVel = 7
local gravAcc = workspace.Gravity
local deltaTime = 0.25
local jumping = false
local function jump()
if humanoid.Sit == true then return end
if jumping == true then return end
if humanoid.FloorMaterial == Enum.Material.Air then return end
local landed = false
local initialVelocity = humanoid.RootPart.AssemblyLinearVelocity
local initialPosition = humanoid.RootPart.Position
humanoid:ChangeState(Enum.HumanoidStateType.Freefall)
-- disable keyboard movement keys
ContextActionService:BindAction("freezeMovement", function() return Enum.ContextActionResult.Sink end, false, unpack(Enum.PlayerActions:GetEnumItems()))
humanoid.RootPart.AssemblyLinearVelocity = Vector3.new(initialVelocity.X, jumpVertVel, initialVelocity.Z)
local moveToTarget = initialPosition + initialVelocity * 20
jumping = true
local Y_Velocity = jumpVertVel
local landedCount = 0 -- require sensing ground 3 time for landing to prevent false landings
while not landed do
wait(deltaTime)
humanoid:MoveTo(moveToTarget)
Y_Velocity = Y_Velocity - gravAcc * deltaTime
humanoid.RootPart.AssemblyLinearVelocity = Vector3.new(initialVelocity.X, Y_Velocity, initialVelocity.Z)
if humanoid.FloorMaterial ~= Enum.Material.Air then
landedCount = landedCount + 1
if landedCount >= 3 then
landed = true
end
end
if humanoid.Sit == true then
landed = true
end
end
jumping = false
ContextActionService:UnbindAction("freezeMovement")
local allMoveButtonsReleased = false
local wkeyreleased = false
local dkeyreleased = false
local skeyreleased = false
local akeyreleased = false
local lookVector
local directionVector
local x1, x2, z1, z2
local angle
-- movement button presses lost in ContextActionService Bind/Unbind. Move manually until all movement keys released
while allMoveButtonsReleased == false do
if humanoid.Sit == true then return end
local wkey = UserInputService:IsKeyDown(Enum.KeyCode.W)
local skey = UserInputService:IsKeyDown(Enum.KeyCode.S)
local akey = UserInputService:IsKeyDown(Enum.KeyCode.A)
local dkey = UserInputService:IsKeyDown(Enum.KeyCode.D)
local spacekey = UserInputService:IsKeyDown(Enum.KeyCode.Space)
initialPosition = humanoid.RootPart.Position
lookVector = game.Workspace.CurrentCamera.CFrame.LookVector
x1 = lookVector.X
z1 = lookVector.Z
angle = 999
if wkey and dkey then
angle=45
elseif dkey and skey then
angle=135
elseif skey and akey then
angle=225
elseif akey and wkey then
angle=315
elseif wkey then
angle=0
elseif dkey then
angle=90
elseif skey then
angle=180
elseif akey then
angle=270
end
if angle > 900 then -- find direction from look vector based on keys pressed
moveToTarget = initialPosition
else
angle = math.rad(angle)
x2 = x1*math.cos(angle) - z1*math.sin(angle)
z2 = x1*math.sin(angle) + z1*math.cos(angle)
directionVector = Vector3.new(x2, 0, z2)
moveToTarget = initialPosition + directionVector * 100
end
humanoid:MoveTo(moveToTarget)
if not wkey then wkeyreleased=true end
if not dkey then dkeyreleased=true end
if not skey then skeyreleased=true end
if not akey then akeyreleased=true end
if wkeyreleased and dkeyreleased and skeyreleased and akeyreleased then
allMoveButtonsReleased = true
end
if spacekey then
wait(0.2) -- need a moment for player velocity to change for next jump
allMoveButtonsReleased = true
jump()
end
wait(0.2) -- while loop wait
end
end
UserInputService.JumpRequest:Connect(jump)