Detecting the material of the floor your standing on

  1. **What do you want to achieve?
    I want to be able to detect what’s the material the character is standing on.

  2. **What is the issue?
    It only detects the ground you spawned on and it doesn’t update if you stand on any other ground.

  3. **What solutions have you tried so far?
    I’ve tried a couple solutions, but they don’t seem to work.

The script is in my custom animator script as a module script and it uses heartbeat service 'till I find a better solution.

local MaterialRaycast = {}
MaterialRaycast.materials = {}

local materials = MaterialRaycast.materials

function MaterialRaycast.Raycast(foot, direction)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude
	raycastParams.IgnoreWater = false

	local result = game:GetService("Workspace"):Raycast(foot.Position, direction.Unit * 180, raycastParams)

	if result then
		local hitPart = result.Instance
		local hitMaterial = hitPart.Material
		print(hitMaterial)
		
		if #materials == 0 then
			table.insert(materials, hitMaterial)
		elseif materials[1] ~= hitMaterial then
			table.remove(materials, 1)
			table.insert(materials, hitMaterial)
		end
		
		for i, value in pairs(materials) do
			print(value)
		end
	else
		print("Ray did not hit anything.")
	end
end

return MaterialRaycast

5 Likes

It looks like you are using this in a module script, where is the code that is actually calling the function?

1 Like

wait(1)
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:FindFirstChild(“Humanoid”)
local animator = humanoid:WaitForChild(“Animator”)
local footsteps = require(script:WaitForChild(“Footsteps”))
local lastFootstepSound = nil
local UIS = game:GetService(“UserInputService”)
local canJump = false
local HRP = character:WaitForChild(“HumanoidRootPart”)
local direction = Vector3.new(0,1,0)
local side = “Left” and “Right”
local leg = character:FindFirstChild(side … " Leg")
local foot = leg:FindFirstChild(side … “FootAttachment”)

local jumpModule = require(script:WaitForChild(“JumpModule”))
local materialRaycast = require(script:WaitForChild(“MaterialRaycast”))

local materials = materialRaycast.materials

local animTracks = {
Walk = script:WaitForChild(“Walk”),
Run = script:WaitForChild(“Run”),
Jump = script:WaitForChild(“Jump”),
Idle = script:WaitForChild(“Idle”),
}

for Name, Object in pairs(animTracks) do
animTracks[Name] = animator:LoadAnimation(Object)
end

function StopAnims(ignoreAnim)
for i, animTrack in pairs(animator:GetPlayingAnimationTracks()) do
if animTrack.Name == ignoreAnim or ignoreAnim == “Run” and animTracks.Name == “Walk” then
continue
end
animTrack:Stop()
end
end

local function Movement()
if humanoid.FloorMaterial ~= Enum.Material.Air or humanoid.FloorMaterial ~= Enum.Material.Water then
if animTracks[“Run”].isPlaying then
animTracks[“Walk”]:Stop()
elseif animTracks[“Walk”].isPlaying then
animTracks[“Run”]:Stop()
end

	if humanoid.WalkSpeed <= 9 and humanoid.MoveDirection.Magnitude > 0 then
		animTracks["Run"]:Stop()
		animTracks["Walk"]:Play()
	elseif humanoid.WalkSpeed > 9 and humanoid.MoveDirection.Magnitude > 0 then
		animTracks["Walk"]:Stop()
		animTracks["Run"]:Play()
	elseif humanoid.MoveDirection.Magnitude == 0 then
		animTracks["Walk"]:Stop()
		animTracks["Run"]:Stop()
		animTracks["Idle"]:Play()
	end
end

end

local function PlayFootstepSound(foot, material)
if not foot then return end

local sounds = footsteps.sounds[material]
if not sounds then return end

local random = Random.new()
local soundId = sounds[random:NextInteger(1, #sounds)]

if soundId and soundId ~= lastFootstepSound then
	lastFootstepSound = soundId
	local sfx = Instance.new("Sound")
	sfx.SoundId = soundId
	sfx.RollOffMaxDistance = 100
	sfx.RollOffMinDistance = 10
	sfx.Volume = footsteps.volume[material] or 0.5
	sfx.Parent = foot
	sfx:Play()
	task.spawn(function()
		sfx.Ended:Wait()
		sfx:Destroy()
	end)
else
	PlayFootstepSound(foot, material)
end

end

local function OnFootStep(side)
local leg = character:FindFirstChild(side…" Leg")
local foot = leg:FindFirstChild(side…“FootAttachment”)
local floorMaterial = humanoid.FloorMaterial
local material = footsteps.materialMap[floorMaterial]

PlayFootstepSound(foot, material)

end

function Jump()
UIS.InputBegan:Connect(function(input, gpe)
if input.KeyCode == Enum.KeyCode.Space then
StopAnims()
animTracks[“Jump”]:Play()
wait(animTracks[“Jump”].Length + 0.1)
jumpModule.Jumping(HRP)
end
end)
end

function AnimationLoader()
animTracks[“Walk”].Priority = Enum.AnimationPriority.Movement
animTracks[“Run”].Priority = Enum.AnimationPriority.Movement
animTracks[“Jump”].Priority = Enum.AnimationPriority.Action
animTracks[“Idle”].Priority = Enum.AnimationPriority.Idle

humanoid.Running:Connect(Movement)	
Jump()

animTracks["Idle"]:Play()

animTracks["Walk"]:GetMarkerReachedSignal("Footstep"):Connect(OnFootStep)
animTracks["Run"]:GetMarkerReachedSignal("Footstep"):Connect(OnFootStep)

end

AnimationLoader()

game:GetService(“RunService”).Heartbeat:Connect(function()
materialRaycast.Raycast(foot, direction)
end)

2 Likes

You can use Humanoid.FloorMaterial. Here’s how to use it on the player:

print(player.Character.Humanoid.FloorMaterial)

Learn more: Humanoid | Documentation - Roblox Creator Hub

3 Likes

Wow… I did ask for it though… didn’t I XD

1 Like

It looks like you are already using the humanoid.floormaterial

image

So where exactly is the module script coming into play?

1 Like

I fixed it. I genuinely don’t know why it didn’t work.

1 Like

You dont need to use Raycast!
Use:

humanoid:GetPropertyChangedSignal("FloorMaterial")

Example:

[StarterCharacterScripts]

local hum = script.Parent:WaitForChild("Humanoid,")
humanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
local NewMaterial = humanoid.FloorMaterial
--Returns an Enum
if NewMaterial == Enum.Material.Sand then
 print(Sand)
 humanoid.HipHeight -= 2
end
)
1 Like

Just on another note, it looks like in the heartbeat, you are calling the module function, but not taking a return from it.

image

So the result it is returning is not being used

1 Like

I’m a bit of a beginner so how would i return from it?

1 Like
game:GetService("RunService").Heartbeat:Connect(function()
  local result = materialRaycast.Raycast(foot,direction)
  -- do something with 'result' which should hold the material or whatever was returned from the function
end)
1 Like

Alos, in your raycast function you are not returning anything

local MaterialRaycast = {}
MaterialRaycast.materials = {}

local materials = MaterialRaycast.materials

function MaterialRaycast.Raycast(foot, direction)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude
	raycastParams.IgnoreWater = false

	local result = game:GetService("Workspace"):Raycast(foot.Position, direction.Unit * 180, raycastParams)

	if result then
		local hitPart = result.Instance
		local hitMaterial = hitPart.Material
		print(hitMaterial)

                -- Return the material
                return hitMaterial
        
	else
		print("Ray did not hit anything.")
	end
end

return MaterialRaycast
2 Likes

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