Alternatives to Humanoid.FloorMaterial?

I’ve come across this problem where whenever I hold down the space bar to make the player jump, the FloorMaterial remains nil even after hitting the ground and jumping again. I use the Humanoid.FloorMaterial property for my double jump and it solely relies on the FloorMaterial property to make the double jump happen. Thus, my double jump doesn’t work and it looks like this:

https://gyazo.com/9c232e71e19737bef8ab75bc00c7e188

As you can see in the video, the FloorMaterial property doesn’t properly detect the material of the baseplate and leaves it nil or Enum.Material.Air. I will provide my double jump script if that may help solve the problem.

--Services--
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

--Variables--
local playerDebounce = {}

--Functions--
local function JumpListener(player)	
	local debounce = playerDebounce[player].Debounce
	
	if not debounce then
		playerDebounce[player].Debounce = true
	
		local character = player.Character or player.CharacterAdded:Wait()
		local humanoid = character:WaitForChild("Humanoid")
		local HRP = character:WaitForChild("HumanoidRootPart")
		
		local DoubleJumpEnabled = playerDebounce[player].DoubleJumpEnabled
		local DoubleJumped = playerDebounce[player].DoubleJumped
		local CurrentJump = playerDebounce[player].CurrentJump

		local MAX_JUMPS = 2
		local AnimationHandler
		
		--Animations--
		local JumpAnimation = Instance.new("Animation")
		JumpAnimation.AnimationId = "rbxassetid://5113328861"
		JumpAnimation = humanoid:LoadAnimation(JumpAnimation)
		
		local RollAnimation = Instance.new("Animation")
		RollAnimation.AnimationId = "rbxassetid://5113315362"
		RollAnimation = humanoid:LoadAnimation(RollAnimation)
		
		--Functions--
		local function Grounded()
			return humanoid.FloorMaterial ~= Enum.Material.Air
		end
		
		local function JumpHandler()
			local Verify = (
				DoubleJumpEnabled
				and not DoubleJumped
				and not Grounded()
			)
			
			if Verify then
				print("Double jumping")
				HRP.Velocity = Vector3.new(0,65,0)
				RollAnimation:Play()
			else
				print("Jumping")
				JumpAnimation:Play()
			end
		end
		
		local function SpamHandler(AnimationTrack)
			if AnimationTrack.Animation.AnimationId == "rbxassetid://5113315362" then
				print("Handling")
				AnimationHandler:Disconnect()
				DoubleJumpEnabled = false
				DoubleJumped = true
				
				repeat wait() until Grounded()
				
				CurrentJump = CurrentJump + 1
				DoubleJumpEnabled = CurrentJump < MAX_JUMPS
			elseif AnimationTrack.Animation.AnimationId == "rbxassetid://5113328861" then
				print("Setting")
				
				CurrentJump = 1
				DoubleJumpEnabled = true
				DoubleJumped = false
				
				repeat wait() until Grounded() or DoubleJumped
			end			
			playerDebounce[player].DoubleJumpEnabled = DoubleJumpEnabled
			playerDebounce[player].DoubleJumped = DoubleJumped
			playerDebounce[player].CurrentJump = CurrentJump
			playerDebounce[player].Debounce = false
		end
		
		--Listeners--
		JumpHandler()
		AnimationHandler = humanoid.AnimationPlayed:Connect(SpamHandler)
	end
end

--Listeners/Events--
game.Players.PlayerAdded:Connect(function(player)
	playerDebounce[player] = {
		Debounce = false,
		DoubleJumpEnabled = false,
		DoubleJumped = false,
		CurrentJump = 0
	}
end)

game.Players.PlayerRemoving:Connect(function(player)
	playerDebounce[player] = nil
end)

--RemoteEvents--
game.ReplicatedStorage.JumpEvent.OnServerEvent:Connect(JumpListener)

Have you considered raycasting?

local function Get_Floor_Material()
local ray = Ray.new(char.HumanoidRootPart.Position, Vector3.new(0, -5, 0))
local hit = workspace:FindPartOnRayWithIgnoreList(ray, {char})

if hit then
print(hit.Material)
end
end
1 Like

I’ll consider using this (30 characters)

The ray works, but not on edges. Any way to fix this?

You could cast 4 rays from each edge of the character.

WorldModel:FindPartOnRay() returns the BasePart or terrain cell hit, the point of intersection, the surface normal at the point of intersection, and the associated Material hit.

local Height = (0.5 * RootPart.Size.Y) + Humanoid.HipHeight
local ray = Ray.new(RootPart.Position, Vector3.new(0, -1, 0) * (Height + .1))
local Hit, Point, Normal, Material = workspace:FindPartOnRay(ray, Character)

if Material then
print(Material) -- enum
end

I am not sure if you can get the Material using Hit.Material if Hit is a terrain cell, so much rather use the Material which :FindPartOnRay() returns.

Also, the distance between the RootPart and the ground won’t always be covered by casting a ray downwards 5 studs as different rigs will have different heights.

2 Likes