Reproduzir sons customizados em FiveM: NUI audio, volume pela distância, formatos
Reproduzir sons customizados em FiveM com NUI audio (SendNUIMessage e um elemento HTML audio), volume baseado em distância, arquivos OGG, xsound e audio banks nativos.
Você tem um arquivo de som, como uma campainha, uma sirene ou uma notificação, e quer reproduzi-lo de um script. FiveM não tem um native simples para arquivos de áudio customizados, então a resposta usual é NUI: uma página web escondida no seu recurso que reproduz o arquivo quando um client script pede. É assim que recursos do estilo interact-sound funcionam. Abaixo você encontra o código, o volume pela distância, os formatos e as outras opções.
Como funciona
- O recurso tem uma página HTML (
ui_page) com um pequeno script. - O client script envia uma mensagem para a página com
SendNUIMessage. - A página cria um objeto
Audiocom o arquivo e o reproduz.
A página pode ficar invisível e não precisa de focus do mouse.
O recurso
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'Os arquivos de som devem estar em files, senão a página não consegue carregá-los.
A página 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 vai de 0.0 a 1.0. Valores fora desse intervalo causam um erro, então o código o restringe.
O client script
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)Agora outro client script pode chamar exports.my_sounds:PlaySound('doorbell', 0.6), e o server pode enviar TriggerClientEvent('my_sounds:play', source, 'doorbell', 0.6) para um jogador, ou -1 para todos eles.
Dica: para um som que um jogador deve ouvir o tempo todo (uma notificação, um ringtone de telefone), isso é tudo que você precisa. Para um som que pertence a um lugar, use a versão de distância abaixo.
Volume baseado em distância
Para um som em um ponto, como um alarme em um prédio, o server envia as coordenadas e cada cliente decide como o som é:
-- 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)Isso verifica a distância uma vez, quando o som começa. Para um som longo onde o jogador se move, envie a posição novamente em intervalos, ou mantenha o objeto de áudio na página e atualize seu volume conforme o cliente envia novos valores. Um som que deve seguir um veículo em movimento é onde uma biblioteca pronta ajuda, como na próxima seção.
Mantenha o server no controle de quem dispara o quê. Se você deixar os clientes enviarem um evento play for everyone, qualquer cheater pode spamear sons para todo o server. Veja secure server events.
Formatos de arquivo e tamanho
- OGG: o melhor padrão, pequeno e boa qualidade.
- MP3: também funciona bem e é fácil de encontrar.
- WAV: funciona, mas é grande. Use apenas para efeitos muito curtos.
Todo arquivo em files é baixado por cada jogador, então mantenha-o curto, mono para efeitos, e comprimido. Remova o silêncio no início do arquivo: um atraso que você ouve no jogo frequentemente vem daí. Se o total é grande, o mesmo aviso se aplica como para outros assets: veja oversized assets.
xsound e outras bibliotecas
Em vez de escrever a página você mesmo, você pode usar uma biblioteca de som como xsound. Ela reproduz áudio de um arquivo ou uma URL em uma posição ou em uma entidade, e pode alterar o volume e a posição depois, o que é adequado para música em um bar ou um boombox que segue um jogador. Leia seu README para seus exports exatos, já que diferem entre versões. A ideia é a mesma: uma página NUI escondida reproduz o áudio, e um client script a controla.
Sons nativos e audio banks
Os sons do próprio jogo são outra opção. Eles são reproduzidos com natives como PlaySoundFrontend ou PlaySoundFromCoord, com o nome e set do som, e não precisam de arquivos seus. Adicionar seus próprios sons ao sistema de áudio do jogo também é possível, com arquivos de audio bank e linhas data_file para áudio, mas é um trabalho de especialista com suas próprias ferramentas e é fácil quebrar. Para a maioria dos servidores, NUI audio é mais simples e suficiente.
Problemas comuns
- Nenhum som. Verifique o nome do arquivo e se o arquivo está em
files. Abra o NUI nas ferramentas de desenvolvedor do jogo se você tiver, e leia o console para um 404. - Som reproduz apenas uma vez. Crie um novo objeto
Audiocada vez, como no código acima, ou resetecurrentTimeem um mantido. - Muito alto ou muito baixo. Mantenha volume de 0.0 a 1.0, e defina baixo por padrão.
- O som é cortado quando o recurso reinicia. A página é recarregada com o recurso. Isso é esperado.
- Um script que usa
interact-soundfalha. Recursos que esperam esse nome precisam de um recurso com o mesmo nome e exports. Verifique o que o script quer antes de renomear o seu.
Checklist
| Sintoma | Solução |
|---|---|
| Nada reproduz | Coloque os arquivos em files e verifique a linha ui_page |
| Caminho errado | Use ./sounds/<name>.ogg relativo à página HTML |
| Muito alto | Restrinja audio.volume entre 0 e 1, e baixe o padrão |
| Som deve desaparecer com a distância | Envie coordenadas e compute o volume no cliente |
| Download é lento | Use arquivos OGG curtos e comprimidos |
| Fonte móvel (veículo) | Use uma biblioteca como xsound, ou atualize o volume conforme o jogador se move |
Respostas rápidas
Qual formato de áudio devo usar?
OGG é um bom padrão: arquivos pequenos e bem suportado pelo navegador do jogo. MP3 também funciona. Evite WAV para qualquer coisa longa, pois os arquivos são grandes e cada jogador faz o download deles.
Preciso de SetNuiFocus para reproduzir um som?
Não. Reproduzir áudio do NUI não precisa de focus e nem de interface visível, apenas uma página carregada com ui_page que contém o código de áudio.
Como faço um som ficar mais baixo quando o jogador está longe?
Envie as coordenadas do som para o cliente, meça a distância até o jogador e defina o volume do áudio baseado nisso, por exemplo linearmente de 1 perto a 0 na distância máxima.
Scripts sem esse problema
Arcade MachinesSete jogos de fliperama jogáveis em máquinas de verdade, com rankings e apostas.Ver script →
Mic PhoneUm celular dobrável que abre em tablet e chega ao celular de verdade do jogador.Ver script →
Crypto MiningCompre um galpão, monte rigs peça por peça e minere moedas num mercado que se mexe.Ver script →