Trying to achieve a proficient Footsteps System that aims for Material Based perception and Global Footstep Sounds.
I already have a System in use atm, however I found it was beneficial in most ways.
[1] What to achieve - Footstep Sounds that are heard by other Clients and Footsteps depict on the Material region.
Figure 1 > I want to add Sound storage instead of using Module
Full Script > StarterPlayer > StarterCharacterScripts
Server Side >
-- Storages
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Players
local Players = game:GetService("Players")
local Player = Players:GetPlayerFromCharacter(script.Parent)
local Character = Player.Character or Player.CharacterAdded:wait()
local Humanoid = Character.Humanoid
-- Sound Variables
local ID
local Volume
local PlaybackSpeed
-- Material Variables
local FloorMaterial
local Material
-- Remote Instance
local UpdateWalkspeedRemote = game:GetService("ReplicatedStorage"):FindFirstChild("UpdateWalkspeed")
if UpdateWalkspeedRemote == nil then
UpdateWalkspeedRemote = Instance.new("RemoteEvent", game.ReplicatedStorage)
UpdateWalkspeedRemote.Name = "UpdateWalkspeed"
end
-- Sound Instance
local CurrentSound = Instance.new("Sound", Character.HumanoidRootPart)
CurrentSound.Name = "CurrentSound"
CurrentSound.RollOffMode = Enum.RollOffMode.Linear
CurrentSound.RollOffMinDistance = 10
CurrentSound.RollOffMaxDistance = 50
-- Fetch the ID List
local FootstepsModule = require(script:FindFirstChildWhichIsA("ModuleScript"))
-- Collect the current Floor Material
local function GetFloorMaterial()
FloorMaterial = Humanoid.FloorMaterial
Material = string.split(tostring(FloorMaterial), "Enum.Material.") [2]
return Material
end
-- Collect the Sound List
local function GetSoundProperties()
for Name, Data in pairs(FootstepsModule) do
if Name == Material then
ID = Data.ID
Volume = Data.Volume
PlaybackSpeed = (Humanoid.WalkSpeed / 10) * Data.Speed
break
end
end
end
-- Update the Sound Data
local function SoundUpdate()
CurrentSound.SoundId = ID
CurrentSound.Volume = Volume
CurrentSound.PlaybackSpeed = PlaybackSpeed
end
UpdateWalkspeedRemote.OnServerEvent:Connect(function(Player, Walkspeed)
Player.Character.Humanoid.WalkSpeed = Walkspeed
end)
-- Moving Control (check Player isn't Climbing)
Humanoid.Running:Connect(function(Speed)
if Humanoid.MoveDirection.Magnitude > 0 and Speed > 0 and Humanoid:GetState() ~= Enum.HumanoidStateType.Climbing then
GetSoundProperties()
SoundUpdate()
CurrentSound.Playing = true
CurrentSound.Looped = true
else
CurrentSound:Stop()
end
end)
-- Solution to 'humanoid:GetPropertyChangedSignal("FloorMaterial")' not working as expected on the Server.
local ServerFix = coroutine.create(function()
while task.wait() do
if Humanoid.FloorMaterial ~= FloorMaterial then
GetFloorMaterial()
GetSoundProperties()
SoundUpdate()
end
end
end)
if coroutine.status(ServerFix) == "suspended" then
coroutine.resume(ServerFix)
end
Client Side
-- Services
local SoundService = game:GetService("SoundService")
-- Storages
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Players
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:wait()
local Humanoid = Character.Humanoid
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
-- Sound Variables
local ID
local Volume
local PlaybackSpeed
-- Material Variables
local FloorMaterial
local Material
-- Collect the Global Audio
local ServerSound = HumanoidRootPart:WaitForChild("CurrentSound")
-- Remote Instance
local UpdateWalkspeedRemote = ReplicatedStorage:WaitForChild("UpdateWalkspeed")
-- Sound Instance
local CurrentSound = Instance.new("Sound", SoundService)
CurrentSound.Name = "CurrentSound"
-- fetch the ID List
local FootstepsModule = require(script.Parent:FindFirstChildWhichIsA("ModuleScript"))
-- Remove Default Footstep Sound
Character.HumanoidRootPart:FindFirstChild("Running"):Destroy()
-- Collect the current Floor Material
local function GetFloorMaterial()
FloorMaterial = Humanoid.FloorMaterial
Material = string.split(tostring(FloorMaterial), "Enum.Material.") [2]
return Material
end
-- Collect the Sound List
local function GetSoundProperties()
for Name, Data in pairs(FootstepsModule) do
if Name == Material then
ID = Data.ID
Volume = Data.Volume
PlaybackSpeed = (Humanoid.WalkSpeed / 10) * Data.Speed
break
end
end
end
-- Update the Sound Data
local function SoundUpdate()
CurrentSound.SoundId = ID
CurrentSound.Volume = Volume
CurrentSound.PlaybackSpeed = PlaybackSpeed
end
-- Initial Data for Client
GetFloorMaterial()
GetSoundProperties()
SoundUpdate()
-- Update < Floor Material & > Material
Humanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
GetFloorMaterial()
GetSoundProperties()
SoundUpdate()
if Humanoid.MoveDirection.Magnitude > 0 then
CurrentSound.Playing = true
end
end)
-- Server replicates the WalkSpeed has changed
Humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(function()
UpdateWalkspeedRemote:FireServer(Humanoid.WalkSpeed)
end)
-- Moving Control (check Player isn't Climbing)
Humanoid.Running:Connect(function(Speed)
if Humanoid.MoveDirection.Magnitude > 0 and Speed > 0 and Humanoid:GetState() ~= Enum.HumanoidStateType.Climbing then
GetSoundProperties()
SoundUpdate()
CurrentSound.Playing = true
CurrentSound.Looped = true
else
CurrentSound:Stop()
end
end)
ServerSound.Changed:Connect(function(Volume)
if Volume ~= 0 then
ServerSound.Volume = 0
end
end)
-- Small Big fix where the Sound would start Playing after the Player joined
Player.CharacterAdded:Connect(function()
task.wait(1)
if CurrentSound.IsPlaying then
CurrentSound:Stop()
end
end)
and the Module that I want to replace with Figure 1.
Module
local FootstepsModule = {
Air = {ID = "rbxassetid://329997777", Volume = 0, Speed = 0},
Asphalt = {ID = "rbxassetid://277067660", Volume = 0.55, Speed = 1.00},
Basalt = {ID = "rbxassetid://3190903775", Volume = 0.55, Speed = 1.00},
Brick = {ID = "rbxassetid://178190837", Volume = 0.55, Speed = 1.00},
Cobblestone = {ID = "rbxassetid://178190837", Volume = 0.55, Speed = 1.00},
Concrete = {ID = "rbxassetid://277067660", Volume = 0.55, Speed = 1.00},
CorrodedMetal = {ID = "rbxassetid://177940974", Volume = 0.55, Speed = 1.00},
CrackedLava = {ID = "rbxassetid://3190903775", Volume = 0.55, Speed = 1.00},
DiamondPlate = {ID = "rbxassetid://177940974", Volume = 0.55, Speed = 1.00},
Fabric = {ID = "rbxassetid://133705377", Volume = 0.55, Speed = 1.00},
Foil = {ID = "rbxassetid://178190837", Volume = 0.55, Speed = 1.00},
Forcefield = {ID = "rbxassetid://329997777", Volume = 0.55, Speed = 1.00},
Glass = {ID = "rbxassetid://178190837", Volume = 0.55, Speed = 1.00},
Granite = {ID = "rbxassetid://178054124", Volume = 0.55, Speed = 1.00},
Grass = {ID = "rbxassetid://177940963", Volume = 0.55, Speed = 1.00},
Glacier = {ID = "rbxassetid://7047108275", Volume = 0.55, Speed = 1.00},
Ground = {ID = "rbxassetid://9064714296", Volume = 0.55, Speed = 1.00},
Ice = {ID = "rbxassetid://7047108275", Volume = 0.55, Speed = 1.00},
Limestone = {ID = "rbxassetid://9083846829", Volume = 0.55, Speed = 1.00},
LeafyGrass = {ID = "rbxassetid://3098847639", Volume = 0.55, Speed = 1.00},
Marble = {ID = "rbxassetid://178190837", Volume = 0.55, Speed = 1.00},
Metal = {ID = "rbxassetid://177940974", Volume = 0.55, Speed = 1.00},
Mud = {ID = "rbxassetid://6441160246", Volume = 0.55, Speed = 1.00},
Neon = {ID = "rbxassetid://177940974", Volume = 0.55, Speed = 1.00},
Pebble = {ID = "rbxassetid://178190837", Volume = 0.55, Speed = 1.00},
Plastic = {ID = "rbxassetid://4416041299", Volume = 0.55, Speed = 1.40},
Pavement = {ID = "rbxassetid://277067660", Volume = 0.55, Speed = 1.00},
Rock = {ID = "rbxassetid://178190837", Volume = 0.55, Speed = 1.00},
Sand = {ID = "rbxassetid://9083846829", Volume = 0.55, Speed = 1.00},
Slate = {ID = "rbxassetid://178054124", Volume = 0.55, Speed = 1.00},
Snow = {ID = "rbxassetid://8453425942", Volume = 0.55, Speed = 1.00},
Salt = {ID = "rbxassetid://9083846829", Volume = 0.55, Speed = 1.00},
Sandstone = {ID = "rbxassetid://3190903775", Volume = 0.55, Speed = 0.75},
SmoothPlastic = {ID = "rbxassetid://178190837", Volume = 0.55, Speed = 1.00},
Wood = {ID = "rbxassetid://178190837", Volume = 0.55, Speed = 1.00},
WoodPlanks = {ID = "rbxassetid://211987063", Volume = 0.55, Speed = 1.00}
}
return FootstepsModule