(NEW VERSION) Smile4's Material Footsteps | Simple & Customizable

What’s up gamers, I was working a new game recently and the need for material specific footsteps came up again, so after rewriting my preexisting system I decided to make public it so all Roblox games could be better with little effort.

Features:
You can hear other peoples footsteps (With adjustable range)
Time between steps varies based on speed
Very easy to customize
Pretty lightweight
Force specific parts to sound like a different material
Force specific parts to use a specific footstep sound
Easy to customize jump sound
Unique sounds for landing on different materials

Showcase (old version):

Click here to get the model (New Version)

Main Script
-- Created by Smile4 / Studio Storm --

if script.Parent:IsA("StarterCharacterScripts") then
	return
end

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

-- Consts --
local SPEED_GATE = 10
local SPEED_MAXIMUM = 15
local MIN_DISTANCE = 0
local MAX_DISTANCE = 100

local FOOTSTEPS : Folder = ReplicatedStorage:WaitForChild("Footsteps")
local CHARACTER : Model = script.Parent
local HUMANOID : Humanoid = CHARACTER:WaitForChild("Humanoid")
local HUMANOID_ROOT_PART : Part = CHARACTER:WaitForChild("HumanoidRootPart")

local SKIN_VECTOR = Vector3.new(0.1, 0, 0.1)
local DELAY_UPPER = (0.33 * (SPEED_MAXIMUM / 17.5)) * (SPEED_MAXIMUM / SPEED_GATE)

-- Vars --
local LastMaterial : string = nil
local LastNum : number = nil
local Landing : boolean = false

-- Functions --
local function CastAndPlaySound(soundType : string, volume : number, hipHeightAdd : number)
	local castParams = RaycastParams.new()
	castParams.FilterDescendantsInstances = {CHARACTER, workspace.CurrentCamera}
	castParams.FilterType = Enum.RaycastFilterType.Exclude
	castParams.RespectCanCollide = true

	local HipHeight = HUMANOID.HipHeight
	if HUMANOID.RigType == Enum.HumanoidRigType.R6 then
		HipHeight = 2
	end

	local cast = workspace:Blockcast(
		CFrame.new(HUMANOID_ROOT_PART.Position),
		HUMANOID_ROOT_PART.Size - SKIN_VECTOR,
		Vector3.new(0, -1, 0) * (HipHeight + hipHeightAdd),
		castParams
	)

	if cast then
		local material : string = cast.Material.Name
		local materialOveride : string = cast.Instance:GetAttribute("Material")
		local soundOveride = cast.Instance:GetAttribute("SoundOveride")
		if materialOveride ~= nil then
			material = materialOveride
		end
		
		local soundTable : table
		if soundOveride then
			soundTable = FOOTSTEPS[soundType][soundOveride]:GetChildren()
		else
			soundTable = FOOTSTEPS[soundType][FOOTSTEPS[material]:GetAttribute("Value")]:GetChildren()
		end

		local newNum = math.random(#soundTable)
		if LastMaterial == material and #soundTable ~= 1 then
			while newNum == LastNum do
				newNum = math.random(#soundTable)
			end
		end
		local sound : Sound = soundTable[newNum]:Clone()

		LastMaterial = material
		LastNum = newNum

		sound.Name = soundType
		sound.Volume = volume
		sound.RollOffMode = Enum.RollOffMode.Linear
		sound.RollOffMinDistance = MIN_DISTANCE
		sound.RollOffMaxDistance = MAX_DISTANCE
		sound.Parent = HUMANOID_ROOT_PART
		sound:Play()

		Debris:AddItem(sound, sound.TimeLength + 0.1)
	end
end

local function FootstepLoop()
	if HUMANOID.Health <= 0 then
		return
	end
	
	local walkSpeed = Vector3.new(HUMANOID_ROOT_PART.AssemblyLinearVelocity.X, 0, HUMANOID_ROOT_PART.AssemblyLinearVelocity.Z).Magnitude
	local delayTime = math.clamp(0.33 * (SPEED_MAXIMUM / walkSpeed), 0.1, DELAY_UPPER)
	
	if walkSpeed > SPEED_GATE and not Landing then
		CastAndPlaySound("step", 0.33, 0.1)
	end

	task.delay(delayTime, FootstepLoop)
end

FootstepLoop()

local StateChanged = HUMANOID.StateChanged:Connect(function(OldState, NewState)
	
	if NewState == Enum.HumanoidStateType.Jumping then
		local sound : Sound = FOOTSTEPS.Jump:Clone()
		
		sound.Name = "jump"
		sound.Volume = 0.05
		sound.RollOffMode = Enum.RollOffMode.Linear
		sound.RollOffMinDistance = MIN_DISTANCE
		sound.RollOffMaxDistance = MAX_DISTANCE
		sound.Parent = HUMANOID_ROOT_PART
		sound:Play()
		
		Debris:AddItem(sound, sound.TimeLength + 0.1)
	elseif NewState == Enum.HumanoidStateType.Landed then
		CastAndPlaySound("land", 0.4, 2)
		Landing = true
		task.delay(0.2, function()
			Landing = false
		end)
	end
end)

HUMANOID.Died:Once(function()
	StateChanged:Disconnect()
end)

oh and if you use this in your game let me know!

40 Likes

This system doesn’t even detect when your foot hits the ground! I’m disappointed, but at least this contains better footstep sounds I can use for mine.

7 Likes

Hi, are you going to add, like different dust effects?

Or foot print effects?

Or different particle trails effects?

Thanks

5 Likes

I might make a version that adds more vanity features like that, but this release was meant to be simple and efficient.

7 Likes

It doesn’t work for on my game. I tried making a new project and it worked on that one but there is literally no output whatsoever hinting at anything that might be breaking this. I’m using ACS but I’ve got rid of all the footstep stuff that comes with ACS. Have you experienced anything similar at all? I honestly have no idea how I can fix this.

2 Likes

Very nice, implemented this in my game with different audio. I appreciate how easy you made it to swap out the sounds.

1 Like

it should work as long as you’re using humanoids and humanoidrootparts :thinking:

1 Like

I am using humanoids and humanoidrootparts. But it doesn’t work with no output at all. I remember hearing one footstep or two when walking on some props but it only works sometimes even on those, I cant replicate it. I can try screensharing you the problem if you want. Also most of my world is just terrain but I have tried parts as well and neither of them work.

1 Like

also another thing, I’m using RCM(Basically ACS) in my game but I tested this on another game also using the same version of RCM but that game doesnt have a problem.
Edit: Nvm I’m just blind I somehow had a different footstep thing installed. This doesn’t work with ACS.

1 Like

Why does this not work on for no reason at all?

1 Like

Did you hit Play?

on the 30characts of stuff for more chars of 29 + 1

1 Like

Huh what do you mean when you say that?

1 Like

i can guarantee its user error

1 Like

Why is the RbxCharacterSounds script empty?

1 Like

it disables the default roblox character noises

1 Like

Okay, I put everything in the correct places but the sounds never worked. Any suggestions?

1 Like

could be literally anything, without access to your place I couldn’t say what it could be. my recommendation is disabling parts of your game that might be causing issues until you find the culprit.

1 Like

doesn’t seem to be working with r6. either way, good resource!

1 Like

there shouldn’t be anything stopping it from working with R6?

1 Like

image
figured out why it doesnt work with R6, just change “HUMANOID.HipHeight” to “2”

1 Like