Custom jump: humanoid FloorMaterial changes prematurely

I made a custom jump using ApplyImpulse on the rootpart. I just added the ability for the player to hold space while in the air to jump again as soon as they hit the ground, to make jumping easier to time.

The issue is that while falling down the player character is propelled upward before actually hitting the ground, making the character hop in the air continually. Printing the state of the humanoid shows that the issue lies with the humanoid FloorMaterial property changing from Air to Running for 3-5 steps without it visually touching the ground.

My code looks like this:

humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)

local canJump = true

UserInputService.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.Space then
		canJump = true
	end
end)

RunService.Stepped:Connect(function(_, dt)	
	print(humanoid:GetState())

	if UserInputService:IsKeyDown(Enum.KeyCode.Space) and
		canJump == true and
		humanoid.FloorMaterial ~= Enum.Material.Air then
		canJump = false
		-- velocity on Y axis needs to be set to zero for the impulse to work predictably
		root.AssemblyLinearVelocity = Vector3.new(root.AssemblyLinearVelocity.X, 0, root.AssemblyLinearVelocity.Z)
		root:ApplyImpulse(Vector3.new(0, 1000, 0))
	end
end)

I suspect the issue might be setting the Y velocity to 0, but without this i can’t get the jump to work at all (character just won’t disconnect from the ground probably because the downward velocity is too high).
If anyone has suggestions for alternative ways to do a custom jump those are welcome too.

You could use raycasts to see if the player is on the ground.
Just raycast from their HRP down to their feet and you can see if a RaycastResult is returned.

Holding space down already does this in-game though.

I ended up using this function to send raycasts down from the corners of the rootpart to determine if the player is on the ground.

local rayCastDir = Vector3.new(0, -10, 0)
local rayCastParams = RaycastParams.new()
rayCastParams.FilterDescendantsInstances = {character}
rayCastParams.FilterType = Enum.RaycastFilterType.Exclude

local raycastResults = {}
raycastResults[1] = workspace:Raycast(corners.bottomFrontRight, rayCastDir, rayCastParams)
raycastResults[2] = workspace:Raycast(corners.bottomFrontLeft, rayCastDir, rayCastParams)
raycastResults[3] = workspace:Raycast(corners.bottomBackRight, rayCastDir, rayCastParams)
raycastResults[4] = workspace:Raycast(corners.bottomBackLeft, rayCastDir, rayCastParams)
	
for i = 1, 4 do
	if raycastResults[i] ~= nil and raycastResults[i].Distance < 2.05 then
		onFloor = true
	end
end

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