Для одинаковой фоновой музыки во всей игре поместите Sound в SoundService. Задайте SoundId, включите Looped, начните с Volume около 0.25 и запустите Play после загрузки аудио.
Музыка из SoundService не привязана к точке в мире, поэтому игрок слышит её одинаково в любом месте. Для костра, машины или водопада нужен позиционный звук внутри 3D-объекта. Не смешивайте эти задачи, иначе громкость будет вести себя неожиданно.
Берём аудио из Creator Store или свой допущенный ассет.
SoundId хранит адрес, Looped повторяет, Volume ограничивает уровень.
Ждём Loaded, вызываем Play и не создаём вторую копию.
Где хранить фоновую музыку
Создайте Sound в SoundService и назовите BackgroundMusic. В SoundId вставляется rbxassetid:// и числовой ID. Если аудио не принадлежит вам и не разрешено для experience, пустая кнопка Play его не исправит. Первым делом сверяйте права и Output.
| Сценарий | Где Sound | Что слышно |
|---|---|---|
| Фоновая музыка | SoundService | Одинаково везде |
| Костёр в мире | Part или Attachment | Громче рядом |
| Звук кнопки | SoundService или UI-код | Одноразово |
| Музыка локации | Отдельная группа | Меняется по зоне |
После этого шага у каждой части есть одна роль. Интерфейс собирает действие, логика меняет состояние, а вывод показывает признак успеха. Это проще отлаживать, чем один большой обработчик.

Один Sound и один путь загрузки. Volume можно менять во время игры
Создаём Sound и запускаем его кодом
Для фона достаточно одного Sound. Скрипт сначала ищет его, устанавливает безопасную громкость и цикл. Если IsLoaded ещё false, мы ждём событие Loaded с тайм-аутом, чтобы не зависнуть на недоступном ассете.
local SoundService = game:GetService("SoundService")
local ContentProvider = game:GetService("ContentProvider")
local music = SoundService:WaitForChild("BackgroundMusic")
music.SoundId = "rbxassetid://1234567890" -- замените ID
music.Looped = true
music.Volume = 0.25
local ok, message = pcall(function()
ContentProvider:PreloadAsync({ music })
end)
if ok and music.IsLoaded then
music:Play()
else
warn("Музыка не загрузилась:", message)
endТрек предзагружается до Play. Looped запускает новый цикл после конца. Volume 0.25 оставляет место для эффектов и голоса. Ошибка загрузки появляется в Output.

Место Sound меняет поведение. Сравнение показывает, какой вариант легче поддерживать и проверять.
Как работают Looped, Volume и Loaded
Volume изменяет амплитуду, но не делает плохую запись чистой. Если трек уже клиппирует и хрипит, снижение Volume только скроет часть проблемы. Для нескольких категорий звука используйте SoundGroup: отдельно Music, Effects и UI. Тогда ползунок настроек меняет группу, а не каждый Sound.
| Свойство | Значение | Эффект |
|---|---|---|
| SoundId | rbxassetid://ID | Выбирает аудио |
| Looped | true | Повторяет трек |
| Volume | 0.25 | Оставляет запас для эффектов |
| Playing | true после Play | Показывает текущее состояние |
Сохраняйте в одном месте то, что может измениться. Если одно и то же значение скопировано в три функции, после первой правки они начнут расходиться. Один объект состояния и одна функция отрисовки снимают эту проблему.
Практика: слушаем на трёх устройствах
Громкость проверяют не по динамикам одного ноутбука. На телефоне меньше низких частот, в наушниках контраст сильнее, а на громких колонках утомляет повторяющаяся петля. На каждом устройстве сверьте, что музыка слышна, но не перекрывает важные сигналы.
- Добавьте разрешённый audio ID и запустите Play.
- Убедитесь, что трек начался один раз и не наложился на себя.
- Дождитесь конца и проверьте плавный повтор.
- Сравните Volume 0.15, 0.25 и 0.5 со звуками шагов.
- Запустите мобильную эмуляцию и наушники.
- Вставьте неверный ID и проверьте понятный warn в Output.
Музыка начинается без двойного запуска. Петля не даёт заметной паузы или щелчка. Шаги, UI и другие сигналы остаются разборчивыми. Недоступный ассет не ломает остальную игру.

Прослушайте до публикации. Пройдите все четыре сценария перед публикацией проекта.
Доводим звук до игрового баланса
Добавьте в настройки отдельный ползунок Music и храните его выбор на клиенте. Не запускайте музыку и в Properties, и в скрипте одновременно. Выберите один источник правды, иначе после респавна или перезахода появятся две копии. Сам трек должен иметь права на использование в experience.
Так звук станет позиционным, а не фоновым.
Музыка закроет эффекты и быстро утомит.
Копии наложатся и дадут эхо.
Аудио не загрузится, даже если число указано верно.
Что получится в итоге

Готовая сцена получает фоновую музыку, которая не зависит от позиции игрока и не перекрывает эффекты.
Где хранить фоновую музыку?
В SoundService, если она должна звучать одинаково во всём мире.
Зачем Looped?
Он автоматически запускает трек с начала после конца.
Почему аудио молчит?
Чаще всего неверен SoundId, нет прав на ассет или загрузка завершилась ошибкой.
Как понять, что проект готов?
Он повторяет целевой сценарий несколько раз подряд, понятно реагирует на ошибочный ввод и не теряет состояние при обычных действиях.
Можно ли копировать код целиком?
Можно как стартовую точку, но сначала замените значения из примера, затем запустите проект по шагам. Если вы не можете объяснить одну строку, её лучше разобрать до следующего шага.
События, объекты и Luau можно закрепить в курсе Lua. Музыку удобно запускать после стартового меню.
Для следующего шага добавьте анимацию и кнопку настроек в ScreenGui. Так игрок сможет сам уменьшить музыку.