Dźwięk 2D to dźwięk niekierunkowy, który nie wydobywa się z żadnej konkretnej lokalizacji, pozostając niezmiennym niezależnie od pozycji lub orientacji słuchacza w przestrzeni 3D. Oznacza to, że gdy gracze poruszają swoimi słuchawkami po otoczeniu, mogą stale słyszeć dźwięk 2D z dowolnego 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 poradnik pokazuje, jak dodać zarówno pętlę, jak i dźwięk jednorazowy 2D do swoich doświadczeń, w tym wskazówki dotyczące:
- Pętli muzyki w tle, która odtwarzana jest, gdy gracze łączą się z serwerem.
- Wyzwalania dźwięków, aby zapewnić graczom natychmiastową informację zwrotną zgodnie z ich celami rozgrywki.
- Aktywizowania różnych dźwięków, aby wskazać różne interakcje z interfejsem użytkownika.
Jeśli w dowolnym 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 niekierunkowy, ważne jest zrozumienie obiektów dźwiękowych, z którymi będziesz pracować w trakcie tego poradnika. Istnieją trzy główne typy obiektów dźwiękowych dla dźwięku 2D:
- Obiekt AudioPlayer ładuje i odtwarza plik audio.
- Obiekt AudioDeviceOutput jest fizycznym urządzeniem sprzętowym w rzeczywistości, takim jak głośnik lub słuchawki.
- Wires przenosi 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. Rzućmy okiem na to, jak to działa w praktyce, używając przykładu gracza noszącego słuchawki podczas gry na swoim laptopie:
- Obiekt AudioPlayer ładuje identyfikator zasobu audio 127645268874265 do doświadczenia 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 jego słuchawek.
W kolejnych sekcjach bardziej szczegółowo omówimy te obiekty, aby nauczyć się, jak odtwarzać zarówno dźwięk 2D w pętli, jak i dźwięk jednorazowy. Przeglądając te obiekty wraz z nadchodzącymi technikami, możesz dokładniej przewidzieć, jak przechwytywać i przekazywać dźwięk z doświadczenia do gracza.
Dźwięk w pętli
Dźwięk 2D w pętli, to znaczy dźwięk niekierunkowy, który powtarza się płynnie, gdy gracze łączą się z serwerem, jest powszechną techniką projektowania dźwięku, która zapewnia spójne tło dźwiękowe, niezależnie od tego, co gracze robią lub gdzie znajdują się w przestrzeni 3D. Dodatkowo dźwięk 2D w pętli zapewnia, że twoje doświadczenie nigdy nie jest całkowicie ciche, co może dezorientować i rozpraszać graczy od ich celów.
Aby zademonstrować ten koncept, sprawdź, jak następujący dźwięk 2D znacząco poprawia jakość próbki Hazardous Space Station. Bez muzyki w tle, stacja kosmiczna wydaje się pusta i lifeless. Jednak gdy do stacji kosmicznej dodaje się muzykę w tle, stacja wydaje się zarówno złowieszcza, jak i niebezpieczna, co zwiększa ogólną mroczną atmosferę.
Dźwięk w pętli jest szczególnie przydatny do ustalenia, jak chcesz, aby gracze czuli się, gdy tylko dołączają do twojego doświadczenia. Na przykład próbka ma na celu zapewnienie graczom radosnej przygody w zimowej krainie czarów, więc wykorzystuje optymistyczny utwór 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ś wymienił muzykę 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ślnego słuchacza, który jest przypięty do postaci gracza.
- W oknie Eksplorator wybierz SoundService.
- W oknie Właściwości ustaw DefaultListenerLocation na Character. Kiedy uruchomisz doświadczenie, silnik automatycznie tworzy AudioDeviceOutput pod SoundService.
W oknie Eksplorator 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łym doświadczeniu.
- Wstaw obiekt Wire, aby przenosić strumień z odtwarzacza audio do głośnika.

Wybierz AudioPlayer, a następnie w oknie Właściwości,
- Ustaw AssetID na rbxassetid://1841461968, aby odtworzyć optymistyczny utwór audio.
- Włącz Looping, aby dźwięk powtarzał się płynnie.
- 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 doświadczeniu.
Wybierz Wire, a następnie w oknie Właściwości,
- Ustaw SourceInstance na nowy AudioPlayer, aby określić, że chcesz, aby kabel przenosił dźwięk z tego konkretnego odtwarzacza audio.
- Ustaw TargetInstance na nowy AudioDeviceOutput, aby określić, że chcesz, aby kabel przenosił dźwięk do tego konkretnego głośnika.
Wróć do okna Eksplorator, wstaw Skrypt do AudioPlayer, zmień jego nazwę na LoopBackgroundMusic, ustaw jego właściwość RunContext na Client, a następnie wklej poniższy kod do skryptu:
local audioPlayer = script.ParentaudioPlayer:Play()Wyjaśnienie koduSkrypt zaczyna się od zadeklarowania zmiennej reprezentującej rodzica skryptu, AudioPlayer. Następnie ustawia źródło audio do odtwarzania od momentu dołączenia gracza do doświadczenia aż do momentu opuszczenia doświadczenia.
Przetestuj doświadczenie, aby usłyszeć muzykę backgroundową w pętli.
Dźwięk jednorazowy
Dźwięk 2D jednorazowy, czyli dźwięk niekierunkowy, który odtwarzany jest raz w określonym czasie i pozycji, chyba że gracz uruchomi go ponownie, dostarcza graczom ważnych informacji na temat wszystkiego, co chcesz, aby zauważyli. Używanie tego typu reakcji dźwiękowej w swoich doświadczeniach jest niezbędne, ponieważ zapewnia natychmiastową, klarowną reakcję na kluczowe funkcje rozgrywki i działania gracza, takie jak rozpoczęcie walki z bossem lub utrata znacznej ilości zdrowia.
Kolejne sekcje dostarczą szczegóły implementacji dla typowych scenariuszy rozgrywki, w których gracze potrzebują na czas niekierunkowej reakcji, w tym informacji zwrotnej o rozgrywce, interakcji z elementami UI oraz narracji głosowej dla tutoriali.
Informacja zwrotna o rozgrywce
W miarę jak gracze postępują w swoim doświadczeniu, ważne jest, aby otrzymywali natychmiastową informację audialną na temat statusu wszystkiego, co wpływa na ich rozgrywkę, na przykład ich punktacji, zdrowia czy postępu w poziomie. Ponieważ ten typ dźwięku bezpośrednio łączy się z celami graczy, ważne jest, aby te dźwięki były wyraźne, słyszalne i przekazywały użyteczne i dokładne informacje.
Aby zademonstrować ten koncept, przeanalizujmy następujący dźwięk 2D jednorazowy z szablonu Platformer, który odtwarzany jest, gdy gracze skaczą i zbierają monety:
- Powietrzny dźwięk "whoosh" odtwarzany jest, gdy gracz naciska klawisz skoku na swoim urządzeniu.
- Dźwięk wysokiego dźwięku "ding" oraz dźwięk poruszających się monet odtwarzany jest, gdy postać gracza dotyka 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, aby je usłyszeć niż inne. W tej sytuacji dźwięk zbierania monety przekazuje wartościowsze informacje o rozgrywce niż dźwięk skoku, więc doświadczenie odtwarza go na nieco wyższym poziomie głośności. Nie ma jednak standardów ani zasad, aby osiągnąć świetną miks, więc dostosuj dźwięki w swoim doświadczeniu, aby odzwierciedlały to, co uważasz za najważniejsze.
Na przykład, próbka zawiera różne wyzwalacze dźwiękowe w całym doświadczeniu, ale nie wszystkie mają ten sam poziom ważności dla zrozumienia głównego celu doświadczenia: zbierz gumdrops, aby otworzyć dom pachnący piernikiem. Aby zapewnić, że gracze mają świadomość tego, co muszą zrobić, próbka potraja wzmocnienie informacji zwrotnej, gdy gracz zbiera gumdrop.
Aby odtworzyć dźwięk zwrotny jednorazowy w próbce pliku Gingerbread House - Complete Audio:
W oknie Eksplorator 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łym doświadczeniu.
- Wstaw obiekt Wire, aby przenosić strumień z odtwarzacza audio do głośnika.

Wybierz AudioPlayer, a następnie w oknie Właściwości,
- Ustaw AssetID na rbxassetid://9113723699, aby odtworzyć delikatny dźwięk przeżuwania.
- Ustaw TimePosition na 0.15, aby rozpocząć utwór audio bliżej rzeczywistego dźwięku przeżuwania.
- Ustaw Volume na 3, aby odtwarzać dźwięk na wysokim poziomie głośności, abyś usłyszał dźwięk gumdropy ponad inne źródła dźwięku w doświadczeniu.
Wybierz Wire, a następnie w oknie Właściwości,
- Ustaw SourceInstance na nowy AudioPlayer, aby określić, że chcesz, aby kabel przenosił dźwięk z tego konkretnego odtwarzacza audio.
- Ustaw TargetInstance на new AudioDeviceOutput, aby określić, że chcesz, aby kabel przenosił dźwięk do tego konkretnego głośnika.
Powiel Gumdrop, aż będziesz miał trzy gumdrops, a następnie rozrzuć je po otoczeniu.
Wróć do okna Eksplorator, przejdź do ServerScriptService, a następnie wstaw Skrypt, zmień jego nazwę na GumdropService, ustaw jego właściwość RunContext na Server, a następnie wklej poniższy 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)-- Aktualizowanie tabeli gumdropslocal newGumdropAmount = PlayerData.updateValue(player, GUMDROP_KEY_NAME, updateFunction)-- Aktualizowanie rankingu gumdropsLeaderboard.setStat(player, GUMDROP_KEY_NAME, newGumdropAmount)-- Sprawdzanie, czy gracz zebrał trzy gumdropsif newGumdropAmount >= 3 then-- Odtwarzanie dźwięku drzwi, gdy gracz zbiera trzy gumdropslocal audioPlayer = Workspace.Door.AudioPlayeraudioPlayer:Play()-- Animacja drzwi 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 zdarzenialocal 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-- Ustawienie nasłuchiwaczy zdarzeńfor _, gumdrop in gumdrops dogumdrop:SetAttribute("Active", true)gumdrop.Touched:Connect(function(otherPart)onGumdropTouched(otherPart, gumdrop)end)endWyjaśnienie koduSkrypt rozpoczyna się od zainicjowania usług Workspace, Players, ServerStorage i TweenService, aby mógł odnosić się do ich dzieci i funkcjonalności. Następnie wymaga modułów Leaderboard i PlayerData w ServerStorage; te moduły odpowiadają za tworzenie i aktualizowanie rankingu w górnym prawym rogu ekranu, który śledzi ilość gumballs, które gracz zbiera w otoczeniu.
Funkcja skryptu updatePlayerGumdrops w dużej mierze odpowiada za aktualizację rankingu za każdym razem, gdy gracz zbiera gumdropa oraz czeka na moment, w którym zbierze wszystkie trzy gumdrops, aby móc wyzwolić dźwięk pozycyjny i animację dla drzwi do chałupy piernikowej. Aby uzyskać więcej informacji na temat tej części skryptu, zobacz Dodaj dźwięk 3D - Informację zwrotną zdarzenia.
Funkcja onGumdropTouched skryptu to miejsce, w którym odbywa się większość pracy dla wyzwalania dźwięku 2D dla reakcji na rozgrywkę, i przyjmuje dwa argumenty:
- otherPart - Część, która koliduje z gumdropem.
- gumdrop - Okresowa część reprezentująca gumdrop.
Gdy cokolwiek koliduje z częścią gumdropa, skrypt najpierw sprawdza, czy gumdrop jest aktywny. Jeśli tak, to sprawdza, aby upewnić się, że obiekt kolidujący jest graczem. Jeśli tak, to skrypt wykonuje:
- Odtwarza utwór dźwiękowy 2D z odtwarzacza audio.
- Zmienia gumdrop na niewidoczny.
- Dezaktywuje gumdropa, aby gracze nie mogli wchodzić w interakcje z niewidocznym gumdropem.
- Aktualizuje ranking dla gracza, który dotknął gumdropa.
Na koniec skrypt ustawia nasłuchiwacze zdarzeń, aby dla każdego gumdropa podłączyć funkcję do zdarzenia Touched, które wywołuje funkcję onGumdropTouched, gdy gracz dotyka gumdropa.
Przetestuj doświadczenie, aby usłyszeć dźwięk przeżuwania po zebraniu gumdropa.
Interakcja UI
Gdy gracze wchodzą w interakcje z elementami 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 UI. Na przykład wielu projektantów zmienia wizualne cechy UI, gdy gracze włączają lub wyłączają ustawienia, aby zakomunikować status ustawienia.
Jednak dla graczy z problemami ze wzrokiem, w których zmiany kolorów lub animacje są trudniejsze do rozpoznania samodzielnie, użyteczne jest zapewnienie wielu form reakcji sensorycznych dla interakcji UI, aby pozostały 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 szablonu UGC Homestore:
- W fokusie - Wskazuje, że gracz zaznacza element UI w przygotowaniu do jego wybrania.
- Na najeździe - Wskazuje, że gracz najeduje kursorem na element UI.
- Wybrany - Wskazuje, że gracz wybrał element UI poprzez swoje wejście.
Wszystkie te trzy interakcje są niezbędne dla głównego przepływu użytkownika szablonu, w którym gracze przeglądają, wybierają i kupują odzież i akcesoria dla awatarów, więc niezwykle istotne jest, aby nikt nie był zdezorientowany co do tego, jak wchodzić w interakcje z interfejsem użytkownika. Aby przygotować graczy na sukces, szablon zapewnia zarówno wizualne, jak i audialne reakcje zwrotne dla każdej interakcji UI.




Aby dać przykład, jak możesz skonfigurować wiele form reakcji sensorycznych, próbka zapewnia zarówno wizualne, jak i audialne reakcje, gdy gracze naciskają na ekranowy przycisk z miętą. Gdy gracze nie wchodzą w interakcje z przyciskiem, wygląda on jak typowa cukier miętowy, ale gdy go naciśną, próbka:
- Odtwarza radosny utwór dźwiękowy.
- Barwi przycisk na odcień teal.
- Nieznacznie przesuwa przycisk w dół na ekranie.
Z tego miejsca możesz połączyć tę interakcję z różnymi użytecznymi akcjami rozgrywkowymi, 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 Eksplorator 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łym doświadczeniu.
- Wstaw obiekt Wire, aby przenosić strumień z odtwarzacza audio do głośnika.

Wybierz AudioPlayer, a następnie w oknie Właściwości ustaw AssetID na rbxassetid://3422389728, aby odtworzyć retro utwór dźwiękowy.
Wybierz Wire, a następnie w oknie Właściwości,
- Ustaw SourceInstance na nowy AudioPlayer, aby określić, że chcesz, aby kabel przenosił dźwięk z tego konkretnego odtwarzacza audio.
- Ustaw TargetInstance na nowy AudioDeviceOutput, aby określić, że chcesz, aby kabel przenosił dźwięk do tego konkretnego głośnika.
Wróć do okna Eksplorator, wstaw LocalScript do 2DAudioButton, zmień jego nazwę na PlayAudioWhenPressed, a następnie wklej poniższy 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 rozpoczyna się od zyskania dostępu do:
- TweenService, aby mógł animować elementy UI.
- Rodzica skryptu, czyli obiektu 2DAudioButton ScreenGui.
- Cukierka miętowego ImageButton.
- Odpowiedniego odtwarzacza audio z utworem dźwiękowym.
Skrypt następnie definiuje:
- Obiekt TweenInfo, który określa, że animacje przycisków będą się odbywać w stylu animacji wykładniczej.
- Dwa tweens, które reprezentują stan naciśnięty lub nienaciśnięty przycisku.
- Stan naciśnięty true nieznacznie przesuwa przycisk w dół na ekranie i barwi go na odcień teal.
- Stan nienaciśnięty false przywraca przycisk do jego pierwotnej pozycji na ekranie i usuwa poprzednią barwę.
Reszta skryptu to miejsce, w którym odbywa się większość pracy, aby wyzwolić dźwięk interakcji UI 2D, więc przyjrzyjmy się, jak funkcja onIsPlayingChanged i nasłuchiwacze zdarzeń współdziałają 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 używa tych informacji, aby wyzwolić animację zmieniającą jego wizualny wygląd na ekranie.
- Aby zapobiec przypadkowemu ponownemu uruchomieniu dźwięku, jeśli gracz kliknie 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 występuje tylko wtedy, gdy zmienia się z false na true, co oznacza, że nie występuje, gdy zmienia się z true na false. To jest zamierzona funkcjonalność z powodu komplikacji związanych z synchronizacją właściwości z serwera do klienta. Z tego powodu zdarzenie Ended jest dostarczane i nasłuchiwane w tym przykładzie, aby pokryć obie sytuacje.
Przetestuj doświadczenie, aby usłyszeć jingle za każdym razem, gdy naciśniesz przycisk na ekranie.