I dont want this code only works if both conditions met

hi, hows yall doing, so i was coding a script that allows player to slowly fall when they hold space key in the freefall state the problem is

first
code only works if both conditions meet
what i want is to make if player is holding a space key while is in the air then fires this code
if he doesnt hold a key in air then doesnt do

second
How do i make player under linearVelocity still be able to move

here is the code

local UserInputService = game:GetService("UserInputService")

local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
local rootPart = character:WaitForChild("HumanoidRootPart")
local rootAttachment = rootPart:WaitForChild("RootAttachment")

local linearVelocity: LinearVelocity  = nil
local inputEndedConnection: RBXScriptConnection? = nil

local function release()
	if linearVelocity ~= nil then
		linearVelocity:Destroy()
		linearVelocity = nil
	end
	
	if inputEndedConnection ~= nil then
		inputEndedConnection:Disconnect()
		inputEndedConnection = nil
	end
end

humanoid.StateChanged:Connect(function(old, new)
	if new == Enum.HumanoidStateType.Freefall then
		task.wait(0.2) -- this wait is only way to sorta make it work
		if UserInputService:IsKeyDown(Enum.KeyCode.Space) then
			if inputEndedConnection == nil then
				inputEndedConnection = UserInputService.InputEnded:Connect(function(input, gameProcessed)
					if input.KeyCode == Enum.KeyCode.Space then
						release()
					end
				end)
			end
			
			if linearVelocity == nil then
				linearVelocity = Instance.new("LinearVelocity")
				assert(linearVelocity ~= nil)
				
				linearVelocity.Name = "SlowFallingVelocity"
				linearVelocity.Attachment0 = rootAttachment
				linearVelocity.RelativeTo = Enum.ActuatorRelativeTo.World
				linearVelocity.MaxForce = math.huge
				linearVelocity.VectorVelocity = Vector3.new(0, -5, 0)
				linearVelocity.Parent = rootPart
			end
		elseif new == Enum.HumanoidStateType.Running or new == Enum.HumanoidStateType.Landed then
			release()
		end
	end
end)

at very least script does the job when it comes to player lands to the ground and linearVelocity getting destroyed and when player no longer hold a space key

1 Like

A good way to do is to see when the player holds space using UserInputService.InputBegan/Ended and then use Humanoid:GetState() to see the state. This may fix the first issue.

And to make the player still move while falling, you need to use VectorForces, rather than using velocity.

1 Like

the problem is
first
i actually tried using inputbegan and inputended but for some reason code just doesnt work

second
i dont know how to make vectorforce have slow falling effect

1 Like

Glad to see my code from before is still working and proved to be useful haha.

As @K4ttt_i has said, connecting to the InputBegan signal is your solution here. We also keep the existing event but turn the creation of the LinearVelocity into its own function so we have 2 conditions without copy pasting code.

As for your LinearVelocity issue, you can set the ForceLimitMode to Enum.ForceLimitMode.PerAxis and change the MaxAxesForce to Vector3.new(0, math.huge, 0). This means that the LinearVelocity will have no affect on the X and Z axes and can apply as much force as it needs to on the Y axis.

The solution is a little bit tricky. Unfortunately, the Enum.HumanoidStateType.Freefall state runs almost immediately after the Enum.HumanoidStateType.Jumping state, meaning it does bug out at the start of the jump. I’ve implemented a workaround by creating a thread that:

  1. Waits until the Humanoid state is Enum.HumanoidStateType.Freefall and the HumanoidRootPart’s AssemblyLinearVelocity.Y is less than 0.
  2. Attaches the slow falling LinearVelocity.

This allows us to cancel the check and the creation with a simple task.cancel(thread) call.

Here is a working version that is not strictly typed:

local UserInputService = game:GetService("UserInputService")

local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
local rootPart = character:WaitForChild("HumanoidRootPart")
local rootAttachment = rootPart:WaitForChild("RootAttachment")

local linearVelocity = nil
local inputEndedConnection = nil
local waitForCanSlowFallThread = nil

local function release()
	if linearVelocity ~= nil then
		print("destroyed linear velocity")
		
		linearVelocity:Destroy()
		linearVelocity = nil
	end

	if inputEndedConnection ~= nil then
		inputEndedConnection:Disconnect()
		inputEndedConnection = nil
	end
	
	if waitForCanSlowFallThread ~= nil then
		task.cancel(waitForCanSlowFallThread)
		waitForCanSlowFallThread = nil
	end
end

local function attach()
	if inputEndedConnection == nil then
		inputEndedConnection = UserInputService.InputEnded:Connect(function(input, gameProcessed)
			if input.KeyCode == Enum.KeyCode.Space then
				release()
			end
		end)
	end
	
	waitForCanSlowFallThread = task.spawn(function()
		while not (humanoid:GetState() == Enum.HumanoidStateType.Freefall and rootPart.AssemblyLinearVelocity.Y < 0) do
			task.wait()
		end

		if linearVelocity == nil then
			linearVelocity = Instance.new("LinearVelocity")
			linearVelocity.Name = "SlowFallingVelocity"
			linearVelocity.Attachment0 = rootAttachment
			linearVelocity.RelativeTo = Enum.ActuatorRelativeTo.World
			linearVelocity.ForceLimitMode = Enum.ForceLimitMode.PerAxis
			linearVelocity.MaxAxesForce = Vector3.new(0, math.huge, 0)
			linearVelocity.VectorVelocity = Vector3.new(0, -5, 0)
			linearVelocity.Parent = rootPart
			
			print("attached linear velocity")
		end
	end)
end

humanoid.StateChanged:Connect(function(old, new)
	if new == Enum.HumanoidStateType.Freefall then
		if UserInputService:IsKeyDown(Enum.KeyCode.Space) then
			attach()
		else
			release()
		end
	elseif new == Enum.HumanoidStateType.Running or new == Enum.HumanoidStateType.Landed then
		release()
	end
end)

UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
	if gameProcessedEvent then return end
	
	if input.KeyCode == Enum.KeyCode.Space and humanoid:GetState() == Enum.HumanoidStateType.Freefall then
		attach()
	end
end)

Note:
I removed the assert(linearVelocity ~= nil) line as it is only used to bypass strict warning.

2 Likes

its always nice to see explanation instead of just putting a code

oh btw its works
thanks so much

2 Likes

Oof, I forgot about this issue. Welp, good job beating me to the solution.

2 Likes