I’m working on a footstep system. All is going rather well except for a rather major issue where the Sound.Playing state for my footsteps is seemingly randomly set to false. The only way to undo this in playtesting mode is to jump.
Here’s the server script that handles the majority of the footsteps.
local players = game:GetService("Players")
local running = game.ReplicatedStorage:WaitForChild("running")
local notrunning = game.ReplicatedStorage:WaitForChild("notrunning")
local footstepsModule = require(game.ReplicatedStorage:WaitForChild("FootstepModule"))
local runservice = game:GetService("RunService")
cooldown = .38
local function footstepsplayingdetect(footsteps)
runservice.Heartbeat:Connect(function()
return footsteps.Playing ~= true and footsteps.Playing == false
end)
end
local function footstepsplayingfix(footsteps)
if footstepsplayingdetect(footsteps) then
footsteps.Playing = true
end
end
local function check_movement(humanoid)
return humanoid.WalkSpeed > 0 and humanoid.MoveDirection.Magnitude > 0 and humanoid.FloorMaterial ~= Enum.Material.Air
end
local function isrunning(running, notrunning)
notrunning.OnServerEvent:Connect(function()
cooldown = .38
end)
running.OnServerEvent:Connect(function()
cooldown = .28
end)
end
local function get_material(floorMaterial)
local SoundTable = footstepsModule:GetTableFromMaterial(floorMaterial)
return footstepsModule:GetRandomSound(SoundTable)
end
local function runningmovement(humanoid, footsteps)
if check_movement(humanoid) then
isrunning(running, notrunning)
footstepsplayingfix(footsteps)
local soundId = get_material(humanoid.FloorMaterial)
footsteps.SoundId = soundId
footsteps:Play()
wait(cooldown)
else
repeat
wait()
until
check_movement(humanoid)
return
end
end
players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
local humanoid = character:WaitForChild("Humanoid")
local root = character:WaitForChild("HumanoidRootPart")
local footsteps = Instance.new("Sound")
footsteps.Name = "footstepssound"
footsteps.Volume = 0.8
footsteps.RollOffMaxDistance = 40
footsteps.RollOffMinDistance = 2
footsteps.RollOffMode = Enum.RollOffMode.Linear
footsteps.Parent = root
while true do
runningmovement(humanoid, footsteps)
end
end)
end)
Every player gets a footstep, placed inside the HumanoidRootPart. It picks from a list of materials, based on what the player is standing on, and if the player is moving, plays the sound. Once the sound is finished, it gets and plays another, so on and so forth.
I’ve tried remedying the situation myself, seen in footstepsplayingdetect()
and footstepsplayingfix()
however they either don’t work at all or don’t work very well.
Some other scripts too, if you think you need to look at them.
ModuleScript
I have checked alot (not all of them) of the Id’s in this list, which wasn’t made by me, to see if they’re either broken or privated and to my knowledge they are neither and I do not believe the problem lies in the ModuleScript.
-- this was made by uglyburger0, all credits to them. none to me
local main = {}
main.SoundIds = {
["Bass"] = {
"rbxassetid://9126748907",
"rbxassetid://9126748813",
"rbxassetid://9126748580",
"rbxassetid://9126748691",
"rbxassetid://9126748431",
"rbxassetid://9126748324",
"rbxassetid://9126748239",
"rbxassetid://9126748185",
"rbxassetid://9126748045",
"rbxassetid://9126747958"
},
["Carpet"] = {
"rbxassetid://9126748130",
"rbxassetid://9126747861",
"rbxassetid://9126747720",
"rbxassetid://9126747529",
"rbxassetid://9126747412",
"rbxassetid://9126747283",
"rbxassetid://9126746732",
"rbxassetid://9126746837",
"rbxassetid://9126747132",
"rbxassetid://9126746984",
"rbxassetid://9126746598",
"rbxassetid://9126746481",
"rbxassetid://9126746371",
"rbxassetid://9126746291"
},
["Concrete"] = {
"rbxassetid://9126746167",
"rbxassetid://9126746098",
"rbxassetid://9126745995",
"rbxassetid://9126745877",
"rbxassetid://9126745774",
"rbxassetid://9126745574",
"rbxassetid://9126745336",
"rbxassetid://9126745241",
"rbxassetid://9126745445",
"rbxassetid://9126745052",
"rbxassetid://9126745141",
"rbxassetid://9126745676",
"rbxassetid://9126744969",
"rbxassetid://9126744894",
"rbxassetid://9126744639",
"rbxassetid://9126744789",
"rbxassetid://9126744481"
},
["Dirt"] = {
"rbxassetid://9126744390",
"rbxassetid://9126744718",
"rbxassetid://9126744263",
"rbxassetid://9126744157",
"rbxassetid://9126744066",
"rbxassetid://9126744009",
"rbxassetid://9126743796",
"rbxassetid://9126743938",
"rbxassetid://9126743711",
"rbxassetid://9126743879",
"rbxassetid://9126743613",
"rbxassetid://9126743481",
"rbxassetid://9126743338",
"rbxassetid://9126743086"
},
["Glass"] = {
"rbxassetid://9126742971",
"rbxassetid://9126742461",
"rbxassetid://9126742875",
"rbxassetid://9126742786",
"rbxassetid://9126743193",
"rbxassetid://9126742680",
"rbxassetid://9126742582",
"rbxassetid://9126742510"
},
["Grass"] = {
"rbxassetid://9126742396",
"rbxassetid://9126741427",
"rbxassetid://9126742333",
"rbxassetid://9126742215",
"rbxassetid://9126742271",
"rbxassetid://9126742031",
"rbxassetid://9126741934",
"rbxassetid://9126742105",
"rbxassetid://9126741826",
"rbxassetid://9126741594",
"rbxassetid://9126741512",
"rbxassetid://9126741741",
"rbxassetid://9126741674"
},
["Gravel"] = {
"rbxassetid://9126741273",
"rbxassetid://9126740393",
"rbxassetid://9126741200",
"rbxassetid://9126741051",
"rbxassetid://9126741128",
"rbxassetid://9126740951",
"rbxassetid://9126740802",
"rbxassetid://9126740724",
"rbxassetid://9126740524",
"rbxassetid://9126740623"
},
["Ladder"] = {
"rbxassetid://9126740217",
"rbxassetid://9126739039",
"rbxassetid://9126740133",
"rbxassetid://9126739947",
"rbxassetid://9126740044",
"rbxassetid://9126740305",
"rbxassetid://9126739834",
"rbxassetid://9126739622",
"rbxassetid://9126739505",
"rbxassetid://9126739406",
"rbxassetid://9126739332",
"rbxassetid://9126739229"
},
["Metal_Auto"] = {
"rbxassetid://9126739090",
"rbxassetid://9126738967",
"rbxassetid://9126738896",
"rbxassetid://9126738732",
"rbxassetid://9126738543",
"rbxassetid://9126738634"
},
["Metal_Chainlink"] = {
"rbxassetid://9126738423",
"rbxassetid://9126737791",
"rbxassetid://9126738338",
"rbxassetid://9126738197",
"rbxassetid://9126738113",
"rbxassetid://9126738032",
"rbxassetid://9126737943",
"rbxassetid://9126737853"
},
["Metal_Grate"] = {
"rbxassetid://9126737728",
"rbxassetid://9126736554",
"rbxassetid://9126737597",
"rbxassetid://9126737668",
"rbxassetid://9126737506",
"rbxassetid://9126737412",
"rbxassetid://9126737315",
"rbxassetid://9126737212",
"rbxassetid://9126736947",
"rbxassetid://9126737081",
"rbxassetid://9126736863",
"rbxassetid://9126736806",
"rbxassetid://9126736642",
"rbxassetid://9126736721"
},
["Metal_Solid"] = {
"rbxassetid://9126736470",
"rbxassetid://9126734921",
"rbxassetid://9126736274",
"rbxassetid://9126736354",
"rbxassetid://9126736186",
"rbxassetid://9126736049",
"rbxassetid://9126735913",
"rbxassetid://9126735734",
"rbxassetid://9126735546",
"rbxassetid://9126735474",
"rbxassetid://9126735265",
"rbxassetid://9126735374",
"rbxassetid://9126735161",
"rbxassetid://9126735028",
"rbxassetid://9126735089",
"rbxassetid://9126734972"
},
["Mud"] = {
"rbxassetid://9126734842",
"rbxassetid://9126734314",
"rbxassetid://9126734778",
"rbxassetid://9126734710",
"rbxassetid://9126734613",
"rbxassetid://9126734499",
"rbxassetid://9126734365",
"rbxassetid://9126734432",
"rbxassetid://9126734244"
},
["Rubber"] = {
"rbxassetid://9126734172",
"rbxassetid://9126733896",
"rbxassetid://9126734560",
"rbxassetid://9126734010",
"rbxassetid://9126733324",
"rbxassetid://9126733766",
"rbxassetid://9126733614",
"rbxassetid://9126733493"
},
["Sand"] = {
"rbxassetid://9126733118",
"rbxassetid://9126733408",
"rbxassetid://9126733225",
"rbxassetid://9126732675",
"rbxassetid://9126732571",
"rbxassetid://9126732962",
"rbxassetid://9126732962",
"rbxassetid://9126732457",
"rbxassetid://9126732862",
"rbxassetid://9126732776",
"rbxassetid://9126732334",
"rbxassetid://9126732253"
},
["Snow"] = {
"rbxassetid://9126732128",
"rbxassetid://9126731099",
"rbxassetid://9126732016",
"rbxassetid://9126731951",
"rbxassetid://9126731877",
"rbxassetid://9126731632",
"rbxassetid://9126731493",
"rbxassetid://9126731343",
"rbxassetid://9126731790",
"rbxassetid://9126731243",
"rbxassetid://9126731169",
"rbxassetid://9126730861"
},
["Tile"] = {
"rbxassetid://9126730713",
"rbxassetid://9126730782",
"rbxassetid://9126731037",
"rbxassetid://9126730980",
"rbxassetid://9126730651",
"rbxassetid://9126730563",
"rbxassetid://9126730279",
"rbxassetid://9126730403",
"rbxassetid://9126730056",
"rbxassetid://9126730172",
"rbxassetid://9126729836",
"rbxassetid://9126730472",
"rbxassetid://9126729938",
"rbxassetid://9126729706"
},
["Wood"] = {
"rbxassetid://9126931624",
"rbxassetid://9126931515",
"rbxassetid://9126931417",
"rbxassetid://9126931322",
"rbxassetid://9126931699",
"rbxassetid://9126931235",
"rbxassetid://9126931169",
"rbxassetid://9126931026",
"rbxassetid://9126930953",
"rbxassetid://9126930885",
"rbxassetid://9126930789",
"rbxassetid://9126930647",
"rbxassetid://9126930516",
"rbxassetid://9126930598",
"rbxassetid://9126930718"
}
}
main.MaterialMap = {
[Enum.Material.Slate] = main.SoundIds.Concrete,
[Enum.Material.Concrete] = main.SoundIds.Concrete,
[Enum.Material.Brick] = main.SoundIds.Concrete,
[Enum.Material.Cobblestone] = main.SoundIds.Concrete,
[Enum.Material.Sandstone] = main.SoundIds.Gravel,
[Enum.Material.Rock] = main.SoundIds.Gravel,
[Enum.Material.Basalt] = main.SoundIds.Gravel,
[Enum.Material.CrackedLava] = main.SoundIds.Concrete,
[Enum.Material.Asphalt] = main.SoundIds.Concrete,
[Enum.Material.Limestone] = main.SoundIds.Gravel,
[Enum.Material.Pavement] = main.SoundIds.Concrete,
[Enum.Material.Plastic] = main.SoundIds.Tile,
[Enum.Material.Marble] = main.SoundIds.Tile,
[Enum.Material.Neon] = main.SoundIds.Tile,
[Enum.Material.Granite] = main.SoundIds.Tile,
[Enum.Material.Wood] = main.SoundIds.Wood,
[Enum.Material.WoodPlanks] = main.SoundIds.Wood,
[Enum.Material.CorrodedMetal] = main.SoundIds.Metal_Solid,
[Enum.Material.DiamondPlate] = main.SoundIds.Metal_Solid,
[Enum.Material.Metal] = main.SoundIds.Metal_Solid,
[Enum.Material.Foil] = main.SoundIds.Metal_Grate,
[Enum.Material.Ground] = main.SoundIds.Dirt,
[Enum.Material.Grass] = main.SoundIds.Grass,
[Enum.Material.LeafyGrass] = main.SoundIds.Grass,
[Enum.Material.Fabric] = main.SoundIds.Carpet,
[Enum.Material.Pebble] = main.SoundIds.Gravel,
[Enum.Material.Snow] = main.SoundIds.Snow,
[Enum.Material.Sand] = main.SoundIds.Sand,
[Enum.Material.Salt] = main.SoundIds.Sand,
[Enum.Material.Ice] = main.SoundIds.Gravel,
[Enum.Material.Glacier] = main.SoundIds.Gravel,
[Enum.Material.Glass] = main.SoundIds.Glass,
[Enum.Material.SmoothPlastic] = main.SoundIds.Rubber,
[Enum.Material.ForceField] = main.SoundIds.Rubber,
[Enum.Material.Mud] = main.SoundIds.Mud
}
-- This function produces a folder under a specified parent.
-- "soundProperties" is a table determining what the default properties of these audios will be.
function main:CreateSoundGroup(parent:Instance?, name:string?, soundProperties:{}?, isFolder:boolean?) : SoundGroup|Folder
if not parent then warn("Parent not specified, Footstep folder parented to workspace") end
isFolder = isFolder or false
soundProperties = soundProperties or {}
parent = parent or workspace
-- Create folder
local SoundGroup = nil
if not isFolder then
SoundGroup = Instance.new("SoundGroup"); SoundGroup.Volume = 1; SoundGroup.Name = name or "Footsteps"
else
SoundGroup = Instance.new("Folder"); SoundGroup.Name = name or "Footsteps"
end
local index = 0
for soundMaterial,soundList in pairs(main.SoundIds) do
index = 0
local sectionGroup = nil
if not isFolder then
sectionGroup = Instance.new("SoundGroup"); sectionGroup.Volume = 1; sectionGroup.Name = soundMaterial
else
sectionGroup = Instance.new("Folder"); sectionGroup.Name = soundMaterial
end
for _,soundId in pairs(soundList) do
index += 1 -- Increment index
local soundEffect = Instance.new("Sound")
soundEffect.Name = string.format("%s_%02i",soundMaterial:lower(),index)
-- Set optional sound group
if not isFolder then
soundEffect.SoundGroup = sectionGroup
end
for property,value in pairs(soundProperties) do
soundEffect[property] = value
end
soundEffect.SoundId = soundId
soundEffect.Parent = sectionGroup
end
sectionGroup.Parent = SoundGroup
end
SoundGroup.Parent = parent
return SoundGroup
end
-- This function returns a table from the MaterialMap given the material.
function main:GetTableFromMaterial(EnumItem : Enum.Material|string) : {}
if typeof(EnumItem) == "string" then -- CONVERSION
EnumItem = Enum.Material[EnumItem]
end
return main.MaterialMap[EnumItem]
end
local lastsoundid = nil
function main:GetRandomSound(SoundTable : {}) : string
if SoundTable and #SoundTable > 0 then
local newsoundid
repeat
newsoundid = math.random(#SoundTable)
until newsoundid ~= lastsoundid
lastsoundid = newsoundid
return SoundTable[newsoundid]
else
repeat wait(0.1) until SoundTable and #SoundTable > 0
local newsoundid
repeat
newsoundid = math.random(#SoundTable)
until newsoundid ~= lastsoundid
lastsoundid = newsoundid
return SoundTable[newsoundid]
end
end
return main
Sprinting Script
I’m aware of the problems attaching an event to a hotkey could cause and I will work to optimize it later.
local userinput = game:GetService("UserInputService")
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local event = game.ReplicatedStorage:WaitForChild("running")
local event2 = game.ReplicatedStorage:WaitForChild("notrunning")
local sprintSpeed = 20
local slowSpeed = 7
local noSpeed = 0
local player = Players.LocalPlayer
local slow = true
local function tweenwalkspeed(targetSpeed, duration)
local character = player.Character
if not character then return end
local humanoid = character:FindFirstChild("Humanoid")
if not humanoid then return end
local tweenInfo = TweenInfo.new(duration, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
local goal = { WalkSpeed = targetSpeed }
local tween = TweenService:Create(humanoid, tweenInfo, goal)
tween:Play()
end
local function beginsprint(input, gameProcessed)
if not gameProcessed then
if input.UserInputType == Enum.UserInputType.Keyboard then
local keycode = input.KeyCode
if keycode == Enum.KeyCode.LeftShift then
event:FireServer()
tweenwalkspeed(sprintSpeed, 2)
end
end
end
end
local function endsprint(input, gameProcessed)
if not gameProcessed then
if input.UserInputType == Enum.UserInputType.Keyboard then
local keycode = input.KeyCode
if keycode == Enum.KeyCode.LeftShift then
if slow == true then
event2:FireServer()
tweenwalkspeed(slowSpeed, 2)
else
event:FireServer()
tweenwalkspeed(player.Character.Humanoid.WalkSpeed, 0.5)
end
end
end
end
end
if player.Character and player.Character:FindFirstChild("Humanoid") then
if player.Character.Humanoid.WalkSpeed == noSpeed then
repeat wait() until player.Character.Humanoid.WalkSpeed > noSpeed
userinput.InputBegan:Connect(beginsprint)
userinput.InputEnded:Connect(endsprint)
elseif player.Character.Humanoid.WalkSpeed > noSpeed then
userinput.InputBegan:Connect(beginsprint)
userinput.InputEnded:Connect(endsprint)
end
end