Odtwarzanie niestandardowych dźwięków w FiveM: audio NUI, głośność na odległość, formaty

Odtwarzaj niestandardowe dźwięki w FiveM za pomocą audio NUI (SendNUIMessage i element audio HTML), głośność na podstawie odległości, pliki OGG, xsound i natywne banki audio.

Masz plik dźwiękowy, taki jak dzwonek do drzwi, syrena lub powiadomienie, i chcesz go odtwarzać ze skryptu. FiveM nie ma prostego natywu dla niestandardowych plików audio, więc zwykła odpowiedź to NUI: ukryta strona internetowa w twoim zasobie, która odtwarza plik, gdy skrypt klienta o to poprosi. W ten sposób pracują zasoby w stylu interact-sound. Poniżej znajdziesz kod, głośność odległości, formaty i inne opcje.

Jak to działa

  1. Zasób ma stronę HTML (ui_page) z małym skryptem.
  2. Skrypt klienta wysyła wiadomość do strony za pomocą SendNUIMessage.
  3. Strona tworzy obiekt Audio z plikiem i go odtwarza.

Strona może pozostać niewidoczna i nie wymaga fokusa myszy.

Zasób

text
resources/[mic]/my_sounds/
  fxmanifest.lua
  client.lua
  html/
    index.html
    sounds/
      doorbell.ogg
      alarm.ogg
lua
-- fxmanifest.lua
fx_version 'cerulean'
game 'gta5'

ui_page 'html/index.html'

files {
    'html/index.html',
    'html/sounds/*.ogg',
}

client_script 'client.lua'

Pliki dźwiękowe muszą być w files, inaczej strona nie może ich załadować.

Strona HTML

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 waha się od 0.0 do 1.0. Wartości spoza tego zakresu powodują błąd, więc kod je ogranicza.

Skrypt klienta

lua
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)

Teraz inny skrypt klienta może wywołać exports.my_sounds:PlaySound('doorbell', 0.6), a serwer może wysłać TriggerClientEvent('my_sounds:play', source, 'doorbell', 0.6) jednemu graczowi, lub -1 dla wszystkich.

Wskazówka: w przypadku dźwięku, który gracz powinien słyszeć cały czas (powiadomienie, dzwonek telefonu), to wszystko czego potrzebujesz. W przypadku dźwięku, który należy do miejsca, użyj wersji z odległością poniżej.

Głośność na podstawie odległości

W przypadku dźwięku w punkcie, takim jak alarm na budynku, serwer wysyła współrzędne, a każdy klient decyduje, jak głośny jest:

lua
-- 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)
lua
-- 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)

Sprawdza odległość raz, gdy dźwięk się rozpoczyna. W przypadku długiego dźwięku, gdzie gracz się porusza, wyślij pozycję ponownie w przedziałach czasowych, lub zatrzymaj obiekt audio na stronie i aktualizuj jego głośność w miarę wysyłania nowych wartości przez klienta. Dźwięk, który musi śledzić poruszający się pojazd, to miejsce, w którym przydaje się gotowa biblioteka, jak w następnej sekcji.

Utrzymuj serwer w kontroli nad tym, kto wyzwala co. Jeśli pozwolisz klientom wysłać zdarzenie play for everyone, każdy oszust może spamować dźwięki do całego serwera. Zobacz bezpieczne zdarzenia serwerowe.

Formaty plików i rozmiar

  • OGG: najlepszy domyślny format, mały i dobra jakość.
  • MP3: również w porządku i łatwy do znalezienia.
  • WAV: działa, ale jest duży. Używaj go tylko dla bardzo krótkich efektów.

Każdy plik w files jest pobierany przez każdego gracza, więc utrzymuj go krótki, mono dla efektów i skompresowany. Przytnij ciszę na początku pliku: opóźnienie, które słyszysz w grze, często pochodzi z tego. Jeśli całość jest duża, to samo ostrzeżenie dotyczy innych zasobów: zobacz oversized assets.

xsound i inne biblioteki

Zamiast pisać stronę sam, możesz użyć biblioteki dźwiękowej, takiej jak xsound. Odtwarza audio z pliku lub adresu URL w pozycji lub na encji, i może zmienić głośność i pozycję później, co pasuje do muzyki w barze lub boomboxu, który podąża za graczem. Przeczytaj jego README, aby poznać jego dokładne exporty, ponieważ różnią się między wersjami. Idea jest taka sama: ukryta strona NUI odtwarza audio, a skrypt klienta ją kontroluje.

Natywne dźwięki i banki audio

Własne dźwięki gry to kolejna opcja. Są odtwarzane za pomocą natywów, takich jak PlaySoundFrontend lub PlaySoundFromCoord, z nazwą i zestawem dźwięku, i nie wymagają żadnych plików od ciebie. Dodawanie własnych dźwięków do systemu audio gry jest również możliwe, za pomocą plików bankowych audio i linii data_file dla audio, ale to specjalistyczna praca z własnymi narzędziami i łatwo ją złamać. Dla większości serwerów audio NUI jest prostsze i wystarczające.

Typowe problemy

  • Brak dźwięku w ogóle. Sprawdź nazwę pliku i czy plik jest w files. Otwórz NUI w narzędziach programistów gry, jeśli je masz, i przeczytaj konsolę dla błędu 404.
  • Dźwięk odtwarza się tylko raz. Utwórz nowy obiekt Audio za każdym razem, jak w powyższym kodzie, lub zresetuj currentTime na utrzymanym.
  • Za głośno lub za cicho. Utrzymuj głośność od 0.0 do 1.0 i domyślnie ustaw ją nisko.
  • Dźwięk przerywa się po restarcie zasobu. Strona jest przeładowywana wraz z zasobem. To jest oczekiwane.
  • Skrypt, który używa interact-sound, nie działa. Zasoby, które oczekują tej nazwy, potrzebują zasobu o tej samej nazwie i exportów. Sprawdź, czego chce skrypt, zanim zmienisz nazwę swojego.

Lista kontrolna

Symptom Naprawa
Nic się nie odtwarza Umieść pliki w files i sprawdź linię ui_page
Zła ścieżka Użyj ./sounds/<name>.ogg względem strony HTML
Za głośno Ogranicz audio.volume między 0 i 1, i obniż domyślne
Dźwięk powinien zanikać z odległością Wyślij współrzędne i oblicz głośność na kliencie
Pobieranie jest powolne Użyj krótkich plików OGG i je skompresuj
Poruszające się źródło (pojazd) Użyj biblioteki, takiej jak xsound, lub aktualizuj głośność w miarę ruchu gracza

Szybkie odpowiedzi

Jaki format audio powinienem używać?

OGG jest dobrym domyślnym formatem: małe pliki i dobrze obsługiwane przez przeglądarkę gry. MP3 też działa. Unikaj WAV dla czegokolwiek długiego, ponieważ pliki są duże, a każdy gracz je pobiera.

Czy potrzebuję SetNuiFocus, aby odtwarzać dźwięk?

Nie. Odtwarzanie audio z NUI nie wymaga fokusa i nie wymaga widocznego interfejsu, tylko załadowanej strony za pomocą ui_page, która zawiera kod audio.

Jak sprawić, aby dźwięk był cichszy, gdy gracz jest daleko?

Wyślij współrzędne dźwięku do klienta, zmierz odległość do gracza i ustaw głośność audio na jej podstawie, na przykład liniowo od 1 blisko do 0 w maksymalnej odległości.

Skrypty bez tego problemu

Arcade MachinesSiedem grywalnych gier arcade w prawdziwych automatach, z rankingami i zakładami.Zobacz skrypt →Mic PhoneSkładany telefon, który rozkłada się w tablet i działa też na prawdziwym telefonie gracza.Zobacz skrypt →Crypto MiningKup magazyn, składaj koparki część po części i kop monety na żywym rynku.Zobacz skrypt →

Czytaj dalej