3D 오디오는 3D 공간의 특정 위치에서 발생하는 방향성 소리로, 오디오 발사체와 청취자 간의 거리 및 방향에 따라 볼륨이 증가하거나 감소합니다. 이를 통해 청취자나 발사체가 환경을 돌아다니면서 플레이어는 다양한 방향과 볼륨 레벨에서 오디오를 동적으로 들을 수 있습니다.
Gingerbread House - Start .rbxl 파일을 출발점으로 사용하고 Gingerbread House - Complete Audio를 참조하여, 이 튜토리얼에서는 경험에 반복 및 일회성 3D 오디오를 추가하는 방법을 설명하며 다음과 같은 지침을 포함합니다:
- 플레이어가 서버에 연결하는 즉시 재생되는 루핑 환경 소리.
- 플레이어의 게임플레이에 중요한 주요 상황 이벤트에 대한 정보를 제공하는 오디오 트리거.
- 3D 객체와 상호작용할 때 플레이어에게 청각적 피드백을 제공하는 오디오 활성화.
- 플레이어를 환경 내 관심 지점으로 안내하는 캐릭터 사운드 클립 재생.
프로세스 중에 막히는 경우, 진행 상황을 비교하기 위해 Gingerbread House - Complete Audio를 참조할 수 있습니다.
오디오 객체
방향성 오디오를 생성하려면 이 튜토리얼에서 작업할 오디오 객체를 이해하는 것이 중요합니다. 3D 오디오에 대한 주요 오디오 객체는 총 여섯 가지입니다:
- AudioPlayer 객체는 오디오 파일을 로드하고 재생합니다.
- AudioEmitter 객체는 3D 환경으로 오디오를 방출하는 가상 스피커입니다.
- AudioListener 객체는 3D 환경에서 오디오를 수집하는 가상 마이크입니다.
- AudioDeviceOutput 객체는 실제 세계 내의 물리적 하드웨어 장치로 스피커 또는 헤드폰과 같습니다.
- AudioDeviceInput 객체는 실제 세계 내의 물리적 마이크입니다.
- Wires는 하나의 객체에서 다른 객체로 오디오 스트림을 전달합니다.
이 모든 오디오 객체들은 실제 세계의 대응물처럼 소리를 방출하는 데 함께 작동합니다. 이제 예를 들어 플레이어가 헤드셋을 착용하고 노트북으로 경험을 플레이하는 상황을 살펴보겠습니다:
- AudioPlayer는 비 내기 트랙을 위해 1516791621 오디오 자산 ID를 경험에 로드합니다.
- AudioEmitter는 3D 환경으로 비 내기 트랙의 오디오 스트림을 방출합니다.
- 캐릭터의 자식 AudioListener 객체가 3D 환경 내의 그 소리를 듣고 이를 헤드셋으로 피드백합니다.
- AudioDeviceOutput 객체는 AudioListener에서 플레이어의 물리적 스피커, 또는 이 경우에는 헤드폰으로 소리를 전달합니다.
- AudioDeviceInput 객체는 실제 세계의 소리를 캡처하여 음성 채팅을 위해 경험에 다시 피드백합니다.


다음 섹션에서는 반복 및 일회성 3D 오디오를 재생하는 방법을 배우면서 이러한 객체를 더 깊이 다룹니다. 향후 기술을 검토할 때 이러한 객체에 대해 더 정확하게 예측할 수 있어 경험에서 소리를 캡처하고 이를 플레이어에게 전달하는 방법과 그 반대의 경우를 배울 수 있습니다.
반복 오디오
반복 3D 오디오는 플레이어가 서버에 연결하는 즉시 원활하게 반복되는 방향성 오디오로, 3D 공간의 분위기를 향상시키는 일반적인 사운드 디자인 기법입니다. 또한, 반복 3D 오디오는 텔레비전의 정적이나 폭포의 포효와 같은 환경 소스의 일관성을 유지합니다. 이러한 소리가 갑자기 멈춘다면 환경은 비현실적으로 느껴질 것입니다.
이 개념을 시연하기 위해, 아래의 3D 오디오를 리뷰해보세요. 두 개의 큰 폭포 소리가 반복되지 않는 오디오 트랙이 완료되는 즉시 멈추는 방식입니다. 물 소리는 처음에 플레이어를 야외 환경으로 몰입시키지만, 갑작스러운 청각적 변화는 폭포가 실제 세계에서 발생하는 방식에 비해 불편하고 비자연스럽습니다.
이와 유사하게, 샘플은 흐르는 초콜릿 폭포에 이 기술을 사용하며, 플레이어의 오디오 발사체와의 거리에 따라 볼륨을 조정합니다. 플레이어가 발사체에서 20 스터드 이내에 있을 때, 발사체는 최대 볼륨으로 소리를 방출합니다. 플레이어가 멀어지면, 소리의 수위는 오디오 발사체로부터 20 스터드 떨어질 때마다 감소합니다. 이러한 것은 현실 세계의 소리가 출처로부터 멀어질수록 볼륨이 감소하는 것을 모방합니다.
샘플 Gingerbread House - Complete Audio 장소 파일에서 반복하는 3D 오디오를 재현하려면:
플레이어 캐릭터에 연결된 기본 리스너를 활성화합니다.
- Explorer 창에서 SoundService를 선택합니다.
- Properties 창에서 DefaultListenerLocation을 Character로 설정합니다. 경험을 실행하면 엔진이 자동으로:
- 각 플레이어 캐릭터의 Humanoid.RootPart 아래에 AudioListener를 생성하여 3D 공간 내 소리의 위치와 크기 변화에 따라 실제 스피커에서 소리가 바뀌도록 합니다.
- SoundService 아래에 AudioDeviceOutput을 생성합니다.
Explorer 창에서 Workspace ⟩ WaterfallAudioObject로 이동한 다음:
- 폭포의 오디오 소스를 생성하기 위해 AudioPlayer 객체를 삽입합니다.
- WaterfallAudioObject에서 위치 스트림을 방출하기 위해 AudioEmitter 객체를 삽입합니다.
- 오디오 플레이어에서 오디오 발사체로 스트림을 전달하기 위해 Wire 객체를 삽입합니다.

AudioPlayer를 선택한 다음, Properties 창에서,
- AssetID를 rbxassetid://1516791621로 설정하여 비 내기 오디오 트랙을 재생합니다.
- Looping을 활성화하여 오디오가 원활하게 반복되도록 합니다.
AudioEmitter를 선택한 다음, Properties 창에서 DistanceAttenuation을 {0: 1}, {20: 0.8}, {40: 0.4}, {80: 0}로 설정하여 소리가 오디오 발사체에서 20 스터드 떨어질 때마다 점진적으로 감소하도록 합니다.
Wire를 선택한 다음, Properties 창에서,
- SourceInstance를 새 AudioPlayer로 설정하여 이 특정 오디오 플레이어에서 오디오를 전달하도록 합니다.
- TargetInstance를 새 AudioEmitter로 설정하여 폭포 내에서 이 특정 오디오 발사체로 오디오를 전달하도록 합니다.
Explorer 창에서 WaterfallAudioObject에 Script를 삽입하고 이름을 LoopWaterfallMusic으로 바꿉니다. RunContext 속성을 Client로 설정한 후 아래 코드를 스크립트에 붙여넣습니다:
local audioPlayer = script.ParentaudioPlayer:Play()코드 설명이 스크립트는 스크립트의 부모인 AudioPlayer를 나타내는 변수를 선언하는 것으로 시작합니다. 스크립트는 플레이어가 경험에 합류한 순간부터 나가는 순간까지 오디오 소스를 재생하도록 설정합니다.
경험을 플레이 테스트하여 아바타가 폭포 근처에 있을 때 반복되는 초콜릿 비 소리를 들어보세요. 캐릭터의 머리를 다른 방향으로 돌릴 때, 사운드는 3D 공간 내에서 발사체의 위치에 따라 실제 스피커에서 동적으로 변화합니다.
일회성 오디오
일회성 3D 오디오는 특정 시간과 위치에서 한 번만 재생되며 플레이어가 다시 트리거하지 않는 한 반복되지 않는 방향성 오디오로, 플레이어에게 그들의 행동, 환경 및 주변 캐릭터에 대한 맥락을 제공합니다. 경험에서 이러한 유형의 청각적 피드백을 사용하는 것은 입장하는 적을 피하거나 유용한 아이템을 획득하는 것과 같은 전략적 결정을 내리도록 허용하기 때문에 필수적입니다.
다음 섹션에서는 플레이어가 시기적절한 방향 피드백이 필요한 일반 게임 플레이 시나리오에 대한 구현 세부 정보를 제공합니다. 여기에는 상황별 게임플레이 이벤트, 객체 상호작용 및 NPC 대화가 포함됩니다.
이벤트 피드백
플레이어가 새로운 게임플레이 영역을 언락하거나 적의 발사를 유도하는 등의 주요 상황 이벤트를 트리거할 때, 그들이 3D 공간의 어디에 집중하고 주의를 기울여야 하는지를 이해하는 것이 중요합니다. 즉각적인 청각적 피드백을 받지 못하면, 그들은 자신의 게임플레이에 중요한 정보 놓칠 수 있으며, 다음에 어디로 가야할지 또는 무엇을 해야 할지에 대한 불만을 느낄 수 있습니다.
이것이 중요한 이유를 보이기 위해, Laser Tag 템플릿에서 각 플레이어의 블래스터에서 발생하는 일회성 3D 오디오를 리뷰해봅시다:
- 플레이어가 블래스터로 발사할 때마다 깊은 팝 소리가 재생됩니다.
- 플레이어가 블래스터에 새 라운드를 재장전할 때마다 클릭 및 로봇 비프 소리가 재생됩니다.
이 두 가지 소리 모두 플레이어에게 발사 방향과 주변 플레이어에게 소리의 위치를 경고하여 정보에 기반한 결정을 내려 재밌게 놀거나 잠재적인 위험을 피할 수 있도록 합니다.
샘플은 같은 기술을 사용하여 경험 내에서 주된 목표를 완료한 플레이어에게 보상을 알립니다. 세 개의 구슬을 모은 후, 진저브레드 하우스의 문이 열려 플레이어가 내부의 선물에 접근할 수 있습니다.
플레이어가 구슬을 수집하는 특정 순서가 없기 때문에, 어떤 구슬을 마지막으로 수집하든 플레이어가 문이 열리는 것을 인식하는 것이 중요합니다. 위치적 소리는 이 가능성을 제공하여 플레이어가 성공을 인식하고 다음에 어디로 가야 할지 인자가 리드합니다.
샘플 Gingerbread House - Complete Audio 장소 파일에서 일회성 이벤트 피드백 3D 오디오를 재현하려면:
Explorer 창에서 Workspace ⟩ Door로 이동한 다음:
- 소리를 위한 오디오 소스를 생성하기 위해 AudioPlayer 객체를 삽입합니다.
- Door에서 위치 스트림을 방출하기 위해 AudioEmitter 객체를 삽입합니다.
- 오디오 플레이어에서 오디오 발사체로 스트림을 전달하기 위해 Wire 객체를 삽입합니다.

AudioPlayer를 선택한 다음, Properties 창에서 AssetID를 rbxassetid://5930776613으로 설정하여 sliding metal gate 오디오 트랙을 재생합니다.
Wire를 선택한 다음, Properties 창에서,
- SourceInstance를 새 AudioPlayer로 설정하여 이 특정 오디오 플레이어에서 오디오를 전달하도록 합니다.
- TargetInstance를 새 AudioEmitter로 설정하여 볼륨 내에서 이 특정 오디오 발사체로 오디오를 전달하도록 합니다.
Explorer 창에서 ServerScriptService로 이동한 다음, Script를 삽입하고 이름을 GumdropService로 바꿉니다. RunContext 속성을 Server로 설정한 후, 아래 코드를 스크립트에 붙여넣습니다:
-- 변수 초기화local Workspace = game:GetService("Workspace")local Players = game:GetService("Players")local ServerStorage = game:GetService("ServerStorage")local TweenService = game:GetService("TweenService")-- 모듈local Leaderboard = require(ServerStorage.Leaderboard)local PlayerData = require(ServerStorage.PlayerData)-- 변수local gumdropsFolder = Workspace.Gumdropslocal gumdrops = gumdropsFolder:GetChildren()local GUMDROP_KEY_NAME = PlayerData.GUMDROP_KEY_NAMElocal GUMDROP_AMOUNT_TO_ADD = 1local function updatePlayerGumdrops(player, updateFunction)-- 구슬 테이블 업데이트하기local newGumdropAmount = PlayerData.updateValue(player, GUMDROP_KEY_NAME, updateFunction)-- 구슬 리더보드 업데이트Leaderboard.setStat(player, GUMDROP_KEY_NAME, newGumdropAmount)-- 플레이어가 세 개의 구슬을 모았는지 확인if newGumdropAmount >= 3 then-- 플레이어가 세 개의 구슬을 수집 시 문 이벤트 오디오 재생local audioPlayer = Workspace.Door.AudioPlayeraudioPlayer:Play()-- 문을 아래로 애니메이션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-- 이벤트 핸들러 정의local function onGumdropTouched(otherPart, gumdrop)if gumdrop:GetAttribute("Enabled") thenlocal character = otherPart.Parentlocal player = Players:GetPlayerFromCharacter(character)if player then-- 플레이어가 구슬에 닿음local audioPlayer = gumdrop.AudioPlayeraudioPlayer:Play()gumdrop.Transparency = 1gumdrop:SetAttribute("Enabled", false)updatePlayerGumdrops(player, function(oldGumdropAmount)oldGumdropAmount = oldGumdropAmount or 0return oldGumdropAmount + GUMDROP_AMOUNT_TO_ADDend)print("플레이어가 구슬을 수집했습니다.")endendend-- 이벤트 리스너 설정for _, gumdrop in gumdrops dogumdrop:SetAttribute("Enabled", true)gumdrop.Touched:Connect(function(otherPart)onGumdropTouched(otherPart, gumdrop)end)end코드 설명이 스크립트는 Workspace, Players, ServerStorage 및 TweenService 서비스를 초기화하여 자식 및 기능을 참조할 수 있도록 시작합니다. 그 후, ServerStorage에서 Leaderboard 및 PlayerData 모듈을 요구하여, 이 모듈들은 환경 내에서 플레이어가 수집한 구슬의 수량을 추적하는 리더보드를 생성하고 업데이트합니다.
스크립트의 updatePlayerGumdrops 함수는 이벤트 피드백을 위한 3D 오디오를 트리거하는 기본 작업이 이루어지는 곳이며, 두 개의 인수를 취합니다:
- player - 구슬을 수집한 플레이어.
- updateFunction - 플레이어의 수집한 구슬 수량을 업데이트하는 콜백 함수.
플레이어가 구슬에 충돌하면 스크립트는:
- PlayerData.updateValue 함수를 호출하여 플레이어의 새로운 구슬 수집량 값을 가져옵니다.
- 이 새로운 양으로 리더보드를 업데이트합니다 (Leaderboard.setStat 함수를 호출).
- 이 양이 3 이상인지 확인합니다.
이 값이 3 이상이면, 스크립트는:
- 오디오 플레이어에서 오디오 발사체까지 3D 오디오 트랙을 재생합니다.
- 문을 현재 위치에서 직선으로 15 스터드 아래로 이동시킵니다.
나머지 스크립트는 구슬과 충돌한 모든 것을 플레이어로 인식하여 비위치 소리를 트리거하도록 합니다. 이 스크립트의 자세한 내용은 2D 오디오 추가 - 게임피드백을 참조하세요.
경험을 플레이 테스트하여 환경 내에서 세 개의 구슬을 수집한 후 슬라이드 게이트 소리를 들어보세요. 카메라를 회전할 때, 사운드는 3D 공간 내에서 발사체의 위치에 따라 동적으로 변화합니다.
객체 상호작용
플레이어가 조명 스위치를 켜거나 무기를 들어올리는 등 3D 객체와 상호작용할 때, 그 객체와의 상호작용 방식에 대해 직관적으로 이해할 수 있도록 즉각적인 피드백을 제공하는 것이 중요합니다. 시각적 및 청각적 피드백의 조합은 플레이어의 행동과 환경 반응 간의 인과 관계를 강화합니다.
이 개념을 확장하기 위해, 다음은 캐비지를 기르는 사용자 흐름을 위한 Plant 샘플에서의 일회성 3D 오디오를 살펴보겠습니다:
- 플레이어가 씨앗을 심을 때 부드러운 클링 소리가 재생됩니다.
- 플레이어가 자라는 식물에 물을 줄 때 젖은 물 splash와 같은 소리가 재생됩니다.
- 플레이어가 커다란 식물을 수확할 때 클립 소리가 재생됩니다.
- 플레이어가 캐비지를 수레에 넣을 때 부드러운 thud 소리가 재생됩니다.
이 모든 소리는 플레이어의 근접 프롬프트 키 상호작용을 3D 공간 내의 객체 형상 변화와 관련하여 강화합니다. 색 변화나 애니메이션이 독립적으로 인식되기 더 어려운 시각 장애가 있는 플레이어에게는 이러한 다양한 형태의 감각 피드백을 제공함으로써 3D 객체 상호작용이 최대한 접근 가능하고 직관적으로 유지됩니다.
객체 상호작용을 다르게 구성할 수 있는 방법의 예로, 샘플은 플레이어가 진저브레드 하우스 내의 3D 페퍼민트 버튼을 밟을 때마다 시각적 및 청각적인 피드백을 제공합니다. 플레이어가 버튼과 상호작용하지 않으면 일반적인 페퍼민트 사탕처럼 보이지만 버튼을 밟으면 샘플은:
- 축하의 지가조리즈 오디오 트랙을 재생합니다.
- 버튼의 측면을 녹색 음영으로 착색합니다.
- 버튼을 지면으로 이동시킵니다.
여기서부터 이 상호작용을 아이템을 잠금 해제하거나 특별한 능력을 트리거하는 것과 같은 다양한 게임 플레이 동작에 연결할 수 있습니다.


샘플 Gingerbread House - Complete Audio 장소 파일에서 일회성 객체 상호작용 3D 오디오를 재현하려면:
Explorer 창에서 Workspace ⟩ 3DAudioButton으로 이동한 다음:
- 버튼을 위한 오디오 소스를 생성하기 위해 AudioPlayer 객체를 삽입합니다.
- 3DAudioButton에서 위치 스트림을 방출하기 위해 AudioEmitter 객체를 삽입합니다.
- 오디오 플레이어에서 오디오 발사체로 스트림을 전달하기 위해 Wire 객체를 삽입합니다.

AudioPlayer를 선택한 다음, Properties 창에서 AssetID를 rbxassetid://1846248593으로 설정하여 기념 축하 음성을 재생합니다.
Wire를 선택한 다음, Properties 창에서,
- SourceInstance를 새 AudioPlayer로 설정하여 이 특정 오디오 플레이어에서 오디오를 전달하도록 합니다.
- TargetInstance를 새 AudioEmitter로 설정하여 버튼 내에서 이 특정 오디오 발사체로 오디오를 전달하도록 합니다.
Explorer 창에서 3DAudioButton에 Script를 삽입하고 이름을 PlayAudioWhenPressed로 바꾼 후 아래 코드를 스크립트에 붙여넣습니다:
local TweenService = game:GetService("TweenService")local buttonModel = script.Parent.Parentlocal buttonPart = buttonModel.ButtonPartlocal buttonPressedAudioPlayer = buttonModel.ButtonPressedAudioPlayerlocal tweenInfo = TweenInfo.new(.2, Enum.EasingStyle.Exponential)local buttonTweenByIsPressed = {-- 눌릴 때[true] = TweenService:Create(buttonPart, tweenInfo, {Size = buttonPart.Size / Vector3.new(2, 1, 1),Color = Color3.fromRGB(75, 151, 75),}),-- 기본 상태[false] = TweenService:Create(buttonPart, tweenInfo, {Size = buttonPart.Size,Color = Color3.fromRGB(196, 40, 28),}),}local function onIsPlayingChanged()local isPlaying = buttonPressedAudioPlayer.IsPlayinglocal tween = buttonTweenByIsPressed[isPlaying]tween:Play()endonIsPlayingChanged()buttonPressedAudioPlayer:GetPropertyChangedSignal("IsPlaying"):Connect(onIsPlayingChanged)buttonPressedAudioPlayer.Ended:Connect(onIsPlayingChanged)buttonPart.Touched:Connect(function(_hit)buttonPressedAudioPlayer:Play()end)코드 설명이 스크립트는:
- 버튼의 위치가 지면에서 튀어나온 부품을 애니메이션화하도록 TweenService를 가져옵니다.
- 스크립트의 부모 3DAudioButton 모델을 가져옵니다.
- 지면에서 튀어나온 부품을 가져옵니다.
- 축하 사운드 오디오 트랙이 있는 해당 오디오 플레이어를 가져옵니다.
그 후 스크립트는:
- 버튼 애니메이션이 지수 애니메이션 스타일로 재생될 것이라고 명시하는 TweenInfo 객체를 정의합니다.
- 버튼이 눌린 상태와 눌리지 않은 상태를 나타내는 두 개의 트윈을 정의합니다.
- true 눌린 상태는 버튼을 살짝 아래로 이동시키고 부분의 측면을 녹색 음영으로 착색합니다.
- false 눌리지 않은 상태는 버튼을 원래 위치로 되돌리고 이전 음영을 제거합니다.
나머지 스크립트에서는 객체 상호작용 피드백을 위한 주요 작업이 이루어지므로 onIsPlayingChanged 함수와 이벤트 리스너가 함께 어떻게 작동하는지 살펴봅시다:
- buttonPart.Touched는 플레이어가 버튼에 닿을 때를 인식하여 Play() 함수를 호출하여 오디오 플레이어의 관련 오디오를 재생합니다. 이 과정은 AudioPlayer.IsPlaying 속성을 false에서 true로 전환합니다.
- buttonPressedAudioPlayer:GetPropertyChangedSignal("IsPlaying")는 오디오 플레이어의 IsPlaying 속성이 변경될 때를 인식하여 onIsPlayingChanged 함수를 호출합니다.
- onIsPlayingChanged 함수는 이 정보를 사용하여 3D 공간 내 시각적 외형을 바꾸는 트윈을 호출합니다.
- 버튼에 빠르게 연속하여 점프하는 플레이어가 오디오를 재시작할 위험을 방지하기 위해 buttonPressedAudioPlayer.Ended는 오디오 플레이어가 재생이 끝날 때까지 onIsPlayingChanged 함수를 다시 호출하도록 합니다.
onIsPlayingChanged 이벤트는 false에서 true로 전환될 때만 발생하므로, true에서 false로 전환될 때는 발생하지 않습니다. 이는 서버에서 클라이언트로 속성을 복제하는 타이밍과 관련하여 발생할 수 있는 문제로 인해 의도된 동작입니다. 이런 이유로 이 예제에서는 두 경우를 모두 커버하기 위해 Ended 이벤트를 제공하고 이를 리스닝합니다.
경험을 플레이 테스트하여 진저브레드 하우스 내 3D 버튼에 플레이어 캐릭터가 닿을 때 축하 소리를 들어보세요. 버튼에서 멀어질 때 소리의 볼륨이 감소합니다.
캐릭터 대화
비플레이어 캐릭터(NPC)로부터 방향성 오디오를 제공하는 것은 플레이어가 그들의 환경 내 관심 지점으로 가는 방법을 알려주고 다른 캐릭터와의 상호작용 깊이를 더하는 데 유용합니다. 사실 내러티브 중심의 경험에서는 많은 디자이너가 캐릭터 대화를 전략적으로 사용하여 플레이어가 그들의 캐릭터, 동료 및 적 캐릭터 또는 세계 자체에 대해 간접적으로 학습하게 합니다.
이 기술의 일반적으로 사용되는 예로는:
- 대화 스타일로 경험의 톤 설정.
- 이야기를 통해 캐릭터 간의 관계를 배우도록 안내.
- 적의 대화를 통해 동기를 고백하거나 플레이어와의 관계에 대한 위치를 공개합니다.
- 플레이어 캐릭터가 자신의 생각을 말하는 행위를 통해 다음에 무엇을 해야 할지 부드럽게 안내합니다. 예: 스스로 치유하거나 다른 위치로 이동하거나 아이템을 찾도록.
- 동료 캐릭터가 플레이어 캐릭터와 대화하여 경험 내 세계의 역사, 문화 및 사회 문제와 같은 세부정보를 드러냅니다.
이것이 실제로 어떻게 보일 수 있는지 시연하기 위해, 샘플은 플레이어가 우주 정거장의 주요 로비 지역에 있을 때 주기적으로 재생되는 Beyond the Dark의 일회성 3D 오디오를 살펴보겠습니다.
우주 정거장을 캐릭터로 구성하여 이 대화 클립은 플레이어에게 전반적인 환경에 대한 중요한 정보 및 전통을 제공합니다. 예를 들어, 이 한 문장에서 플레이어는:
- 우주, 특히 Kerr-Newman Deep Space Relay 14로 알려진 우주 정거장에 있다는 것을 알게 됩니다.
- 그들의 환경이 미래적이고 환영을 받는다는 것을 파악합니다.
- 그들은 방문자이며 곧 떠날 가능성이 있다는 것을 이해합니다.
이러한 세부 사항은 플레이어를 그들의 환경에 몰입시키고, 그들의 임무에 긴급함을 더합니다. 그러나 플레이어가 그들의 주요 임무가 무엇인지 알지 못하면, 캐릭터 대화를 사용하여 플레이어가 경험 내에서 하기를 원하는 것을 알릴 수 있습니다.
예를 들어, 샘플에서는 volume, 즉 3D 공간 내의 보이지 않는 영역을 사용하여 눈사람으로부터 캐릭터 대화를 트리거하여 플레이어에게 세 개의 구슬을 수집하여 그의 집의 문을 열도록 안내합니다. 플레이어가 경험에 합류할 때 처음 보는 것 중 하나로, 플레이어가 대화를 트리거하고 성공하기 위해 무엇을 해야 하는지 아는 가능성이 높아집니다.

샘플 Gingerbread House - Complete Audio 장소 파일에서 일회성 캐릭터 대화 3D 오디오를 재현하려면:
Explorer 창에서 Workspace ⟩ DialogueVolume로 이동한 다음:
- 볼륨을 위한 오디오 소스를 생성하기 위해 AudioPlayer 객체를 삽입합니다.
- DialogueVolume에서 위치 스트림을 방출하기 위해 AudioEmitter 객체를 삽입합니다.
- 오디오 플레이어에서 오디오 발사체로 스트림을 전달하기 위해 Wire 객체를 삽입합니다.

AudioPlayer를 선택한 다음, Properties 창에서 AssetID를 rbxassetid://92917410841704로 설정하여 경험의 목표에 대한 안내 음성을 재생합니다.
Wire를 선택한 다음, Properties 창에서,
- SourceInstance를 새 AudioPlayer로 설정하여 이 특정 오디오 플레이어에서 오디오를 전달하도록 합니다.
- TargetInstance를 새 AudioEmitter로 설정하여 볼륨 내에서 이 특정 오디오 발사체로 오디오를 전달하도록 합니다.
Explorer 창에서 StarterPlayer ⟩ StarterCharacterScripts로 이동한 다음, LocalScript를 삽입하고 이름을 PlayAudioWhenInVolume로 바꾼 후 아래 코드를 로컬 스크립트에 붙여넣습니다:
local Workspace = game:GetService("Workspace")local Players = game:GetService("Players")local humanoid = script.Parent:WaitForChild("Humanoid")local volumeDetector = Workspace.DialogueVolumelocal trigger = humanoid:WaitForChild("Animator")local debounce = falselocal localPlayer = Players.LocalPlayervolumeDetector.Touched:Connect(function(hit)if debounce thenreturnendlocal hitCharacter = hit:FindFirstAncestorWhichIsA("Model")local hitPlayer = Players:GetPlayerFromCharacter(hitCharacter)if hitPlayer ~= localPlayer thenreturnenddebounce = truelocal audioPlayer = Workspace.DialogueVolume.AudioPlayeraudioPlayer:Play()audioPlayer.Ended:Wait()debounce = falseend)코드 설명이 스크립트는 Workspace 및 Players 서비스를 가져와 자식 및 기능을 참조할 수 있도록 시작됩니다. 각 플레이어 캐릭터가 경험 내에 로드되거나 재스폰될 때마다, 스크립트는 다음을 기다립니다:
- DialogueVolume이라는 볼륨 객체.
볼륨과 충돌하는 모든 것이 충돌하면, Touched 이벤트 핸들러 함수는 충돌한 볼륨의 자손 모델을 검색하여 그 것이 캐릭터인지 확인합니다. 만약 수확할 수 없다면:
- 디바운스를 true로 설정합니다.
- 오디오를 재생하고 끝날 때까지 기다립니다.
- 디바운스를 다시 false로 설정합니다.
디바운스를 false에서 true로 전환한 후 오디오가 재생되는 동안 다시 false로 전환하는 것은 플레이어가 볼륨과 충돌할 때 발생하는 반복적인 트리거를 방지하는 디바운스 패턴입니다. 이 디바운스 패턴에 대한 자세한 내용은 Debounce - 충돌 감지를 참조하세요.
경험을 플레이 테스트하여 눈사람 주변의 볼륨에 도달했을 때 안내 캐릭터 대화를 들어보세요.