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

Showcase:

Click here to get the model

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

-- Functions --
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 then
		local castParams = RaycastParams.new()
		castParams.FilterDescendantsInstances = {CHARACTER, workspace.CurrentCamera}
		castParams.FilterType = Enum.RaycastFilterType.Exclude
		castParams.RespectCanCollide = true
		
		local cast = workspace:Blockcast(
			CFrame.new(HUMANOID_ROOT_PART.Position),
			HUMANOID_ROOT_PART.Size - SKIN_VECTOR,
			Vector3.new(0, -1, 0) * (HUMANOID.HipHeight + 0.1),
			castParams
		)
		
		if cast then
			local soundOveride = cast.Instance:GetAttribute("SoundOveride")
			if soundOveride then
				local soundTable : table = FOOTSTEPS.Raw[soundOveride]:GetChildren()

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

				LastMaterial = soundOveride
				LastNum = newNum

				sound.Name = "step"
				sound.Volume = 0.33
				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)
			else
				local material : string = cast.Material.Name
				local materialOveride : string = cast.Instance:GetAttribute("Material")
				if materialOveride ~= nil then
					material = materialOveride
				end

				local soundTable : table = FOOTSTEPS.Raw[FOOTSTEPS[material]:GetAttribute("Value")]:GetChildren()

				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 = "step"
				sound.Volume = 0.33
				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
	end

	task.delay(delayTime, function()
		FootstepLoop()
	end)
end

FootstepLoop()

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

32 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.

5 Likes

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

Or foot print effects?

Or different particle trails effects?

Thanks

3 Likes

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

5 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.

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

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

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.

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.

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

Did you hit Play?

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

Huh what do you mean when you say that?

i can guarantee its user error

Why is the RbxCharacterSounds script empty?

it disables the default roblox character noises

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

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.

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

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

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

1 Like