เสียง 3D คือเสียงที่มีทิศทางซึ่งออกจากตำแหน่งเฉพาะในพื้นที่ 3D โดยจะเพิ่มหรือลดระดับเสียงขึ้นอยู่กับระยะห่างและทิศทางระหว่างผู้ปล่อยเสียงและผู้ฟัง ซึ่งหมายความว่าเมื่อผู้ฟังหรือผู้ปล่อยเสียงเคลื่อนที่ไปรอบ ๆ สภาพแวดล้อม ผู้เล่นสามารถได้ยินเสียงนั้นจากทิศทางและระดับเสียงที่แตกต่างกันได้อย่างไดนามิก
โดยใช้ไฟล์ Gingerbread House - Start .rbxl เป็นจุดเริ่มต้นและ Gingerbread House - Complete Audio เป็นข้อมูลอ้างอิง บทแนะนำนี้จะแสดงให้คุณเห็นวิธีการเพิ่มเสียง 3D ทั้งแบบวนซ้ำและแบบเล่นครั้งเดียวในเกมของคุณ รวมถึงแนวทางในการ:
- เสียงสภาพแวดล้อมที่วนซ้ำซึ่งเล่นทันทีที่ผู้เล่นเชื่อมต่อกับเซิร์ฟเวอร์
- การกระตุ้นเสียงเพื่อแจ้งผู้เล่นเกี่ยวกับเหตุการณ์สำคัญในสถานการณ์ที่สำคัญต่อการเล่นเกมของพวกเขา
- การเปิดเสียงเพื่อให้ผู้เล่นได้รับฟีดแบ็กทางเสียงเมื่อพวกเขามีปฏิสัมพันธ์กับวัตถุ 3D
- การเล่นเสียงของตัวละครที่มีส่วนร่วมและชี้นำผู้เล่นไปยังจุดที่น่าสนใจในสภาพแวดล้อมของพวกเขา
หากคุณติดขัดในกระบวนการใด ๆ คุณสามารถใช้ Gingerbread House - Complete Audio เป็นข้อมูลอ้างอิงเพื่อเปรียบเทียบความก้าวหน้าของคุณ
วัตถุเสียง
ในการสร้างเสียงทิศทาง สิ่งสำคัญคือต้องเข้าใจวัตถุเสียงที่คุณจะทำงานด้วยตลอดบทแนะนำนี้ มีวัตถุเสียงหลัก 6 ประเภทสำหรับเสียง 3D:
- วัตถุ AudioPlayer โหลดและเล่น ไฟล์เสียง
- วัตถุ AudioEmitter เป็น ลำโพงเสมือน ที่ปล่อยเสียงเข้าสู่สภาพแวดล้อม 3D
- วัตถุ AudioListener เป็น ไมโครโฟนเสมือน ที่รับเสียงจากสภาพแวดล้อม 3D
- วัตถุ AudioDeviceOutput เป็น อุปกรณ์ฮาร์ดแวร์จริง ในโลกจริง เช่น ลำโพงหรือหูฟัง
- วัตถุ AudioDeviceInput เป็น ไมโครโฟนจริง ในโลกจริง
- Wires ส่งเสียงจากวัตถุหนึ่งไปยังอีกวัตถุหนึ่ง
วัตถุเสียงทั้งหมดนี้ทำงานร่วมกันเพื่อปล่อยเสียงเช่นเดียวกับคู่ของพวกเขาในโลกจริง มาดูวิธีการทำงานนี้ในทางปฏิบัติด้วยตัวอย่างของผู้เล่นที่สวมชุดหูฟังขณะเล่นเกมด้วยแล็ปท็อปของพวกเขา:
- วัตถุ AudioPlayer โหลด ID ของสินทรัพย์เสียง 1516791621 ลงในเกมสำหรับแทร็กเสียงฝน
- วัตถุ AudioEmitter ปล่อยสตรีมเสียงของแทร็กฝนเข้าสู่สภาพแวดล้อม 3D
- วัตถุ AudioListener ของตัวละครฟังเสียงนั้นในสภาพแวดล้อม 3D และส่งกลับไปยังชุดหูฟังของพวกเขา
- วัตถุ AudioDeviceOutput ส่งเสียงจาก AudioListener ไปยังลำโพงจริงของผู้เล่น หรือในกรณีนี้คือหูฟังของพวกเขา
- วัตถุ AudioDeviceInput จับเสียงจากโลกจริงและส่งกลับเข้าสู่เกมสำหรับการสนทนาผ่านเสียง


ส่วนถัดไปจะเจาะลึกและอ้างอิงถึงวัตถุเหล่านี้เมื่อคุณเรียนรู้วิธีการเล่นเสียง 3D ทั้งแบบวนซ้ำและแบบเล่นครั้งเดียว ขณะที่คุณตรวจสอบวัตถุเหล่านี้ด้วยเทคนิคที่กำลังจะมาถึง คุณจะสามารถคาดการณ์ได้อย่างแม่นยำมากขึ้นว่าจะแคปเจอร์และส่งเสียงจากเกมไปยังผู้เล่นและในทางกลับกันได้อย่างไร
เสียงวนซ้ำ
เสียง 3D วนซ้ำ หรือเสียงทิศทางที่เล่นซ้ำอย่างต่อเนื่องทันทีที่ผู้เล่นเชื่อมต่อกับเซิร์ฟเวอร์ เป็นเทคนิคการออกแบบเสียงที่ใช้กันทั่วไปเพื่อเพิ่มบรรยากาศของพื้นที่ 3D โดยทำให้รู้สึกมีชีวิตชีวาและมีพลศาสตร์ นอกจากนี้ เสียง 3D วนซ้ำยังช่วยให้แหล่งเสียงในสภาพแวดล้อมของคุณมีความสอดคล้องกัน เช่น เสียงสัญญาณโทรทัศน์หรือเสียงคำรามของน้ำตก หากเสียงเหล่านี้หยุดลงอย่างกะทันหัน สภาพแวดล้อมจะรู้สึกไม่สมจริง
เพื่อแสดงแนวคิดนี้ ให้ตรวจสอบว่าเสียง 3D ต่อไปนี้สำหรับน้ำตกขนาดใหญ่สองแห่งหยุดลงทันทีที่แทร็กเสียงที่ไม่วนซ้ำเสร็จสิ้น ขณะที่เสียงน้ำเริ่มต้นทำให้ผู้เล่นดื่มด่ำกับสภาพแวดล้อมกลางแจ้ง การเปลี่ยนแปลงทางเสียงอย่างกะทันหันนั้นทำให้รู้สึกสะดุดและไม่เป็นธรรมชาติในลักษณะที่น้ำตกทำงานในโลกจริง
ในทำนองเดียวกัน ตัวอย่างนี้ใช้เทคนิคนี้สำหรับน้ำตกช็อกโกแลตที่ไหล และปรับระดับเสียงตามระยะห่างของผู้เล่นจากผู้ปล่อยเสียง เมื่อผู้เล่นอยู่ห่างไม่เกิน 20 สตัด ผู้ปล่อยเสียงจะปล่อยเสียงที่ระดับเสียงเต็ม เมื่อผู้เล่นเคลื่อนที่ออกไป เสียงน้ำที่กระเพื่อมจะลดระดับเสียงลงทุก 20 สตัดจากผู้ปล่อยเสียง ซึ่งเลียนแบบเสียงในโลกจริงที่ลดระดับเสียงลงเมื่อคุณอยู่ห่างจากแหล่งเสียง
ในการสร้างเสียง 3D วนซ้ำในไฟล์ตัวอย่าง Gingerbread House - Complete Audio:
เปิดใช้งานผู้ฟังเริ่มต้นที่เชื่อมต่อกับตัวละครของผู้เล่น
- ในหน้าต่าง Explorer ให้เลือก SoundService
- ในหน้าต่าง Properties ให้ตั้งค่า DefaultListenerLocation เป็น Character เมื่อคุณรันเกม เอนจินจะสร้าง:
- วัตถุ AudioListener ภายใต้ Humanoid.RootPart ของแต่ละตัวละครผู้เล่นเพื่อให้คุณได้ยินเสียงที่เปลี่ยนแปลงในลำโพงจริงของคุณตามตำแหน่งและขนาดของแหล่งเสียงภายในเกม
- วัตถุ AudioDeviceOutput ภายใต้ SoundService
ในหน้าต่าง Explorer ให้ไปที่ Workspace ⟩ WaterfallAudioObject จากนั้น:
- แทรกวัตถุ AudioPlayer เพื่อสร้างแหล่งเสียงสำหรับน้ำตก
- แทรกวัตถุ AudioEmitter เพื่อปล่อยสตรีมตำแหน่งจาก WaterfallAudioObject
- แทรกวัตถุ 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 แทรก Script ลงใน WaterfallAudioObject เปลี่ยนชื่อเป็น LoopWaterfallMusic ตั้งค่า RunContext เป็น Client จากนั้นวางโค้ดต่อไปนี้ลงในสคริปต์:
local audioPlayer = script.ParentaudioPlayer:Play()คำอธิบายโค้ดสคริปต์เริ่มต้นโดยการประกาศตัวแปรเพื่อแทนที่พ่อแม่ของสคริปต์ AudioPlayer จากนั้นสคริปต์จะตั้งค่าแหล่งเสียงให้เล่นตั้งแต่ผู้เล่นเข้าร่วมเกมจนถึงช่วงเวลาที่พวกเขาออกจากเกม
ทดสอบเกมเพื่อฟังเสียงฝนช็อกโกแลตวนซ้ำเมื่ออวตารของคุณอยู่ใกล้น้ำตก เมื่อคุณหมุนหัวของตัวละครเพื่อมองไปในทิศทางที่แตกต่าง เสียงจะเปลี่ยนแปลงอย่างไดนามิกในลำโพงจริงของคุณตามตำแหน่งของผู้ปล่อยเสียงในพื้นที่ 3D
เสียงเล่นครั้งเดียว
เสียง 3D เล่นครั้งเดียว หรือเสียงทิศทางที่เล่นเพียงครั้งเดียวในเวลาที่เฉพาะเจาะจงและตำแหน่ง เว้นแต่ผู้เล่นจะกระตุ้นมันอีกครั้ง จะให้บริบทแก่ผู้เล่นเกี่ยวกับการกระทำของพวกเขา สภาพแวดล้อม และตัวละครใด ๆ ที่อยู่รอบตัวพวกเขา การใช้ฟีดแบ็กทางเสียงประเภทนี้ในเกมของคุณเป็นสิ่งสำคัญเพราะช่วยให้ผู้เล่นสามารถตัดสินใจเชิงกลยุทธ์ เช่น หลีกเลี่ยงศัตรูที่เข้ามาหรือเก็บไอเท็มที่มีประโยชน์
ส่วนถัดไปจะให้รายละเอียดการใช้งานสำหรับสถานการณ์การเล่นเกมทั่วไปที่ผู้เล่นต้องการฟีดแบ็กทางเสียงที่ทันท่วงทีและมีทิศทาง รวมถึงเหตุการณ์การเล่นเกมในสถานการณ์ การโต้ตอบกับวัตถุ และการสนทนาของตัวละครที่ไม่สามารถเล่นได้
ฟีดแบ็กเหตุการณ์
เมื่อผู้เล่นกระตุ้นเหตุการณ์สำคัญในสถานการณ์ภายในสภาพแวดล้อมของพวกเขา เช่น การปลดล็อกพื้นที่การเล่นเกมใหม่หรือการกระตุ้นการยิงของศัตรู สิ่งสำคัญคือพวกเขาต้องเข้าใจว่าต้องมุ่งเน้นและให้ความสนใจที่ไหนในพื้นที่ 3D หากพวกเขาไม่ได้รับฟีดแบ็กทางเสียงทันที พวกเขาอาจพลาดข้อมูลที่สำคัญต่อการเล่นเกมของพวกเขา ซึ่งนำไปสู่ความหงุดหงิดที่ไม่รู้ว่าจะไปที่ไหนหรือทำอะไรต่อไป
เพื่อแสดงให้เห็นว่าทำไมสิ่งนี้จึงสำคัญ ให้ตรวจสอบเสียง 3D เล่นครั้งเดียวจากเทมเพลต Laser Tag ที่เล่นจากปืนของผู้เล่นแต่ละคน:
- เสียงป๊อปลึก ๆ จะเล่นสำหรับทุกการยิงที่ผู้เล่นยิงจากปืนของพวกเขา
- เสียงคลิกและเสียงบี๊บแบบหุ่นยนต์จะเล่นทุกครั้งที่ผู้เล่นรีโหลดปืนด้วยรอบใหม่
เสียงทั้งสองนี้ให้การรับรู้สถานการณ์โดยการเตือนผู้เล่นที่อยู่ใกล้เคียงถึงทิศทางที่การยิงมาจาก เพื่อให้พวกเขาสามารถตัดสินใจได้อย่างมีข้อมูลว่าจะเข้าร่วมสนุกหรือหลีกเลี่ยงอันตรายที่อาจเกิดขึ้น
ตัวอย่างนี้ใช้เทคนิคเดียวกันเพื่อให้ผู้เล่นรับรู้สถานการณ์เกี่ยวกับรางวัลของพวกเขาสำหรับการทำภารกิจหลักภายในเกม หลังจากที่พวกเขาเก็บลูกอมทั้งสาม ลูกประตูบ้านขนมปังขิงจะเปิดขึ้นเพื่อให้ผู้เล่นเข้าถึงของขวัญภายใน
เนื่องจากไม่มีลำดับเฉพาะที่ผู้เล่นต้องเก็บลูกอม จึงเป็นสิ่งสำคัญที่ผู้เล่นจะต้องรับรู้ถึงการเปิดประตูไม่ว่าจะเก็บลูกอมลูกไหนเป็นลูกสุดท้าย เสียงตำแหน่งทำให้สิ่งนี้เป็นไปได้เพื่อให้ผู้เล่นรับรู้ถึงความสำเร็จของพวกเขาและที่ที่พวกเขาต้องไปต่อไปไม่ว่าจะอยู่ห่างและอยู่ในทิศทางใดจากประตู
ในการสร้างฟีดแบ็กเสียง 3D เล่นครั้งเดียวในไฟล์ตัวอย่าง Gingerbread House - Complete Audio:
ในหน้าต่าง Explorer ให้ไปที่ Workspace ⟩ Door จากนั้น:
- แทรกวัตถุ AudioPlayer เพื่อสร้างแหล่งเสียงสำหรับปริมาตร
- แทรกวัตถุ AudioEmitter เพื่อปล่อยสตรีมตำแหน่งจาก Door
- แทรกวัตถุ Wire เพื่อส่งสตรีมจากผู้เล่นเสียงไปยังผู้ปล่อยเสียง

เลือก AudioPlayer จากนั้นในหน้าต่าง Properties ตั้งค่า AssetID เป็น rbxassetid://5930776613 เพื่อเล่นแทร็กเสียงประตูเหล็กเลื่อน
เลือก 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()-- Animate the door to move downwardlocal 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 เพื่อให้สามารถอ้างอิงถึงลูกและฟังก์ชันของพวกเขาได้ จากนั้นจะเรียกใช้โมดูล Leaderboard และ PlayerData ใน ServerStorage; โมดูลเหล่านี้มีหน้าที่ในการสร้างและอัปเดตกระดานคะแนนในมุมขวาบนของหน้าจอที่ติดตามจำนวนลูกอมที่ผู้เล่นเก็บในสภาพแวดล้อม
ฟังก์ชัน updatePlayerGumdrops ของสคริปต์คือที่ที่งานส่วนใหญ่เกิดขึ้นสำหรับการกระตุ้นเสียง 3D สำหรับฟีดแบ็กเหตุการณ์ และรับสองอาร์กิวเมนต์:
- player - ผู้เล่นที่เก็บลูกอม
- updateFunction - ฟังก์ชัน callback ที่อัปเดตจำนวนลูกอมที่ผู้เล่นเก็บ
เมื่อผู้เล่นชนกับลูกอม สคริปต์จะ:
- รับค่าจำนวนลูกอมใหม่ของผู้เล่นโดยการเรียกใช้ฟังก์ชัน PlayerData.updateValue
- อัปเดตกระดานคะแนนด้วยจำนวนใหม่นี้โดยการเรียกใช้ฟังก์ชัน Leaderboard.setStat
- ตรวจสอบว่าจำนวนมากกว่าหรือเท่ากับ 3
เมื่อค่ามากกว่าหรือเท่ากับ 3 สคริปต์จะ:
- เล่นแทร็กเสียง 3D จากผู้เล่นเสียงไปยังผู้ปล่อยเสียง
- เคลื่อนที่ประตูลงไป 15 สตัดจากตำแหน่งปัจจุบัน
ส่วนที่เหลือของสคริปต์มีหน้าที่หลักในการตรวจจับสิ่งใดก็ตามที่ชนกับลูกอมว่าเป็นผู้เล่นเพื่อให้สามารถกระตุ้นเสียงที่ไม่ใช่ตำแหน่งสำหรับฟีดแบ็กการเก็บได้ สำหรับข้อมูลเพิ่มเติมเกี่ยวกับส่วนนี้ของสคริปต์ ให้ดูที่ เพิ่มเสียง 2D - ฟีดแบ็กการเล่นเกม.
ทดสอบเกมเพื่อฟังเสียงประตูเลื่อนหลังจากที่คุณเก็บลูกอมทั้งสามในสภาพแวดล้อม เมื่อคุณหมุนกล้อง เสียงจะเปลี่ยนแปลงอย่างไดนามิกในลำโพงจริงของคุณเพื่อให้คุณได้ยินตามตำแหน่งของผู้ปล่อยเสียงในพื้นที่ 3D
การโต้ตอบกับวัตถุ
เมื่อผู้เล่นมีปฏิสัมพันธ์กับวัตถุ 3D ภายในสภาพแวดล้อมของพวกเขา เช่น การเปิดสวิตช์ไฟหรือการเก็บอาวุธ สิ่งสำคัญคือต้องให้ฟีดแบ็กทันทีเพื่อให้พวกเขาเข้าใจได้อย่างชัดเจน วิธี ที่พวกเขากำลังมีปฏิสัมพันธ์กับวัตถุ การจับคู่ระหว่างฟีดแบ็กทางภาพและเสียงช่วยเสริมสร้างความสัมพันธ์ระหว่างสาเหตุและผลระหว่างการกระทำของผู้เล่นและการตอบสนองของสภาพแวดล้อม
เพื่อขยายแนวคิดนี้ มาตรวจสอบเสียง 3D เล่นครั้งเดียวจากตัวอย่าง Plant สำหรับการไหลของผู้ใช้ในการปลูกกะหล่ำปลี:
- เสียงคลิกเบา ๆ จะเล่นเมื่อผู้เล่นปลูกเมล็ด
- เสียงสาดน้ำจะเล่นเมื่อผู้เล่นรดน้ำต้นไม้ที่กำลังเติบโต
- เสียงคลิปจะเล่นเมื่อผู้เล่นเก็บต้นไม้ที่โตเต็มที่
- เสียงดังเบา ๆ จะเล่นเมื่อผู้เล่นวางกะหล่ำปลีลงในรถเข็น
เสียงทั้งหมดนี้ช่วยเสริมสร้าง การกระตุ้นความใกล้ชิด ของผู้เล่นกับการเปลี่ยนแปลงรูปแบบของวัตถุในพื้นที่ 3D สำหรับผู้เล่นที่มีความบกพร่องทางการมองเห็นซึ่งการเปลี่ยนสีหรือการเคลื่อนไหวเป็นเรื่องยากที่จะเข้าใจด้วยตนเอง การให้ฟีดแบ็กทางประสาทสัมผัสหลายรูปแบบช่วยให้การโต้ตอบกับวัตถุ 3D ของคุณยังคงเข้าถึงได้และเข้าใจได้ง่ายสำหรับผู้เล่นมากที่สุดเท่าที่จะเป็นไปได้
เพื่อให้ตัวอย่างที่แตกต่างกันเกี่ยวกับวิธีการกำหนดการโต้ตอบกับวัตถุด้วยฟีดแบ็กทางประสาทสัมผัสหลายรูปแบบ ตัวอย่างนี้ให้ฟีดแบ็กทั้งทางภาพและเสียงเมื่อผู้เล่นเหยียบปุ่ม 3D พริกขี้หนูภายในบ้านขนมปังขิง เมื่อผู้เล่นไม่ได้มีปฏิสัมพันธ์กับปุ่ม มันจะปรากฏเป็นลูกอมพริกขี้หนูทั่วไป แต่เมื่อพวกเขาเหยียบปุ่ม ตัวอย่างจะ:
- เล่นแทร็กเสียงเฉลิมฉลอง
- เปลี่ยนสีข้างของปุ่มให้เป็นสีเขียว
- เคลื่อนที่ปุ่มลงไปในพื้นดิน
จากที่นี่ คุณสามารถเชื่อมโยงการโต้ตอบนี้กับการกระทำการเล่นเกมที่ไม่ซ้ำกัน เช่น การปลดล็อกไอเท็มหรือการกระตุ้นความสามารถพิเศษ


ในการสร้างเสียง 3D เล่นครั้งเดียวสำหรับการโต้ตอบกับวัตถุในไฟล์ตัวอย่าง Gingerbread House - Complete Audio:
ในหน้าต่าง Explorer ให้ไปที่ Workspace ⟩ 3DAudioButton จากนั้น:
- แทรกวัตถุ AudioPlayer เพื่อสร้างแหล่งเสียงสำหรับปุ่ม
- แทรกวัตถุ AudioEmitter เพื่อปล่อยสตรีมตำแหน่งจาก 3DAudioButton
- แทรกวัตถุ Wire เพื่อส่งสตรีมจากผู้เล่นเสียงไปยังผู้ปล่อยเสียง

เลือก AudioPlayer จากนั้นในหน้าต่าง Properties ตั้งค่า AssetID เป็น rbxassetid://1846248593 เพื่อเล่นแทร็กเสียงเฉลิมฉลองที่มีความสุข
เลือก Wire จากนั้นในหน้าต่าง Properties,
- ตั้งค่า SourceInstance เป็น AudioPlayer ใหม่ของคุณเพื่อระบุว่าคุณต้องการให้สายส่งเสียงจากผู้เล่นเสียงนี้
- ตั้งค่า TargetInstance เป็น AudioEmitter ใหม่ของคุณเพื่อระบุว่าคุณต้องการให้สายส่งเสียงไปยังผู้ปล่อยเสียงเฉพาะนี้ภายในปุ่ม
กลับไปที่หน้าต่าง Explorer แทรก Script ลงใน 3DAudioButton เปลี่ยนชื่อเป็น 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) เป็นประโยชน์ในการชี้นำผู้เล่นไปยังจุดที่น่าสนใจในสภาพแวดล้อมของพวกเขา และเพิ่มความลึกให้กับการมีปฏิสัมพันธ์กับตัวละครอื่น ๆ ในความเป็นจริง ในเกมที่ขับเคลื่อนด้วยเรื่องราว นักออกแบบหลายคนใช้การสนทนาของตัวละครอย่างมีกลยุทธ์เพื่อสอนผู้เล่นเกี่ยวกับตัวละครของพวกเขา ตัวละครพันธมิตรและศัตรู หรือโลกเอง
ตัวอย่างทั่วไปของเทคนิคนี้รวมถึง:
- สไตล์การสนทนา เพื่อกำหนดโทนของเกมของคุณ
- การพูดคุย เพื่อสอนผู้เล่นเกี่ยวกับความสัมพันธ์ของตัวละคร
- การสนทนาของศัตรู เพื่อสารภาพแรงจูงใจหรือสถานะของพวกเขาในความสัมพันธ์กับผู้เล่น
- ตัวละครผู้เล่นพูดความคิดของพวกเขาออกมา เพื่อชี้นำผู้เล่นอย่างเบา ๆ ว่าพวกเขาควรทำอะไรต่อไป เช่น รักษาตัวเอง เคลื่อนที่ไปยังตำแหน่งอื่น หรือค้นหาไอเท็ม
- ตัวละครพันธมิตรพูดคุยกับตัวละครผู้เล่น เพื่อเปิดเผยรายละเอียดเกี่ยวกับโลกในเกม เช่น ประวัติศาสตร์ วัฒนธรรม และปัญหาสังคม
เพื่อแสดงให้เห็นว่าสิ่งนี้สามารถดูเป็นอย่างไรในทางปฏิบัติ มาตรวจสอบเสียง 3D เล่นครั้งเดียวจาก Beyond the Dark ที่เล่นเป็นระยะ ๆ เมื่อผู้เล่นอยู่ในพื้นที่ล็อบบี้หลักของสถานีอวกาศ
โดยใช้สถานีอวกาศเป็นตัวละคร คลิปการสนทนานี้ให้บริบทและเรื่องราวที่สำคัญแก่ผู้เล่นเกี่ยวกับการตั้งค่าทั้งหมด ตัวอย่างเช่น จากประโยคเดียวนี้ผู้เล่นจะได้เรียนรู้:
- พวกเขาอยู่ในอวกาศ โดยเฉพาะอย่างยิ่งในสถานีอวกาศชื่อ Kerr-Newman Deep Space Relay 14
- สภาพแวดล้อมของพวกเขาเป็นอนาคตและเป็นมิตร
- พวกเขาเป็นผู้เยี่ยมชมและน่าจะออกไปในไม่ช้า
รายละเอียดเหล่านี้รวมกันทำให้ผู้เล่นดื่มด่ำกับสภาพแวดล้อมของพวกเขา และเพิ่มความรู้สึกเร่งด่วนต่อภารกิจของพวกเขา อย่างไรก็ตาม หากผู้เล่นไม่รู้ว่าภารกิจหลักของพวกเขาคืออะไร คุณยังสามารถใช้การสนทนาของตัวละครเพื่อแจ้งผู้เล่นว่าคุณต้องการให้พวกเขาทำอะไรในเกมของคุณ
เพื่อแสดง ตัวอย่างนี้ใช้ ปริมาตร หรือพื้นที่ที่มองไม่เห็นภายในพื้นที่ 3D เพื่อกระตุ้นการสนทนาของตัวละครจากมนุษย์หิมะเพื่อชี้นำผู้เล่นให้เก็บลูกอมสามลูกเพื่อเปิดประตูบ้านของเขา ในฐานะที่เป็นสิ่งแรกที่ผู้เล่นเห็นเมื่อพวกเขาเข้าร่วมเกม ผู้เล่นมีแนวโน้มที่จะกระตุ้นการสนทนาและรู้ว่าพวกเขาต้องทำอะไรเพื่อให้ประสบความสำเร็จ

ในการสร้างเสียง 3D เล่นครั้งเดียวสำหรับการสนทนาของตัวละครในไฟล์ตัวอย่าง Gingerbread House - Complete Audio:
ในหน้าต่าง Explorer ให้ไปที่ Workspace ⟩ DialogueVolume จากนั้น:
- แทรกวัตถุ AudioPlayer เพื่อสร้างแหล่งเสียงสำหรับปริมาตร
- แทรกวัตถุ AudioEmitter เพื่อปล่อยสตรีมตำแหน่งจาก DialogueVolume
- แทรกวัตถุ 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 จะดึง ancestor แรกที่เป็น Model ซึ่งควรจะเป็นตัวละครหาก BasePart ที่ชนกับปริมาตรเป็นลูกหลานของโมเดลตัวละคร หากเป็นเช่นนั้น ฟังก์ชันจะ:
- ตั้งค่า debounce เป็น true
- เล่นและรอให้เสียงจบ
- ตั้งค่า debounce กลับเป็น false
การตั้งค่า debounce จาก false เป็น true แล้วกลับเป็น false อีกครั้งหลังจากเสียงเล่นจบเป็นรูปแบบ debounce ที่ป้องกันไม่ให้เสียงถูกกระตุ้นซ้ำ ๆ ขณะที่ผู้เล่นชนกับปริมาตรอย่างต่อเนื่อง สำหรับข้อมูลเพิ่มเติมเกี่ยวกับรูปแบบ debounce นี้ ให้ดูที่ Debounce - ตรวจจับการชน.
ทดสอบเกมเพื่อฟังการสนทนาของตัวละครที่ให้คำแนะนำเมื่อผู้เล่นของคุณสัมผัสปริมาตรรอบ ๆ มนุษย์หิมะ