How would I prevent a player from being able to move/change directions in midair?

For my game I’ve made a custom jump in order to extend how far it reaches and to reduce the height for it. I’ve done this by setting jump power to 0 and just having it set up to where a force will be applied whenever the conditions to jump are set.

The Problem: Players are able to move any direction they want while mid-air, which is normal for most games, however in mine I’d like them to be almost locked into the jump and committed to wherever they’re jumping to.

I have searched far and wide for any support on this but have come up with nothing. Setting WalkSpeed to 0 freezes the character. I can’t increase the force of the jump too much because I need the game to be lower gravity than normal. The ControllerManager and AirController instances didn’t help much, unless if I just used them wrong (to be honest I don’t really understand them). I tried looking through the core scripts for anything related to air physics but came up short.

Here’s the script:

local uis = game:GetService("UserInputService")
local player = game:GetService("Players").LocalPlayer
local character = player.CharacterAdded:Wait()
local hum = character:WaitForChild("Humanoid")
local jumpdebounce = false
local isfall = false

local function playerlanded(duration)
	task.wait(duration)
	hum.WalkSpeed = 14
	hum.AutoRotate = true
	isfall = false
end

uis.InputBegan:Connect(function(input, gpe) 
	if gpe then
		return
	else 
		if input.KeyCode == Enum.KeyCode.LeftShift and hum:GetState() ~= Enum.HumanoidStateType.Freefall and isfall == false then
			for c = 0, 8, 2 do
				if not uis:IsKeyDown(Enum.KeyCode.LeftShift) then
					character.Humanoid.WalkSpeed = 14
					break
				end
				character.Humanoid.WalkSpeed += 2
				task.wait(0.1)
			end
		end
		
		if input.KeyCode == Enum.KeyCode.Space and hum.WalkSpeed == 24 and jumpdebounce == false and hum.FloorMaterial ~= Enum.Material.Air then
			jumpdebounce = true
			local jumpforce = Instance.new("LinearVelocity")
			local hlv = character.HumanoidRootPart.CFrame.LookVector
			jumpforce.Parent = character
			jumpforce.Attachment0 = character.HumanoidRootPart.RootAttachment
			jumpforce.MaxForce = math.huge
			jumpforce.VectorVelocity = (hlv * 45) + Vector3.new(0,25,0)
			task.wait(0.1)
			jumpforce:Destroy()
			task.wait(1.5)
			jumpdebounce = false
		end
	end
end)

uis.InputEnded:Connect(function(input, gpe)
	task.wait()
	if input.KeyCode == Enum.KeyCode.LeftShift and isfall == false and hum:GetState() ~= Enum.HumanoidStateType.Freefall then
		character.Humanoid.WalkSpeed = 14
	end
end)

hum.StateChanged:Connect(function(old, new)
	print("hi")
	if new == Enum.HumanoidStateType.Freefall then
		task.wait(1)
		if hum:GetState() == Enum.HumanoidStateType.Freefall then
			isfall = true
			hum.AutoRotate = false
			for c = hum.WalkSpeed, 1, -1 do
				hum.WalkSpeed = c
				task.wait(0.01)
				if hum:GetState() == Enum.HumanoidStateType.Landed then
					hum.WalkSpeed = 0
					playerlanded(0.75)
					break
				end
			end
		end
	end
	if new == Enum.HumanoidStateType.Landed and hum.WalkSpeed == 1 then
		hum.WalkSpeed = 0
		playerlanded(1.5)
	end
end)

Any help would be appreciated as I am losing my mind over this

1 Like

I feel like the best way to do this is to disable the player’s control of the character from when jump is activated till when landed.

Check this out!

1 Like

from my understanding, you are saying that you want to keep the player from changing where they look at, whether they would move their character angles due to shift lock or first person mode.

i would say you should just get the orientation of the HRP right before the body velocity is applied, and play that on a RunService to make sure that the orientation is kept. i dont really recommend disabling the player module just bcuz, and i’m not sure if that would help you at all.

1 Like

I think I implemented what you said, and unfortunately it didn’t work. It yielded some kinda funny results though lol

Also you’re right about not disabling the module since when it’s reenabled you have to press your keys again to keep moving, which feels kinda janky. I’m gonna keep playing around with the orientation though and see what I can come up with.

Here’s what I made btw:

local function jumplock(orientation)
	local currentOrientation = character.HumanoidRootPart.Orientation
	jumplockthing = rs.Stepped:Connect(function()
						currentOrientation = character.HumanoidRootPart.Orientation
						if currentOrientation ~= orientation then
							character.HumanoidRootPart.Orientation = orientation
						end
					end)
end

And an edit to original script:

if input.KeyCode == Enum.KeyCode.Space and hum.WalkSpeed == 24 and jumpdebounce == false and hum.FloorMaterial ~= Enum.Material.Air then
			jumpdebounce = true
			local jumpforce = Instance.new("LinearVelocity")
			local hlv = character.HumanoidRootPart.CFrame.LookVector
			local rpo = character.HumanoidRootPart.Orientation
			jumpforce.Parent = character
			jumpforce.Attachment0 = character.HumanoidRootPart.RootAttachment
			jumpforce.MaxForce = math.huge
			jumpforce.VectorVelocity = (hlv * 45) + Vector3.new(0,25,0)
			jumplock(rpo)
			task.wait(0.1)
			jumpforce:Destroy()
			task.wait(0.75)
			jumplockthing:Disconnect()
			task.wait(1.5)
			jumpdebounce = false
		end
1 Like

You could try making a custom move function forked from the player module that just calls the normal move function if the players floor material is not equal to air

1 Like

Sorry, I’m not too accustomed to how module scripts really work. I’m assuming what you mean is rewriting a function in the player module? Where would I find it? Unless if I’m completely off, which is a good chance

1 Like

In order to find PlayerModule, you can play the game, search through your own player instance in “Players” service, and then go in “PlayerScripts”. PlayerModule should be a child under PlayerScripts.

1 Like

Its really simple, you can just require the player module like the previous person did and access the controls, from there you can re state the move function, like this:

local playerModule = require(script.Parent:WaitForChild("PlayerModule"))

playerModule.controls.moveFunction = function(player,direction,cameraRelative)
	local hum = player.Character and player.Character:FindFirstChild("Humanoid")
	if not hum or hum.FloorMaterial ~= Enum.Material.Air then
		player:Move(direction,cameraRelative)
	end
end

this is a local script in starter player scripts

2 Likes

Putting that in the script worked, thank you! I think I understand the process behind this, but I’ll do a bit more research to fully grasp it. Now I don’t have to go insane anymore, lol

2 Likes

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