Dźwięk 2D to dźwięk niedyrektywny, który nie emituje z żadnej konkretnej lokalizacji, pozostając takim samym niezależnie od pozycji lub orientacji słuchacza w przestrzeni 3D. Oznacza to, że gdy gracze poruszają swoimi słuchawkami po otoczeniu, mogą konsekwentnie słyszeć dźwięk 2D z każdego miejsca, w które się obracają.
Używając pliku Gingerbread House - Start .rbxl jako punktu wyjścia oraz Gingerbread House - Complete Audio jako odniesienia, ten samouczek pokazuje, jak dodać zarówno dźwięk 2D w pętli, jak i dźwięk jednorazowy do swoich gier, w tym wskazówki dotyczące:
- Muzyki w tle, która odtwarzana jest natychmiast po połączeniu graczy z serwerem.
- Wyzwalania dźwięku, aby zapewnić graczom natychmiastową informację zwrotną zgodnie z ich celami w grze.
- Aktywacji różnych dźwięków, aby wskazać różne interakcje z interfejsem użytkownika.
Jeśli w którymkolwiek momencie utkniesz w procesie, możesz użyć Gingerbread House - Complete Audio jako odniesienia, aby porównać swoje postępy.
Obiekty dźwięku 2D
Aby stworzyć dźwięk niedyrektywny, ważne jest, aby zrozumieć obiekty dźwiękowe, z którymi będziesz pracować w tym samouczku. Istnieją trzy główne typy obiektów dźwiękowych dla dźwięku 2D:
- Obiekt AudioPlayer ładuje i odtwarza plik audio.
- Obiekt AudioDeviceOutput to fizyczne urządzenie sprzętowe w rzeczywistości, takie jak głośnik lub słuchawki.
- Wires przenoszą strumienie audio z jednego obiektu do drugiego.
Wszystkie te obiekty dźwiękowe współpracują ze sobą, aby przenieść dźwięk z odtwarzania pliku do sprzętu każdego gracza. Przyjrzyjmy się, jak to działa w praktyce, używając przykładu gracza noszącego słuchawki podczas grania w grę na swoim laptopie:
- Obiekt AudioPlayer ładuje identyfikator zasobu audio 127645268874265 do gry dla dźwięku zakupu waluty.
- Wire przenosi strumień z AudioPlayer do AudioDeviceOutput, aby strumień wydobywał się z słuchawek gracza.
- Obiekt AudioDeviceOutput przenosi dźwięk do fizycznego głośnika gracza, a w tym przypadku do ich słuchawek.
Następujące sekcje zagłębiają się w te obiekty, gdy uczysz się, jak odtwarzać zarówno dźwięk 2D w pętli, jak i dźwięk jednorazowy. Przeglądając te obiekty z nadchodzącymi technikami, możesz dokładniej przewidzieć, jak uchwycić i przekazać dźwięk z gry do gracza.
Dźwięk w pętli
Dźwięk 2D w pętli, czyli dźwięk niedyrektywny, który powtarza się bezproblemowo, gdy gracze łączą się z serwerem, jest powszechną techniką projektowania dźwięku, aby zapewnić spójne tło dźwiękowe, niezależnie od tego, co gracze robią lub gdzie się znajdują w przestrzeni 3D. Ponadto dźwięk 2D w pętli zapewnia, że twoja gra nigdy nie jest całkowicie cicha, co może dezorientować i rozpraszać graczy od ich celów.
Aby zilustrować ten koncept, sprawdź, jak poniższy dźwięk 2D znacząco poprawia jakość próbki Hazardous Space Station. Bez muzyki w tle stacja kosmiczna wydaje się pusta i martwa. Jednak gdy stacja kosmiczna zawiera muzykę w tle, stacja kosmiczna wydaje się zarówno złowroga, jak i niebezpieczna, co dodaje do ogólnej mrocznej atmosfery.
Dźwięk w pętli jest szczególnie przydatny do ustalenia, jak chcesz, aby gracze się czuli, gdy tylko dołączą do twojej gry. Na przykład próbka ma na celu zapewnienie graczom radosnej przygody w zimowej krainie czarów, więc używa wesołego utworu audio, aby pozytywnie wpłynąć na ich nastrój w momencie, gdy wchodzą do otoczenia. Aby zobaczyć, jak wpływowa może być ta technika, rozważ, jak zmieniłoby się doświadczenie gracza, gdybyś zamienił dźwięk w pętli na utwór metalowy.
Aby odtworzyć dźwięk 2D w pętli w próbce pliku Gingerbread House - Complete Audio:
Włącz domyślny słuchacz, który jest przypisany do twojej postaci gracza.
- W oknie Explorer wybierz SoundService.
- W oknie Properties ustaw DefaultListenerLocation na Character. Gdy uruchomisz grę, silnik automatycznie tworzy AudioDeviceOutput pod SoundService.
W oknie Explorer przejdź do SoundService, a następnie:
- Wstaw obiekt AudioPlayer, aby utworzyć źródło dźwięku.
- Wstaw obiekt AudioDeviceOutput, aby utworzyć głośnik, który odtwarza dźwięk w całej grze.
- Wstaw obiekt Wire, aby przenieść strumień z odtwarzacza audio do głośnika.

Wybierz AudioPlayer, a następnie w oknie Properties,
- Ustaw AssetID na rbxassetid://1841461968, aby odtworzyć wesoły utwór audio.
- Włącz Looping, aby dźwięk powtarzał się bezproblemowo.
- Ustaw Volume na 0.2, aby odtwarzać dźwięk na niskim poziomie głośności, abyś mógł nadal słyszeć inne źródła dźwięku w grze.
Wybierz Wire, a następnie w oknie Properties,
- Ustaw SourceInstance na nowy AudioPlayer, aby określić, że chcesz, aby przewód przenosił dźwięk z tego konkretnego odtwarzacza audio.
- Ustaw TargetInstance na nowy AudioDeviceOutput, aby określić, że chcesz, aby przewód przenosił dźwięk do tego konkretnego głośnika.
W oknie Explorer wstaw Script do AudioPlayer, zmień jego nazwę na LoopBackgroundMusic, ustaw jego właściwość RunContext na Client, a następnie wklej następujący kod do skryptu:
local audioPlayer = script.ParentaudioPlayer:Play()Wyjaśnienie koduSkrypt zaczyna od zadeklarowania zmiennej reprezentującej rodzica skryptu AudioPlayer. Następnie skrypt ustawia źródło dźwięku do odtwarzania od momentu, gdy gracz dołącza do gry, do momentu, gdy opuszcza grę.
Przetestuj grę, aby usłyszeć muzykę w tle w pętli.
Dźwięk jednorazowy
Dźwięk 2D jednorazowy, czyli dźwięk niedyrektywny, który odtwarzany jest raz w określonym czasie i miejscu, chyba że gracz wyzwoli go ponownie, dostarcza graczom ważnych informacji o wszystkim, co chcesz, aby nie przegapili. Używanie tego typu informacji zwrotnej w dźwięku w swoich grach jest istotne, ponieważ zapewnia natychmiastową, jasną odpowiedź na kluczowe funkcje rozgrywki i działania gracza, takie jak rozpoczęcie walki z bossem lub utrata znacznej ilości zdrowia.
Następujące sekcje dostarczają szczegóły implementacji dla typowych scenariuszy rozgrywki, w których gracze potrzebują terminowej, niedyrektywnej informacji zwrotnej, w tym informacji zwrotnej dotyczącej rozgrywki, interakcji z elementami UI oraz narracji głosowej dla samouczków.
Informacja zwrotna dotycząca rozgrywki
Gdy gracze postępują w twojej grze, ważne jest, aby otrzymywali natychmiastową informację zwrotną dźwiękową na temat statusu wszystkiego, co wpływa na ich rozgrywkę, takiego jak ich wynik, zdrowie lub postęp w poziomie. Ponieważ ten typ dźwięku bezpośrednio łączy się z celami gracza, ważne jest, aby te dźwięki były jasne, słyszalne i przekazywały użyteczne i dokładne informacje.
Aby zilustrować ten koncept, przyjrzyjmy się poniższemu dźwiękowi 2D jednorazowemu z szablonu Platformer, który odtwarzany jest, gdy gracze skaczą i zbierają monety:
- Dźwięk powiewu powietrza odtwarzany jest natychmiast po naciśnięciu klawisza skoku przez gracza na ich urządzeniu.
- Wysokotonowy dźwięk dzwonka i dźwięk monet odtwarzane są natychmiast po tym, jak postać gracza dotknie monety.
Obydwa te dźwięki są natychmiast rozpoznawalne w kontekście przestrzeni 3D i pomagają graczom zrozumieć sukces ich działań bez polegania wyłącznie na wskazówkach wizualnych.
Gdy odtwarzasz wiele dźwięków jednocześnie, niektóre dźwięki mogą być ważniejsze dla graczy niż inne. W tym przypadku dźwięk zbierania monet przekazuje cenniejsze informacje o rozgrywce niż dźwięk skoku, więc gra odtwarza go na nieco wyższym poziomie głośności. Nie ma jednak standardów ani zasad, aby osiągnąć świetną mieszankę, więc dostosuj dźwięki w swojej grze, aby odzwierciedlały to, co uważasz za najważniejsze.
Na przykład próbka zawiera różne wyzwalacze dźwiękowe w całej grze, ale nie wszystkie są na tym samym poziomie ważności dla zrozumienia głównego celu gry: zbieraj gumdrops, aby otworzyć domek z piernika. Aby upewnić się, że gracze są świadomi, co muszą zrobić, próbka potraja amplitudę informacji zwrotnej dźwiękowej za każdym razem, gdy gracz zbiera gumdrop.
Aby odtworzyć dźwięk informacji zwrotnej jednorazowej w próbce pliku Gingerbread House - Complete Audio:
W oknie Explorer przejdź do Workspace ⟩ Gumdrops ⟩ Gumdrop, a następnie:
- Wstaw obiekt AudioPlayer, aby utworzyć źródło dźwięku.
- Wstaw obiekt AudioDeviceOutput, aby utworzyć głośnik, który odtwarza dźwięk w całej grze.
- Wstaw obiekt Wire, aby przenieść strumień z odtwarzacza audio do głośnika.

Wybierz AudioPlayer, a następnie w oknie Properties,
- Ustaw AssetID na rbxassetid://9113723699, aby odtworzyć delikatny dźwięk żucia.
- Ustaw TimePosition na 0.15, aby rozpocząć utwór audio bliżej rzeczywistego dźwięku żucia.
- Ustaw Volume na 3, aby odtwarzać dźwięk na wysokim poziomie głośności, abyś mógł usłyszeć dźwięk gumdropa ponad inne źródła dźwięku w grze.
Wybierz Wire, a następnie w oknie Properties,
- Ustaw SourceInstance na nowy AudioPlayer, aby określić, że chcesz, aby przewód przenosił dźwięk z tego konkretnego odtwarzacza audio.
- Ustaw TargetInstance na nowy AudioDeviceOutput, aby określić, że chcesz, aby przewód przenosił dźwięk do tego konkretnego głośnika.
Duplikuj Gumdrop, aż będziesz miał trzy gumdrops, a następnie rozrzuć je po otoczeniu.
W oknie Explorer przejdź do ServerScriptService, a następnie wstaw Script, zmień jego nazwę na GumdropService, ustaw jego właściwość RunContext na Server, a następnie wklej następujący kod do skryptu:
-- Inicjalizacja usługlocal Workspace = game:GetService("Workspace")local Players = game:GetService("Players")local ServerStorage = game:GetService("ServerStorage")local TweenService = game:GetService("TweenService")-- Modułylocal Leaderboard = require(ServerStorage.Leaderboard)local PlayerData = require(ServerStorage.PlayerData)-- Zmiennelocal gumdropsFolder = Workspace.Gumdropslocal gumdrops = gumdropsFolder:GetChildren()local GUMDROP_KEY_NAME = PlayerData.GUMDROP_KEY_NAMElocal GUMDROP_AMOUNT_TO_ADD = 1local function updatePlayerGumdrops(player, updateFunction)-- Aktualizuj tabelę gumdropówlocal newGumdropAmount = PlayerData.updateValue(player, GUMDROP_KEY_NAME, updateFunction)-- Aktualizuj tablicę liderów gumdropówLeaderboard.setStat(player, GUMDROP_KEY_NAME, newGumdropAmount)-- Sprawdź, czy gracz zebrał trzy gumdropsif newGumdropAmount >= 3 then-- Odtwórz dźwięk zdarzenia drzwi, gdy gracz zbierze trzy gumdropslocal audioPlayer = Workspace.Door.AudioPlayeraudioPlayer:Play()-- Animuj drzwi, aby przesunęły się w dółlocal doorPart = Workspace.Doorlocal tweenInfo = TweenInfo.new(2, Enum.EasingStyle.Linear)local tween = TweenService:Create(doorPart, tweenInfo, {Position = doorPart.Position + Vector3.new(0, -15, 0)})tween:Play()endend-- Definiowanie obsługi zdarzeńlocal function onGumdropTouched(otherPart, gumdrop)if gumdrop:GetAttribute("Active") thenlocal character = otherPart.Parentlocal player = Players:GetPlayerFromCharacter(character)if player then-- Gracz dotknął gumdropalocal audioPlayer = gumdrop.AudioPlayeraudioPlayer:Play()gumdrop.Transparency = 1gumdrop:SetAttribute("Active", false)updatePlayerGumdrops(player, function(oldGumdropAmount)oldGumdropAmount = oldGumdropAmount or 0return oldGumdropAmount + GUMDROP_AMOUNT_TO_ADDend)endendend-- Ustawianie nasłuchiwaczy zdarzeńfor _, gumdrop in gumdrops dogumdrop:SetAttribute("Active", true)gumdrop.Touched:Connect(function(otherPart)onGumdropTouched(otherPart, gumdrop)end)endWyjaśnienie koduSkrypt zaczyna od inicjalizacji usług Workspace, Players, ServerStorage oraz TweenService, aby mógł odwołać się do ich dzieci i funkcjonalności. Następnie wymaga modułów Leaderboard i PlayerData w ServerStorage; te moduły są odpowiedzialne za tworzenie i aktualizowanie tablicy liderów w prawym górnym rogu ekranu, która śledzi ilość gumdrops, które gracz zbiera w otoczeniu.
Funkcja updatePlayerGumdrops skryptu jest w dużej mierze odpowiedzialna za aktualizację tablicy liderów za każdym razem, gdy gracz zbiera gumdrop, oraz czekanie na moment, w którym zbierze wszystkie trzy gumdrops, aby mogła wyzwolić dźwięk pozycyjny i animację dla drzwi domku z piernika. Aby uzyskać więcej informacji na temat tej części skryptu, zobacz Dodaj dźwięk 3D - Informacja zwrotna zdarzeń.
Funkcja onGumdropTouched skryptu to miejsce, w którym odbywa się większość pracy związanej z wyzwalaniem dźwięku 2D dla informacji zwrotnej dotyczącej rozgrywki, i przyjmuje dwa argumenty:
- otherPart - Część, która koliduje z gumdropem.
- gumdrop - Sferyczna część, która reprezentuje gumdrop.
Gdy cokolwiek koliduje z częścią gumdropa, skrypt najpierw sprawdza, czy gumdrop jest aktywny. Jeśli tak, sprawdza, czy kolidujący obiekt to gracz. Jeśli tak, skrypt następnie:
- Odtwarza utwór audio 2D z odtwarzacza audio.
- Sprawia, że gumdrop staje się niewidoczny.
- Dezaktywuje gumdrop, aby gracze nie mogli wchodzić w interakcję z niewidocznym gumdropem.
- Aktualizuje tablicę liderów dla gracza, który dotknął gumdropa.
Na koniec skrypt ustawia nasłuchiwacze zdarzeń, aby dla każdego gumdropa połączyć funkcję z zdarzeniem Touched, które wywołuje funkcję onGumdropTouched, gdy gracz dotknie gumdropa.
Przetestuj grę, aby usłyszeć dźwięk żucia po zebraniu gumdropa.
Interakcja z UI
Gdy gracze wchodzą w interakcję z elementami interfejsu użytkownika (UI), takimi jak najeżdżanie na pole wyboru lub wybieranie przycisku zakupu, ważne jest, aby zapewnić natychmiastową informację zwrotną, aby intuicyjnie zrozumieli jak wchodzą w interakcję z twoim UI. Na przykład wielu projektantów zmienia cechy wizualne UI, gdy gracze włączają lub wyłączają ustawienia, aby komunikować status ustawienia.
Jednak dla graczy z wadami wzroku, w których zmiany kolorów lub animacje są trudniejsze do zrozumienia samodzielnie, przydatne jest zapewnienie wielu form informacji zwrotnej sensorycznej dla interakcji z UI, aby pozostały one dostępne i intuicyjne dla jak największej liczby graczy. Aby rozwinąć ten koncept, rozważmy następujące stany UI, które są ważne dla przycisków zakupu w szablonie UGC Homestore:
- W fokusie - Wskazuje, że gracz podświetla element UI w przygotowaniu do jego wyboru.
- Na hoverze - Wskazuje, że gracz najeżdża kursorem na element UI.
- Wybrany - Wskazuje, że gracz wybrał element UI za pomocą swojego wejścia.
Wszystkie trzy te interakcje są niezbędne dla głównego przepływu użytkowników w szablonie, w którym gracze przeglądają, wybierają i kupują odzież i akcesoria dla awatarów, więc niezwykle ważne jest, aby nikt nie był zdezorientowany co do tego, jak wchodzić w interakcję z UI. Aby przygotować graczy do sukcesu, szablon zapewnia zarówno wizualną, jak i dźwiękową informację zwrotną dla każdej interakcji z UI.




Aby dać przykład, jak możesz skonfigurować wiele form informacji zwrotnej sensorycznej, próbka zapewnia zarówno wizualną, jak i dźwiękową informację zwrotną, gdy gracze naciskają przycisk miętowy na ekranie. Gdy gracze nie wchodzą w interakcję z przyciskiem, wygląda on jak typowy cukierek miętowy, ale gdy naciskają przycisk, próbka:
- Odtwarza radosny utwór audio.
- Zabarwia przycisk na odcień niebieskozielony.
- Przesuwa przycisk nieco w dół na ekranie.
Z tego miejsca możesz połączyć tę interakcję z różnymi użytecznymi akcjami w grze, takimi jak otwieranie menu lub zakup przedmiotu.


Aby odtworzyć dźwięk interakcji UI jednorazowy w próbce pliku Gingerbread House - Complete Audio:
W oknie Explorer przejdź do StarterGui ⟩ 2DAudioButton, a następnie:
- Wstaw obiekt AudioPlayer, aby utworzyć źródło dźwięku.
- Wstaw obiekt AudioDeviceOutput, aby utworzyć głośnik, który odtwarza dźwięk w całej grze.
- Wstaw obiekt Wire, aby przenieść strumień z odtwarzacza audio do głośnika.

Wybierz AudioPlayer, a następnie w oknie Properties ustaw AssetID na rbxassetid://3422389728, aby odtworzyć retro utwór dźwiękowy.
Wybierz Wire, a następnie w oknie Properties,
- Ustaw SourceInstance na nowy AudioPlayer, aby określić, że chcesz, aby przewód przenosił dźwięk z tego konkretnego odtwarzacza audio.
- Ustaw TargetInstance na nowy AudioDeviceOutput, aby określić, że chcesz, aby przewód przenosił dźwięk do tego konkretnego głośnika.
W oknie Explorer wstaw LocalScript do 2DAudioButton, zmień jego nazwę na PlayAudioWhenPressed, a następnie wklej następujący kod do skryptu:
local TweenService = game:GetService("TweenService")local buttonGui = script.Parentlocal buttonImageButton = buttonGui.ButtonFrame.ButtonImageButtonlocal buttonAudioPlayer = buttonGui.AudioPlayerlocal tweenInfo = TweenInfo.new(.2, Enum.EasingStyle.Exponential)local buttonTweenByIsPressed = {-- Naciśnięty[true] = TweenService:Create(buttonImageButton, tweenInfo, {Position = buttonImageButton.Position + UDim2.fromScale(0, .1),ImageColor3 = Color3.fromRGB(117, 255, 255),}),-- Domyślny[false] = TweenService:Create(buttonImageButton, tweenInfo, {Position = buttonImageButton.Position,ImageColor3 = Color3.fromRGB(255, 255, 255),}),}local function onIsPlayingChanged()local isPlaying = buttonAudioPlayer.IsPlayinglocal tween = buttonTweenByIsPressed[isPlaying]tween:Play()endonIsPlayingChanged()buttonAudioPlayer:GetPropertyChangedSignal("IsPlaying"):Connect(onIsPlayingChanged)buttonAudioPlayer.Ended:Connect(onIsPlayingChanged)buttonImageButton.Activated:Connect(function(_hit)buttonAudioPlayer:Play()end)Wyjaśnienie koduSkrypt zaczyna od uzyskania:
- TweenService, aby mógł animować elementy UI.
- Rodzica skryptu 2DAudioButton ScreenGui.
- Cukierka miętowego ImageButton.
- Odpowiedniego odtwarzacza audio z twoim utworem dźwiękowym.
Skrypt następnie definiuje:
- Obiekt TweenInfo, który określa, że animacja przycisku będzie odtwarzana z eksponencjalnym stylem animacji.
- Dwa tweens, które reprezentują stan przycisku naciśnięty lub nienaciśnięty.
- Stan true naciśnięty przesuwa przycisk nieco w dół na ekranie i zabarwia go na odcień niebieskozielony.
- Stan false nienaciśnięty przesuwa przycisk z powrotem do jego pierwotnej pozycji na ekranie i usuwa poprzednie zabarwienie.
Reszta skryptu to miejsce, w którym odbywa się większość pracy związanej z wyzwalaniem informacji zwrotnej dźwiękowej interakcji UI 2D, więc przyjrzyjmy się, jak funkcja onIsPlayingChanged i nasłuchiwacze zdarzeń współpracują ze sobą w przepływie użytkownika UI:
- buttonImageButton.Activated nasłuchuje, gdy gracz klika przycisk, a następnie wywołuje funkcję Play(), aby rozpocząć odtwarzanie powiązanego dźwięku z odtwarzacza audio. Ten proces zmienia właściwość AudioPlayer.IsPlaying z false na true.
- buttonAudioPlayer:GetPropertyChangedSignal("IsPlaying") nasłuchuje zmiany właściwości IsPlaying odtwarzacza audio, a następnie wywołuje funkcję onIsPlayingChanged.
- Funkcja onIsPlayingChanged wykorzystuje te informacje do wyzwolenia tweenu, który zmienia jego wizualny wygląd na ekranie.
- Aby zapobiec przypadkowemu ponownemu uruchomieniu dźwięku przez gracza, jeśli klikną przycisk w szybkim tempie, buttonAudioPlayer.Ended nasłuchuje, gdy odtwarzacz audio kończy odtwarzanie, zanim ponownie wywoła funkcję onIsPlayingChanged.
Ważne jest, aby zauważyć, że zdarzenie onIsPlayingChanged wyzwala się tylko wtedy, gdy zmienia się z false na true, co oznacza, że nie wyzwala się, gdy zmienia się z true na false. To jest zamierzona funkcjonalność z powodu komplikacji związanych z czasowaniem replikacji właściwości z serwera do klienta. Z tego powodu w tym przykładzie dostarczono i nasłuchiwano zdarzenia Ended, aby pokryć obie sytuacje.
Przetestuj grę, aby usłyszeć dźwięk dzwonka za każdym razem, gdy naciskasz przycisk na ekranie.