Skip to main content

soundUtil

A utility module for working with sounds.

soundUtil.registerSoundHeartbeatCallback(someSound, function(sound, deltaTime)
	if not sound.Playing then
		sound.Volume = 0
		sound:Play()
	end

	-- Lerp the volume to 1:
	sound.Volume += (1 - sound.Volume) * deltaTime * 2
end)

soundUtil.registerSoundCleanupCallback(someSound, function(sound, deltaTime)
	-- Lerp the volume to 0:
	sound.Volume += (0 - sound.Volume) * deltaTime * 2

	if sound.Volume < 1e-3 then
		-- We've fully lerped the volume to 0, let's stop the sound and finish
		-- up cleanup!
		sound:Stop()
		return false
	end

	return true
end)

soundUtil.playSound(someSound)

Functions

playSoundCloneAndCleanup

soundUtil.playSoundCloneAndCleanup(soundSound) → Sound

Plays a cloned version of the sound and destroys it when it has ended.

stopAll

soundUtil.stopAll() → ()

Stops all playing registered ounds via soundUtil.stopSound.

playSound

soundUtil.playSound(soundSound) → ()

Plays the given sound instance, if the sound instance has a heartbeat callback registered for it, then the sound instance will not be played by this method.

soundUtil.registerSoundHeartbeatCallback(someSound, function(sound, deltaTime)
	if not sound.Playing then
		sound.Volume = 0
		sound:Play()
	end
	-- Lerp the volume to 1:
	sound.Volume += (2 - sound.Volume) * deltaTime
end)

soundUtil.playSound(someSound)

playSoundIn3DOnce

soundUtil.playSoundIn3DOnce(
soundSound,
positionOrBasePartVector3 | BasePart
) → ()

Plays the given sound at the specified given 3D position or instance. If the sound instance has a heartbeat callback registered for it, then the sound instance will not be played by this method. Once the sound has ended, it'll be destroyed.

-- Usecase: lightning bolt sounds!
local lightningBoltSound = ...
local generatedLightningBoltModel = ...
soundUtil.playSound3D(lightningBoltSound, generatedLightningBoltModel.PrimaryPart) 
NOTE

Ideally you should always generally pass in a cloned version of the sound instance so you can reuse it.

-- BAD:
soundUtil.playSoundIn3DOnce(someStorage.someRandomSound, workspace.Baseplate)
soundUtil.playSoundIn3DOnce(someStorage.someRandomSound, workspace.ZombiePart) -- PANIC: `someStorage.someRandomSound` does not exist anymore!

-- GOOD:
oundUtil.playSoundIn3DOnce(someStorage.someRandomSound:Clone(), workspace.Baseplate)
soundUtil.playSoundIn3DOnce(someStorage.someRandomSound:Clone(), workspace.ZombiePart) 

stopSound

soundUtil.stopSound(soundSound) → ()

Stops the given sound instance.

registerSoundCleanupCallback

soundUtil.registerSoundCleanupCallback(
soundSound,
cleanupPredicate((
soundSound,
deltaTimenumber
) → boolean)?
) → ()

Registers the given callback as a cleanup callback for the given sound instance. The callback will be called every Heartbeat when the sound is stopped via soundUtil.stopSound, for as long as it doesn't return false (to complete cleanup).

local someSound = ...
soundUtil.registerSoundCleanupCallback(someSound, function(someSound, deltaTime)
	-- Lerp the volume to 0:
	someSound.Volume += (0 - someSound.Volume) * deltaTime
	
	if someSound.Volume < 1e-3 then
		-- We've fully lerped the volume to 0, let's stop the sound and finish
		-- up cleanup!
		someSound:Stop()
		return false 
	end

	return true 
end)

soundUtil.playSound(someSound)
task.wait(2)
someSoundUtil.stopSound(someSound)
NOTE

The cleanupPredicate will no longer run if the same sound instance is suddenly played again.

registerSoundHeartbeatCallback

soundUtil.registerSoundHeartbeatCallback(
soundSound,
heartbeatCallback(
soundSound,
deltaTimenumber
) → ()
) → ()

Registers the given callback as a heartbeat callback for the given sound instance. It will be called every Heartbeat for as long as the sound is playing (sound will be in "playing" state if it has been played by soundUtil.playSound and has not finished / stopped yet).

soundUtil.registerSoundHeartbeatCallback(someSound, function(sound, deltaTime)
	if not sound.Playing then
		sound.Volume = 0
		sound:Play()
	end
	-- Lerp the volume to 2:
	sound.Volume += (2 - sound.Volume) * deltaTime
end)

soundUtil.playSound(someSound)
Show raw api
{
    "functions": [
        {
            "name": "playSoundCloneAndCleanup",
            "desc": "Plays a cloned version of the sound and destroys it when it has ended.",
            "params": [
                {
                    "name": "sound",
                    "desc": "",
                    "lua_type": "Sound"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Sound\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 50,
                "path": "src/soundUtil/init.luau"
            }
        },
        {
            "name": "stopAll",
            "desc": "Stops all playing registered ounds via [soundUtil.stopSound].",
            "params": [],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 66,
                "path": "src/soundUtil/init.luau"
            }
        },
        {
            "name": "playSound",
            "desc": "Plays the given sound instance, if the sound instance has a heartbeat callback registered for it, then\nthe sound instance will not be played by this method.\n\n```lua\nsoundUtil.registerSoundHeartbeatCallback(someSound, function(sound, deltaTime)\n\tif not sound.Playing then\n\t\tsound.Volume = 0\n\t\tsound:Play()\n\tend\n\t-- Lerp the volume to 1:\n\tsound.Volume += (2 - sound.Volume) * deltaTime\nend)\n\nsoundUtil.playSound(someSound)\n```",
            "params": [
                {
                    "name": "sound",
                    "desc": "",
                    "lua_type": "Sound"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 90,
                "path": "src/soundUtil/init.luau"
            }
        },
        {
            "name": "playSoundIn3DOnce",
            "desc": "Plays the given sound at the specified given 3D position or instance. If the sound instance has a heartbeat callback registered for it, \nthen the sound instance will not be played by this method. Once the sound has ended, it'll be destroyed.\n\n```lua\n-- Usecase: lightning bolt sounds!\nlocal lightningBoltSound = ...\nlocal generatedLightningBoltModel = ...\nsoundUtil.playSound3D(lightningBoltSound, generatedLightningBoltModel.PrimaryPart) \n```\n\n:::note\nIdeally you should always generally pass in a cloned version of the sound instance so you can\nreuse it.\n\n```lua\n-- BAD:\nsoundUtil.playSoundIn3DOnce(someStorage.someRandomSound, workspace.Baseplate)\nsoundUtil.playSoundIn3DOnce(someStorage.someRandomSound, workspace.ZombiePart) -- PANIC: `someStorage.someRandomSound` does not exist anymore!\n\n-- GOOD:\noundUtil.playSoundIn3DOnce(someStorage.someRandomSound:Clone(), workspace.Baseplate)\nsoundUtil.playSoundIn3DOnce(someStorage.someRandomSound:Clone(), workspace.ZombiePart) \n```\n:::",
            "params": [
                {
                    "name": "sound",
                    "desc": "",
                    "lua_type": "Sound"
                },
                {
                    "name": "positionOrBasePart",
                    "desc": "",
                    "lua_type": "Vector3 | BasePart"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 126,
                "path": "src/soundUtil/init.luau"
            }
        },
        {
            "name": "stopSound",
            "desc": "Stops the given sound instance. ",
            "params": [
                {
                    "name": "sound",
                    "desc": "",
                    "lua_type": "Sound"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 176,
                "path": "src/soundUtil/init.luau"
            }
        },
        {
            "name": "registerSoundCleanupCallback",
            "desc": "Registers the given callback as a cleanup callback for the given sound instance. The callback will be\ncalled every [Heartbeat](https://create.roblox.com/docs/reference/engine/classes/RunService#Heartbeat) when the \nsound is stopped via [soundUtil.stopSound], for as long as it doesn't return `false` (to complete cleanup). \n\n```lua\nlocal someSound = ...\nsoundUtil.registerSoundCleanupCallback(someSound, function(someSound, deltaTime)\n\t-- Lerp the volume to 0:\n\tsomeSound.Volume += (0 - someSound.Volume) * deltaTime\n\t\n\tif someSound.Volume < 1e-3 then\n\t\t-- We've fully lerped the volume to 0, let's stop the sound and finish\n\t\t-- up cleanup!\n\t\tsomeSound:Stop()\n\t\treturn false \n\tend\n\n\treturn true \nend)\n\nsoundUtil.playSound(someSound)\ntask.wait(2)\nsomeSoundUtil.stopSound(someSound)\n```\n\n:::note\nThe `cleanupPredicate` will no longer run if the same sound instance is suddenly played again.\n:::\t",
            "params": [
                {
                    "name": "sound",
                    "desc": "",
                    "lua_type": "Sound"
                },
                {
                    "name": "cleanupPredicate",
                    "desc": "",
                    "lua_type": "((\n\t\tsound: Sound,\n\t\tdeltaTime: number\n\t) -> boolean)?\n"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 218,
                "path": "src/soundUtil/init.luau"
            }
        },
        {
            "name": "registerSoundHeartbeatCallback",
            "desc": "Registers the given callback as a heartbeat callback for the given sound instance. It\nwill be called every [Heartbeat](https://create.roblox.com/docs/reference/engine/classes/RunService#Heartbeat)\nfor as long as the sound is playing (sound will be in \"playing\" state if it has been played by [soundUtil.playSound]\nand has not finished / stopped yet).\n\n```lua\nsoundUtil.registerSoundHeartbeatCallback(someSound, function(sound, deltaTime)\n\tif not sound.Playing then\n\t\tsound.Volume = 0\n\t\tsound:Play()\n\tend\n\t-- Lerp the volume to 2:\n\tsound.Volume += (2 - sound.Volume) * deltaTime\nend)\n\nsoundUtil.playSound(someSound)\n```",
            "params": [
                {
                    "name": "sound",
                    "desc": "",
                    "lua_type": "Sound"
                },
                {
                    "name": "heartbeatCallback",
                    "desc": "",
                    "lua_type": "(sound: Sound, deltaTime: number) -> ()\n"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 248,
                "path": "src/soundUtil/init.luau"
            }
        }
    ],
    "properties": [],
    "types": [],
    "name": "soundUtil",
    "desc": "A utility module for working with sounds.\n\n```lua\nsoundUtil.registerSoundHeartbeatCallback(someSound, function(sound, deltaTime)\n\tif not sound.Playing then\n\t\tsound.Volume = 0\n\t\tsound:Play()\n\tend\n\n\t-- Lerp the volume to 1:\n\tsound.Volume += (1 - sound.Volume) * deltaTime * 2\nend)\n\nsoundUtil.registerSoundCleanupCallback(someSound, function(sound, deltaTime)\n\t-- Lerp the volume to 0:\n\tsound.Volume += (0 - sound.Volume) * deltaTime * 2\n\n\tif sound.Volume < 1e-3 then\n\t\t-- We've fully lerped the volume to 0, let's stop the sound and finish\n\t\t-- up cleanup!\n\t\tsound:Stop()\n\t\treturn false\n\tend\n\n\treturn true\nend)\n\nsoundUtil.playSound(someSound)\n```",
    "source": {
        "line": 34,
        "path": "src/soundUtil/init.luau"
    }
}