Воспроизведение пользовательских звуков в FiveM: NUI аудио, громкость по расстоянию, форматы
Воспроизведение пользовательских звуков в FiveM с помощью NUI аудио (SendNUIMessage и HTML элемента audio), громкость на основе расстояния, файлы OGG, xsound и встроенные аудиобанки.
У вас есть звуковой файл, например звонок в дверь, сирена или уведомление, и вы хотите воспроизвести его из скрипта. FiveM не имеет простого встроенного инструмента для пользовательских аудиофайлов, поэтому обычный ответ — NUI: скрытая веб-страница в вашем ресурсе, которая воспроизводит файл, когда скрипт клиента просит об этом. Так работают ресурсы в стиле interact-sound. Ниже вы найдете код, громкость по расстоянию, форматы и другие варианты.
Как это работает
- Ресурс имеет HTML-страницу (
ui_page) с небольшим скриптом. - Скрипт клиента отправляет сообщение на страницу с
SendNUIMessage. - Страница создает объект
Audioс файлом и воспроизводит его.
Страница может оставаться невидимой и не требует фокуса мыши.
Ресурс
resources/[mic]/my_sounds/
fxmanifest.lua
client.lua
html/
index.html
sounds/
doorbell.ogg
alarm.ogg-- fxmanifest.lua
fx_version 'cerulean'
game 'gta5'
ui_page 'html/index.html'
files {
'html/index.html',
'html/sounds/*.ogg',
}
client_script 'client.lua'Звуковые файлы должны быть в files, или страница не сможет их загрузить.
HTML-страница
<!DOCTYPE html>
<html>
<body>
<script>
window.addEventListener('message', (event) => {
const data = event.data
if (data.action !== 'play') return
const audio = new Audio('./sounds/' + data.file + '.ogg')
audio.volume = Math.min(Math.max(data.volume ?? 1.0, 0), 1)
audio.play().catch((err) => console.log('sound error', err))
})
</script>
</body>
</html>audio.volume варьируется от 0.0 до 1.0. Значения вне этого диапазона вызывают ошибку, поэтому код ограничивает его.
Скрипт клиента
local function playSound(file, volume)
SendNUIMessage({
action = 'play',
file = file,
volume = volume or 1.0,
})
end
RegisterNetEvent('my_sounds:play', function(file, volume)
playSound(file, volume)
end)
exports('PlaySound', playSound)Теперь другой скрипт клиента может вызвать exports.my_sounds:PlaySound('doorbell', 0.6), и сервер может отправить TriggerClientEvent('my_sounds:play', source, 'doorbell', 0.6) одному игроку или -1 всем.
Совет: для звука, который игрок должен слышать все время (уведомление, звонок телефона), этого достаточно. Для звука, связанного с местом, используйте версию с расстоянием ниже.
Громкость на основе расстояния
Для звука в точке, например сигнализации на здании, сервер отправляет координаты, и каждый клиент решает, насколько громко она звучит:
-- client.lua
RegisterNetEvent('my_sounds:playAt', function(file, coords, maxDistance, baseVolume)
local pos = GetEntityCoords(PlayerPedId())
local dist = #(pos - vec3(coords.x, coords.y, coords.z))
if dist >= maxDistance then return end
local volume = (1.0 - dist / maxDistance) * (baseVolume or 1.0)
playSound(file, volume)
end)-- server.lua: everyone gets it, only players in range hear it
TriggerClientEvent('my_sounds:playAt', -1, 'alarm', vec3(120.0, -1300.0, 29.0), 40.0, 1.0)Это проверяет расстояние один раз, когда звук начинается. Для длительного звука, где игрок движется, отправьте позицию снова через интервалы или сохраните объект аудио на странице и обновляйте его громкость по мере отправки клиентом новых значений. Звук, который должен следовать за движущимся транспортным средством, — это то место, где готовая библиотека помогает, как в следующем разделе.
Держите сервер под контролем того, кто что инициирует. Если позволить клиентам отправлять событие «воспроизвести для всех», любой читер может спамить звуки всему серверу. Смотрите события сервера и безопасность.
Форматы и размер файлов
- OGG: лучший выбор по умолчанию, маленький и хорошего качества.
- MP3: тоже хорошо, и легко найти.
- WAV: работает, но большой. Используйте только для очень коротких эффектов.
Каждый файл в files скачивается каждым игроком, поэтому делайте его коротким, моно для эффектов и сжатым. Обрежьте тишину в начале файла: задержка, которую вы слышите в игре, часто исходит из этого. Если общий объем велик, применяется то же предупреждение, что и для других активов: смотрите перегруженные активы.
xsound и другие библиотеки
Вместо написания страницы самостоятельно вы можете использовать звуковую библиотеку, такую как xsound. Она воспроизводит аудио из файла или URL в позиции или на сущности и может позже изменять громкость и позицию, что подходит для музыки в баре или портативной колонки, которая следует за игроком. Прочитайте её README для точного синтаксиса экспортов, так как они различаются между версиями. Идея та же: скрытая NUI страница воспроизводит аудио, а скрипт клиента управляет им.
Встроенные звуки и аудиобанки
Встроенные звуки игры — еще один вариант. Они воспроизводятся с помощью встроенных функций, таких как PlaySoundFrontend или PlaySoundFromCoord, с именем и набором звука, и не требуют файлов от вас. Добавление собственных звуков в аудиосистему игры также возможно с помощью файлов аудиобанков и строк data_file для аудио, но это специализированная работа с собственными инструментами и легко сломать. Для большинства серверов NUI аудио проще и достаточно.
Распространенные проблемы
- Вообще нет звука. Проверьте имя файла и что файл находится в
files. Откройте NUI в инструментах разработки игры, если они у вас есть, и прочитайте консоль на предмет 404. - Звук воспроизводится только один раз. Создавайте новый объект
Audioкаждый раз, как в коде выше, или сбросьтеcurrentTimeна сохраненный. - Слишком громко или слишком тихо. Держите громкость от 0.0 до 1.0 и устанавливайте её низко по умолчанию.
- Звук прерывается при перезагрузке ресурса. Страница перезагружается с ресурсом. Это ожидается.
- Скрипт, использующий
interact-sound, не работает. Ресурсы, ожидающие это имя, нуждаются в ресурсе с тем же именем и экспортами. Проверьте, что хочет скрипт, прежде чем переименовывать свой.
Контрольный список
| Симптом | Исправление |
|---|---|
| Ничего не воспроизводится | Поместите файлы в files и проверьте строку ui_page |
| Неверный путь | Используйте ./sounds/<name>.ogg относительно HTML страницы |
| Слишком громко | Ограничьте audio.volume от 0 до 1 и понизьте значение по умолчанию |
| Звук должен затухать с расстоянием | Отправьте координаты и вычислите громкость на клиенте |
| Скачивание медленное | Используйте короткие OGG файлы и сожмите их |
| Движущийся источник (транспортное средство) | Используйте библиотеку, такую как xsound, или обновляйте громкость по мере движения игрока |
Короткие ответы
Какой формат аудио я должен использовать?
OGG — хороший выбор по умолчанию: маленькие файлы и хорошо поддерживаются браузером игры. MP3 также работает. Избегайте WAV для чего-либо длительного, так как файлы большие и каждый игрок их скачивает.
Нужен ли мне SetNuiFocus для воспроизведения звука?
Нет. Воспроизведение аудио из NUI не требует фокуса и видимого интерфейса, только загруженную страницу с ui_page, содержащую код аудио.
Как сделать звук тише, когда игрок далеко?
Отправьте координаты звука клиенту, измерьте расстояние до игрока и установите громкость аудио на основе этого, например линейно от 1 близко до 0 на максимальном расстоянии.
Скрипты без этой проблемы
Arcade MachinesСемь аркадных игр в настоящих автоматах, с таблицами рекордов и ставками.Смотреть скрипт →
Mic PhoneСкладной телефон, который раскладывается в планшет и работает и на настоящем телефоне игрока.Смотреть скрипт →
Crypto MiningКупите склад, соберите фермы по деталям и майните монеты на живом рынке.Смотреть скрипт →