Jouer des sons personnalisés dans FiveM : audio NUI, volume par distance, formats
Jouer des sons personnalisés dans FiveM avec l'audio NUI (SendNUIMessage et un élément audio HTML), volume basé sur la distance, fichiers OGG, xsound et banques audio natives.
Vous avez un fichier audio, comme une sonnette, une sirène ou une notification, et vous voulez le jouer à partir d'un script. FiveM n'a pas de native simple pour les fichiers audio personnalisés, donc la réponse habituelle est NUI : une page web cachée dans votre ressource qui joue le fichier quand un script client le demande. C'est comme fonctionnent les ressources dans le style d'interact-sound. Ci-dessous, vous trouverez le code, le volume en fonction de la distance, les formats et les autres options.
Comment ça marche
- La ressource a une page HTML (
ui_page) avec un petit script. - Le script client envoie un message à la page avec
SendNUIMessage. - La page crée un objet
Audioavec le fichier et le joue.
La page peut rester invisible, et elle n'a besoin d'aucune mise au point de souris.
La ressource
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'Les fichiers audio doivent être dans files, sinon la page ne peut pas les charger.
La page 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 va de 0,0 à 1,0. Les valeurs en dehors de cette plage causent une erreur, le code la limite donc.
Le script client
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)Maintenant, un autre script client peut appeler exports.my_sounds:PlaySound('doorbell', 0.6), et le serveur peut envoyer TriggerClientEvent('my_sounds:play', source, 'doorbell', 0.6) à un joueur, ou -1 pour tous les joueurs.
Conseil : pour un son qu'un joueur devrait entendre tout le temps (une notification, une sonnerie de téléphone), c'est tout ce dont vous avez besoin. Pour un son qui appartient à un lieu, utilisez la version de distance ci-dessous.
Volume basé sur la distance
Pour un son à un point, comme une alarme sur un bâtiment, le serveur envoie les coordonnées, et chaque client décide de son volume :
-- 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)Cela vérifie la distance une fois, quand le son commence. Pour un son long où le joueur bouge, envoyez la position à nouveau à intervalles, ou gardez l'objet audio dans la page et mettez à jour son volume à mesure que le client envoie de nouvelles valeurs. Un son qui doit suivre un véhicule en mouvement est où une bibliothèque prête à l'emploi aide, comme dans la section suivante.
Gardez le serveur sous contrôle de qui déclenche quoi. Si vous laissez les clients envoyer un événement « jouer pour tout le monde », n'importe quel tricheur peut spammer des sons sur tout le serveur. Consultez événements serveur et sécurité.
Formats et taille des fichiers
- OGG : le meilleur par défaut, petit et bonne qualité.
- MP3 : aussi bien, et facile à trouver.
- WAV : fonctionne, mais c'est volumineux. Utilisez-le uniquement pour les très courts effets.
Chaque fichier dans files est téléchargé par chaque joueur, donc gardez-le court, mono pour les effets, et compressé. Découpez le silence au début du fichier : un délai que vous entendez dans le jeu provient souvent de cela. Si le total est volumineux, le même avertissement s'applique comme pour les autres actifs : consultez actifs surdimensionnés.
xsound et autres bibliothèques
Au lieu d'écrire la page vous-même, vous pouvez utiliser une bibliothèque audio comme xsound. Il joue de l'audio à partir d'un fichier ou d'une URL à une position ou sur une entité, et peut modifier le volume et la position plus tard, ce qui convient à la musique dans un bar ou un boombox qui suit un joueur. Lisez son README pour ses exports exacts, car ils diffèrent selon les versions. L'idée est la même : une page NUI cachée joue l'audio, et un script client le contrôle.
Sons natifs et banques audio
Les sons du jeu lui-même sont une autre option. Ils sont joués avec des natives comme PlaySoundFrontend ou PlaySoundFromCoord, avec le nom et l'ensemble du son, et n'ont besoin d'aucun fichier de votre part. L'ajout de vos propres sons au système audio du jeu est également possible, avec des fichiers de banque audio et des lignes data_file pour l'audio, mais c'est un travail de spécialiste avec ses propres outils et c'est facile de casser. Pour la plupart des serveurs, l'audio NUI est plus simple et suffisant.
Problèmes courants
- Aucun son du tout. Vérifiez le nom du fichier et que le fichier est dans
files. Ouvrez la NUI dans les outils de développement du jeu si vous les avez, et lisez la console pour un 404. - Le son ne joue qu'une fois. Créez un nouvel objet
Audioà chaque fois, comme dans le code ci-dessus, ou réinitialisezcurrentTimesur un objet conservé. - Trop fort ou trop silencieux. Gardez le volume de 0,0 à 1,0, et mettez-le bas par défaut.
- Le son est coupé quand la ressource redémarre. La page est rechargée avec la ressource. C'est attendu.
- Un script qui utilise
interact-soundéchoue. Les ressources qui s'attendent à ce nom ont besoin d'une ressource avec le même nom et les mêmes exports. Vérifiez ce que le script veut avant de renommer le vôtre.
Liste de contrôle
| Symptôme | Correction |
|---|---|
| Rien ne joue | Mettez les fichiers dans files et vérifiez la ligne ui_page |
| Mauvais chemin | Utilisez ./sounds/<name>.ogg relatif à la page HTML |
| Trop fort | Limitez audio.volume entre 0 et 1, et baissez la valeur par défaut |
| Le son devrait diminuer avec la distance | Envoyez les coordonnées et calculez le volume sur le client |
| Le téléchargement est lent | Utilisez des fichiers OGG courts et compressez-les |
| Source en mouvement (véhicule) | Utilisez une bibliothèque comme xsound, ou mettez à jour le volume à mesure que le joueur bouge |
Réponses rapides
Quel format audio devrais-je utiliser ?
OGG est un bon par défaut : petits fichiers et bien supporté par le navigateur du jeu. MP3 fonctionne aussi. Évitez WAV pour n'importe quoi de long, car les fichiers sont volumineux et chaque joueur les télécharge.
Ai-je besoin de SetNuiFocus pour jouer un son ?
Non. Jouer de l'audio depuis NUI n'a besoin d'aucune mise au point et aucune interface visible, seulement une page chargée avec ui_page qui contient le code audio.
Comment faire un son plus silencieux quand le joueur est loin ?
Envoyez les coordonnées du son au client, mesurez la distance jusqu'au joueur et définissez le volume audio à partir de celui-ci, par exemple linéairement de 1 près à 0 à la distance maximale.
Des scripts sans ce problème
Arcade MachinesSept jeux d’arcade jouables dans de vraies bornes, avec classements et paris.Voir le script →
Mic PhoneUn téléphone pliable qui se déplie en tablette et se prolonge jusqu’au vrai téléphone du joueur.Voir le script →
Crypto MiningAchetez un entrepôt, montez vos rigs pièce par pièce et minez sur un marché qui bouge.Voir le script →