Limiting movement mid air

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear! I want to limit the player’s movement mid air such that if the player jumps in any direction, he continues to go in that direction, if the player didn’t move, he won’t be able to start moving during the jump

  2. What is the issue? Include screenshots / videos if possible! I tried to do it, but my poor understanding of CFrames started to drive me crazy so I couldnt do it anymore

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub? I looked for solutions on the forum, but nothings seems to work. I also tried to come up with solutions myself

2 Likes

Little brutte-ish but i think you can set the walkspeed to 0 while the player is airborne, other possibility may be disabling player controls on JumpRequest until they’re landed again

1 Like

That wouldnt work.

I would suggest that OP looks into AirControllers (AirController | Documentation - Roblox Creator Hub). This has identical functionality to what the op wants

I’m using a custom jump system made with a script so i dont think it would work

You could grab the players velocity when they jump, then save it to a variable. And then set their velocity every frame to the original velocity.

-- /// Services /// --

local RunS = game:GetService("RunService")

-- /// Variables /// --

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local root = character:WaitForChild("HumanoidRootPart")

-- /// Functions /// --

function Jumping()
	local AVX = root.AssemblyLinearVelocity.X -- grabbing the players root velocity on the x axis
	local AVZ = root.AssemblyLinearVelocity.Z -- same with the z axis
	
	RunS:BindToRenderStep("update", 1, function() -- bind to the renderstep to update the velocity values constantly
		maintainAirMomentum(AVX, AVZ) -- sending the velocity to the function
	end)
end

function Landed()
	RunS:UnbindFromRenderStep("update") -- unbinding the function when the player lands
end

function maintainAirMomentum(AVX, AVZ)
	root.AssemblyLinearVelocity = Vector3.new(AVX, root.AssemblyLinearVelocity.Y, AVZ) -- setting the players velocity minus the y axis so they don't fly.
end



-- /// detect when the player jumps and lands (not needed depending on how your jump system works)

humanoid.StateChanged:Connect(function(old, new)
	if old == Enum.HumanoidStateType.Freefall and new == Enum.HumanoidStateType.Landed then
		Landed()
	elseif old == Enum.HumanoidStateType.Running and new == Enum.HumanoidStateType.Jumping then
		Jumping()
	end
end)


You could set the characters AssemblyLinearVelocity X and Z values in the HumanoidRootPart so when they jump it doesn’t change the direction that the player is moving until the player is grounded

I tried it, I also had to tweak some things, but it still doesnt work. It just breaks my jump completely:

sorry for the late reply, I was very busy. I will try to reply sooner next time

Could you show me how your jump script/scripts work?

here you go

Server script:

local track
game.ReplicatedStorage.Remotes.stillJump.OnServerEvent:Connect(function(player, stop)
	if stop == true then
		track:Stop()
		player.Character.Humanoid.AutoRotate = true
		return
	end
	local animation = Instance.new("Animation")
	animation.AnimationId = "rbxassetid://126307006062723"
	track = player.Character.Humanoid:LoadAnimation(animation)
	track:Play()
	track:GetMarkerReachedSignal("jump"):Connect(function()
		print("reached")
		game.ReplicatedStorage.Remotes.stillJump:FireClient(player)
		player.Character.Humanoid.AutoRotate = false
	end)
end)

local script:

game.ReplicatedStorage.Remotes.stillJump.OnClientEvent:Connect(function()
	game.Players.LocalPlayer.Character.Humanoid.StateChanged:Connect(function(old, new)
		if new == Enum.HumanoidStateType.Landed then
			game.ReplicatedStorage.Remotes.stillJump:FireServer(true)
			game.Players.LocalPlayer.HumanoidRootPart:ApplyImpulse(0, 700, 0)
			script.Event:Fire(0)
		end
	end)
end)

oh wait actually i found a mistake lemme fix it

i corrected the local script like that:

game.ReplicatedStorage.Remotes.stillJump.OnClientEvent:Connect(function()
	game.Players.LocalPlayer.Character.HumanoidRootPart:ApplyImpulse(Vector3.new(0,70,0))
	game.Players.LocalPlayer.Character.Humanoid.StateChanged:Connect(function(old, new)
		if new == Enum.HumanoidStateType.Landed then
			game.ReplicatedStorage.Remotes.stillJump:FireServer(true)
			script.Event:Fire(0)
		end
	end)
end

but it still doesnt work and just sends me flying on supersonic speeds into the air

A little confused on how the system works, Could you either send me a copy of the studio place or show me any of the other scripts that are being used.

For example

script.Event:Fire(0)

I’m not sure if this is relevant to your system or not, but I’m unable to tell what it does because I don’t have the entire picture. I think I have an idea on how this works, but I can’t really give you a fix until I know how everything works.

This sends a signal to the script you made, because I already have a handler for humanoid states. I tested it already, and it works perfectly

But I don’t have access to what that script is, I can’t try to debug it for you. unless I either have or know what the whole system does.

Alright, here is every single script involved in the system:

local UIS = game:GetService("UserInputService")

function BumpCharge()
	repeat task.wait() until not UIS:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)
	game.ReplicatedStorage.Remotes.Bump:FireServer()
end

function pressed()
	game.ReplicatedStorage.Remotes.BumpCharge:FireServer()
	BumpCharge()
end

game.Players.LocalPlayer:GetMouse().Button1Down:Connect(pressed)

UIS.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.Space then
		local timer = 0
		repeat
			timer += 0.01 
			task.wait()
		until timer >= 0.2 or not UIS:IsKeyDown(Enum.KeyCode.Space)
		print(timer)
		if UIS:IsKeyDown(Enum.KeyCode.Space) then
			local particle1 = game.ReplicatedStorage.Particles.JumpCharge.Crescents:Clone()
			local particle2 = game.ReplicatedStorage.Particles.JumpCharge.HitTwo:Clone()
			particle1.Parent = game.Players.LocalPlayer.Character.HumanoidRootPart
			particle2.Parent = game.Players.LocalPlayer.Character.HumanoidRootPart
			particle1:Emit(5)
			particle2:Emit(2)
			game.Debris:AddItem(particle1, 1)
			game.Debris:AddItem(particle2, 1)
			repeat task.wait() until not UIS:IsKeyDown(Enum.KeyCode.Space)
			game.ReplicatedStorage.Remotes.approachJump:FireServer()
		else
			game.ReplicatedStorage.Remotes.stillJump:FireServer(false)
			script.Parent.Jump.Event:Fire(1)
		end	
	end	
end)
local track
game.ReplicatedStorage.Remotes.stillJump.OnServerEvent:Connect(function(player, stop)
	if stop == true then
		track:Stop()
		player.Character.Humanoid.AutoRotate = true
		return
	end
	local animation = Instance.new("Animation")
	animation.AnimationId = "rbxassetid://126307006062723"
	track = player.Character.Humanoid:LoadAnimation(animation)
	track:Play()
	track:GetMarkerReachedSignal("jump"):Connect(function()
		print("reached")
		game.ReplicatedStorage.Remotes.stillJump:FireClient(player)
		player.Character.Humanoid.AutoRotate = false
	end)
end)
game.ReplicatedStorage.Remotes.stillJump.OnClientEvent:Connect(function()
	game.Players.LocalPlayer.Character.HumanoidRootPart:ApplyImpulse(Vector3.new(0,70,0))
	game.Players.LocalPlayer.Character.Humanoid.StateChanged:Connect(function(old, new)
		if new == Enum.HumanoidStateType.Landed then
			game.ReplicatedStorage.Remotes.stillJump:FireServer(true)
			script.Event:Fire(0)
		end
	end)
end)

local RunS = game:GetService("RunService")



local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local root = character:WaitForChild("HumanoidRootPart")



function Jumping()
	local AVX = root.AssemblyLinearVelocity.X
	local AVZ = root.AssemblyLinearVelocity.Z

	RunS:BindToRenderStep("update", 1, function()
		maintainAirMomentum(AVX, AVZ)
	end)
end

function Landed()
	RunS:UnbindFromRenderStep("update")
end

function maintainAirMomentum(AVX, AVZ)
	root.AssemblyLinearVelocity = Vector3.new(AVX, root.AssemblyLinearVelocity.Y, AVZ)
end
local RunS = game:GetService("RunService")

-- /// Variables /// --

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local root = character:WaitForChild("HumanoidRootPart")

-- /// Functions /// --

function Jumping()
	local AVX = root.AssemblyLinearVelocity.X -- grabbing the players root velocity on the x axis
	local AVZ = root.AssemblyLinearVelocity.Z -- same with the z axis

	RunS:BindToRenderStep("update", 1, function() -- bind to the renderstep to update the velocity values constantly
		maintainAirMomentum(AVX, AVZ) -- sending the velocity to the function
	end)
end

function Landed()
	RunS:UnbindFromRenderStep("update") -- unbinding the function when the player lands
end

function maintainAirMomentum(AVX, AVZ)
	root.AssemblyLinearVelocity = root.AssemblyLinearVelocity + Vector3.new(AVX, root.AssemblyLinearVelocity.Y, AVZ) -- setting the players velocity minus the y axis so they don't fly.
end



-- /// detect when the player jumps and lands (not needed depending on how your jump system works)


script.Parent.Event.Event:Connect(function(action)
	if action == 0 then
		Landed()
		print("landed")
	else
		Jumping()
		print("jumping")
	end
end)

Okay so I figured out why you were flying, It was a pretty obvious mistake I made. that’s my fault, Instead of setting the players velocity every frame

function maintainAirMomentum(AVX, AVZ)
	root.AssemblyLinearVelocity = root.AssemblyLinearVelocity + Vector3.new(AVX, root.AssemblyLinearVelocity.Y, AVZ)
end

I was adding the velocity up, This is how it should look

function maintainAirMomentum(AVX, AVZ)
	root.AssemblyLinearVelocity = Vector3.new(AVX, root.AssemblyLinearVelocity.Y, AVZ)
end

Sorry it took so long for me to notice
I didn’t notice the issue before because I was using roblox normal jump system in place.
Which for some reason this had no effect on.
I only realized it once I was messing around with your System.