Is it possible to make custom sounds for terrain?

Recently I’ve found a script that changes sounds for parts that have different materials.
I was wondering if it’s possible to do the same with Terrain.
Please let me know how to do it :wink:

7 Likes

Some terrain types (eg grass, sand) will report the material they are standing on as being the Enum.Material equivalent, others will report it as air/none.

In other words- it should work automatically with Terrain.

Well, for me it doesn’t work, I don’t really know why.

Can you send the script here?

Materials = script.Parent.Materials
Color = script.Parent.Colors

while true do

local ray = Ray.new(
script.Parent.Position,
Vector3.new(0, -10, 0)
)
local part, endPoint = Workspace:FindPartOnRay(ray, script.Parent.Parent)

if part then

if part.Material == Enum.Material.Grass then
Color.Value = BrickColor.new(part.Color)
Materials.Value = “Grass”

elseif part.Name == “Terrain” then
Color.Value = BrickColor.new(“Camo”)
Materials.Value = “Grass”

elseif part.Name == “Water” then
Color.Value = BrickColor.new(part.Color)
Materials.Value = “Water”

elseif part.Material == Enum.Material.Ice then
Color.Value = BrickColor.new(“Ghost grey”)
Materials.Value = “Ice”

elseif part.Material == Enum.Material.Wood then
Color.Value = BrickColor.new(part.Color)
Materials.Value = “Wood”

elseif part.Material == Enum.Material.Plastic then
Color.Value = BrickColor.new(part.Color)
Materials.Value = “Plastic”

elseif part.Material == Enum.Material.Foil then
Color.Value = BrickColor.new(part.Color)
Materials.Value = “Foil”

elseif part.Material == Enum.Material.DiamondPlate then
Color.Value = BrickColor.new(part.Color)
Materials.Value = “DiamondPlate”

elseif part.Material == Enum.Material.CorrodedMetal then
Color.Value = BrickColor.new(part.Color)
Materials.Value = “CMetal”

elseif part.Material == Enum.Material.Concrete then
Color.Value = BrickColor.new(part.Color)
Materials.Value = “Concrete”

elseif part.Material == Enum.Material.Slate then
Color.Value = BrickColor.new(part.Color)
Materials.Value = “Slate”

elseif part.Material == Enum.Material.Sand then
Color.Value = BrickColor.new(part.Color)
Materials.Value = “Sand”

elseif part.Material == Enum.Material.Marble then
Color.Value = BrickColor.new(part.Color)
Materials.Value = “Marble”

elseif part.Material == Enum.Material.Granite then
Color.Value = BrickColor.new(part.Color)
Materials.Value = “Granite”

elseif part.Material == Enum.Material.Brick then
Color.Value = BrickColor.new(part.Color)
Materials.Value = “Brick”

end

else
Materials.Value = “None”
end

wait()
end

1 Like

Please use codeblocks

This is code
-- hi

What i understand from this is that you’r trying to change the sound depending on the material the player is standing on?

The script is meant to change sounds for parts, I need it to change souns for terrain

Humanoid has a property called FloorMaterial which works with Terrain.

Put this script in StarterCharacterScripts

--[[
	Author: @FullMetalEdward45221
	
	This script will Change your Running Sound Id Depending on the material you're Standing
	Hey would be nice if you give me some Credit, please Provide the link of
	this model in your Game so more people can use this ;)
	
	Script Should be at StarterCharacterScripts
	and The Sound Group should be at SoundService
--]]
local Character = script.Parent
local Head = Character:WaitForChild("Head")
local RunningSound = Head:WaitForChild("Running")
local FootstepsSoundGroup = game:GetService("SoundService"):WaitForChild("Footsteps")
local Humanoid = Character:WaitForChild("Humanoid")

Humanoid.Changed:Connect(function(property)
	if property == "FloorMaterial" then			
		if FootstepsSoundGroup:FindFirstChild(Humanoid.FloorMaterial) == nil then
			RunningSound.SoundId = FootstepsSoundGroup:WaitForChild("nil Sound").SoundId
			RunningSound.PlaybackSpeed = FootstepsSoundGroup:WaitForChild("nil Sound").PlaybackSpeed
			RunningSound.Volume = FootstepsSoundGroup:WaitForChild("nil Sound").Volume
		else
			RunningSound.SoundId = FootstepsSoundGroup:WaitForChild(Humanoid.FloorMaterial).SoundId 
			RunningSound.PlaybackSpeed = FootstepsSoundGroup:WaitForChild(Humanoid.FloorMaterial).PlaybackSpeed
			RunningSound.Volume = FootstepsSoundGroup:WaitForChild(Humanoid.FloorMaterial).Volume
		end
	end
end)

And put this SoundGroup in SoundService
Footsteps.rbxm (1.5 KB)

17 Likes

ugh, rbxm won’t open for me. It’s always corrupted for some reason…

You need to drag & drop the file into studio. You can’t open rbxm and rbxmx files as they’re models.

That’s what I am doing actually.

I’ve uploaded this as a cloud model for you:
https://www.roblox.com/library/4061297577/Footsteps

I think you can also use GetPropertyChangedSignal followed by if statements to check the materials.

Make sure to correct me if i am wrong :blush:.

1 Like

Yes, you can- and that is a much better way of doing it.

1 Like

Just saying, Terrain is a BasePart but the instance itself doesn’t have a valid material or rather one that would actually work for your scenario. Your original code with the downcast would’ve still worked if you addressed the material return.

Raycast returns a tuple and the material of the object it hit is included. You could skip FloorMaterial, but I find that’s a better solution since it handles the downcast internally to get the material.

while true do
    local ray = Ray.new(script.Parent.Position, Vector3.new(0, -6, 0))
    local part, endPoint, _, material = workspace:FindPartOnRay(ray, script.Parent.Parent)
    print(material)
    wait(0.2)
end
2 Likes

This doesn’t work. Probably outdated code.

Well, it was created in 2019, after all. This will work with the legacy sound system but not the current one that superseded it where character sounds, both your own and those of others, are handled locally. Regular scripts can’t interface with character sounds and instead need to have the client do that.

Hypothetically could still work if you make a few changes:

  • Use a LocalScript instead.
  • Modify this code to work across other characters’ humanoids, not just your own.

Obviously these suggestions are naïve and you should look into a solution that fits the current sound handler script, RbxCharacterSounds. Can be forked by starting a new session and fetching it from StarterPlayerScripts. Sound structure’s mostly the same, there’s just no network footprint anymore.

This still works but, Running Sound is now in HumanoidRootPart so you have to set RunningSound to Character.HumanoidRootPart:WaitForChild(“Running”).

3 Likes