النص إلى الكلام هو شكل من أشكال التكنولوجيا المساعدة التي تحول سلاسل النص إلى أصوات كلام باستخدام صوت اصطناعي. بالإضافة إلى تحسين إمكانية الوصول إلى ألعابك للاعبين ذوي الإعاقات البصرية أو الحركية أو الإدراكية، يسمح لك TTS بإنشاء الكلام ديناميكيًا حتى لا تضطر إلى تسجيل الصوت مسبقًا لجميع السيناريوهات السردية الممكنة.
باستخدام ملف Gingerbread House - Start .rbxl كنقطة انطلاق و Gingerbread House - Text-to-Speech كمرجع، يوضح لك هذا الدليل كيفية إضافة كل من صوت TTS الأساسي والواعي للسياق إلى ألعابك، بما في ذلك الإرشادات حول:
- تفعيل TTS لسيناريوهات اللعب الشائعة التي لن تتغير أبدًا، مثل تفاعلات واجهة المستخدم والدروس التعليمية.
- تكوين TTS بحيث يتكيف مع إجراءات اللاعب، أو حالة البيئة، أو الأهداف المرنة.
إذا واجهت أي صعوبة في العملية، يمكنك استخدام Gingerbread House - Text-to-Speech كمرجع لمقارنة تقدمك.
كائنات الصوت
لإنشاء صوت TTS، من المهم فهم كائنات الصوت التي ستعمل معها طوال هذا الدليل. هناك خمسة أنواع رئيسية من كائنات الصوت لـ TTS:
- كائن AudioTextToSpeech يحول سلاسل النص إلى أصوات كلام.
- كائن AudioEmitter هو مكبر صوت افتراضي يصدر الصوت في البيئة ثلاثية الأبعاد.
- كائن AudioListener هو ميكروفون افتراضي يلتقط الصوت من البيئة ثلاثية الأبعاد.
- كائن AudioDeviceOutput هو جهاز مادي في العالم الحقيقي، مثل مكبر صوت أو سماعات رأس.
- Wires تحمل تدفقات الصوت من كائن إلى آخر.
تعمل جميع هذه الكائنات الصوتية معًا لإصدار صوت TTS استجابةً لإجراءات اللاعب. دعنا نلقي نظرة على كيفية عمل ذلك في الممارسة العملية لصوت ثلاثي الأبعاد باستخدام مثال للاعب يرتدي سماعة رأس أثناء لعبه لعبة على جهاز الكمبيوتر المحمول الخاص به:
- يقوم AudioTextToSpeech بتحميل وتحويل النص إلى صوت كلما لمس اللاعب جزءًا بالقرب من شخصية غير قابلة للعب (NPC).
- يقوم AudioEmitter بإصدار تدفق صوت TTS من NPC إلى البيئة ثلاثية الأبعاد.
- يستمع كائن AudioListener الخاص بالشخصية إلى ذلك الصوت داخل البيئة ثلاثية الأبعاد ويعيده إلى سماعته.
- تحمل كائن AudioDeviceOutput الصوت من AudioListener إلى مكبر الصوت الفعلي للاعب، أو في هذه الحالة، سماعات الرأس الخاصة به.
تتناول الأقسام التالية بعمق وتشير إلى هذه الكائنات أثناء تعلمك كيفية تشغيل الصوت الأساسي والواعي للسياق. أثناء مراجعتك لهذه الكائنات مع التقنيات القادمة، يمكنك التنبؤ بدقة بكيفية التقاط الصوت وإعادته من اللعبة إلى اللاعب.
TTS الأساسي
TTS الأساسي هو الشكل الأكثر شيوعًا من النص إلى الكلام حيث يقرأ الصوت الاصطناعي سلسلة نصية بغض النظر عن سياق اللاعب أو البيئة. هذا يعني أنه كلما قام اللاعب بتفعيل صوت TTS، تظل الكلمات والطريقة التي يقرأ بها الصوت الاصطناعي الكلمات متسقة بغض النظر عن حالة اللاعب أو أفعاله أو حالة البيئة.
هذا الشكل من TTS مفيد في معظم سيناريوهات اللعب، مثل تفاعل اللاعبين مع قوائم واجهة المستخدم، والدروس التعليمية، أو التفاعلات الروتينية مع NPC مثل عروض البائعين أو نباح الأعداء. توفر Roblox الأنواع التالية من الأصوات التي يمكنك تجربتها لأي من هذه التفاعلات:
| VoiceID | وصف الصوت | مثال صوتي |
|---|---|---|
| 1 | ذكر بريطاني | |
| 2 | أنثى بريطانية | |
| 3 | ذكر أمريكي #1 | |
| 4 | أنثى أمريكية #1 | |
| 5 | ذكر أمريكي #2 | |
| 6 | أنثى أمريكية #2 | |
| 7 | ذكر أسترالي | |
| 8 | أنثى أسترالية | |
| 9 | صوت قديم #1 | |
| 10 | صوت قديم #2 | |
| 11 | صوت المضيف | |
| 101 | ذكر إسباني | |
| 102 | أنثى إسبانية | |
| 201 | ذكر ألماني | |
| 202 | أنثى ألمانية | |
| 301 | ذكر إيطالي | |
| 302 | أنثى إيطالية | |
| 401 | ذكر فرنسي | |
| 402 | أنثى فرنسية |
لإعادة إنشاء صوت TTS ثلاثي الأبعاد الأساسي في ملف Gingerbread House - Text-to-Speech النموذجي:
- قم بتمكين مستمع افتراضي متصل بشخصية اللاعب الخاصة بك.
- في نافذة Explorer، حدد SoundService.
- في نافذة Properties، قم بتعيين DefaultListenerLocation إلى Character. عند تشغيل اللعبة، يقوم المحرك تلقائيًا:
- بإنشاء AudioListener تحت Humanoid.RootPart لكل شخصية لاعب حتى تتمكن من سماع الأصوات تتغير في مكبرات الصوت الخاصة بك في العالم الحقيقي وفقًا لموقع ومقياس مصادر الصوت داخل اللعبة.
- بإنشاء AudioDeviceOutput تحت SoundService.
- في نافذة Explorer، انتقل إلى Workspace ⟩ DialogueVolume، ثم:
- أدخل كائن AudioTextToSpeech لإنشاء مولد صوتي للكلام للمنطقة المحيطة بالرجل الثلجي.
- أدخل كائن AudioEmitter لإصدار تدفق موضعي من DialogueVolume.
- أدخل كائن Wire لنقل التدفق من مولد الصوت إلى مكبر الصوت.
- حدد كائن AudioTextToSpeech، ثم في نافذة Properties:
- قم بتعيين Text إلى "اجمع كل حبة جومدروب أخيرة لفتح منزلي!"
- قم بتعيين VoiceId إلى 2 لتعيين الصوت الاصطناعي لمحاكاة أنثى بريطانية.
- قم بتعيين Volume إلى 3 لتشغيل الصوت بمستوى عالٍ حتى تسمع صوت TTS فوق مصادر الصوت الأخرى داخل اللعبة.
- حدد Wire، ثم في نافذة Properties:
- قم بتعيين SourceInstance إلى AudioTextToSpeech الجديد الخاص بك لتحديد أنك تريد أن تحمل السلك الصوت من مولد الصوت هذا.
- قم بتعيين TargetInstance إلى AudioEmitter الجديد الخاص بك لتحديد أنك تريد أن يحمل السلك الصوت إلى مكبر الصوت هذا داخل المنطقة.
- مرة أخرى في نافذة Explorer، انتقل إلى StarterPlayer ⟩ StarterCharacterScripts، ثم أدخل LocalScript، وأعد تسميته إلى PlayBasicTTSAudioWhenInVolume، والصق الكود التالي في البرنامج النصي المحلي:
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local humanoid = script.Parent:WaitForChild("Humanoid")
local volumeDetector = Workspace.DialogueVolume
local trigger = humanoid:WaitForChild("Animator")
local debounce = false
local localPlayer = Players.LocalPlayer
volumeDetector.Touched:Connect(function(hit)
if debounce then
return
end
local hitCharacter = hit:FindFirstAncestorWhichIsA("Model")
local hitPlayer = Players:GetPlayerFromCharacter(hitCharacter)
if hitPlayer ~= localPlayer then
return
end
debounce = true
local audioTextToSpeech = Workspace.DialogueVolume.AudioTextToSpeech
audioTextToSpeech:Play()
audioTextToSpeech.Ended:Wait()
debounce = false
end)يبدأ هذا البرنامج النصي بالحصول على خدمات Workspace و Players حتى يتمكن من الإشارة إلى أطفالهم ووظائفهم. لكل شخصية لاعب يتم تحميلها أو إعادة ظهورها في اللعبة، ينتظر البرنامج النصي:
- كائن الحجم في مساحة العمل المسمى DialogueVolume.
عندما يتصادم أي شيء مع الحجم، تقوم وظيفة معالج الحدث Touched بالحصول على أول سلف يكون Model، والذي يجب أن يكون الشخصية إذا كان BasePart الذي تصادم مع الحجم هو تابع لنموذج شخصية. إذا كان الأمر كذلك، تقوم الوظيفة بعد ذلك:
- تعيين debounce إلى true.
- تشغيل وانتظار انتهاء صوت TTS.
- تعيين debounce مرة أخرى إلى false.
يعد تعيين debounce من false إلى true ثم إلى false مرة أخرى بعد انتهاء تشغيل صوت TTS الأساسي نمط debounce يمنع الصوت من التفعيل بشكل متكرر حيث يتصادم اللاعبون باستمرار مع الحجم. لمزيد من المعلومات حول نمط debounce هذا، راجع Debounce - Detect collisions.
اختبر اللعبة لسماع حوار الشخصية التعليمية عندما تلمس شخصية اللاعب الخاصة بك الحجم حول الرجل الثلجي.
يمكنك تجربة هذا الصوت بشكل أكبر عن طريق تعديل خصائص Text و VoiceID و Pitch و Speed إلى قيم جديدة. يصبح الكلام الناتج مختلفًا تمامًا دون الحاجة إلى تسجيل وتحميل ملف صوتي جديد لكل سيناريو.
TTS الواعي للسياق
TTS الواعي للسياق هو شكل أكثر تقدمًا من النص إلى الكلام حيث يقرأ الصوت الاصطناعي سلسلة نصية بالنسبة للاعب، أو حالة بيئته، أو حالة اللعب. هذا يعني أنه كلما قام اللاعب بتفعيل صوت TTS، تتكيف الكلمات والطريقة التي يقرأ بها الصوت الاصطناعي الكلمات وفقًا لذلك.
هذا الشكل من TTS مفيد لسيناريوهات اللعب التي تتغير باستمرار، مثل إشارات الصوت الاتجاهية، أو حالة الأهداف، أو التفاعلات الفريدة مع NPC. وبالتالي، نظرًا لأن TTS الواعي للسياق يحتاج إلى التحول ليكون دقيقًا، يجب عليك تكوين عناصر اللعب بحيث يمكنك تتبع حالتها بينما يتنقل اللاعبون عبر البيئة ويكملون أهداف اللعب.
بينما هناك العديد من الطرق لإنجاز هذه المهمة، يستخدم المثال سمات مخصصة لتتبع اللون و الموقع لكل حبة جومدروب يجب على اللاعب جمعها للدخول إلى منزل الزنجبيل. لمزيد من المعلومات حول السمات، راجع الخصائص والسمات.



لإعادة إنشاء صوت TTS ثلاثي الأبعاد الواعي للسياق في ملف Gingerbread House - Text-to-Speech النموذجي:
في نافذة Explorer، انتقل إلى Workspace ⟩ GumDrops.
قم بتكوين ثلاث سمات مخصصة لتتبع حبة الجومدروب الصفراء.
- حدد حبة الجومدروب الصفراء، ثم في نافذة Properties، انتقل إلى قسم Attributes، ثم انقر على أيقونة الزائد. تظهر نافذة منبثقة.
- في حقل Name، أدخل ColorDescription.
- في قائمة Type المنسدلة، اختر string.
- انقر على زر Save.
- قم بتعيين السمة الجديدة ColorDescription إلى yellow.
- باستخدام هذه العملية، أنشئ سمتين أخريين باستخدام القيم التالية.
الاسم النوع القيمة HintOrder number 0 LocationDescription string بجانب الشلال قم بتكوين ثلاث سمات مخصصة لتتبع حبة الجومدروب الخضراء.
- في نافذة Explorer، حدد حبة الجومدروب الخضراء.
- في نافذة Properties، أنشئ ثلاث سمات باستخدام القيم التالية.
الاسم النوع القيمة ColorDescription string green HintOrder number 1 LocationDescription string على الحافة قم بتكوين ثلاث سمات مخصصة لتتبع حبة الجومدروب الحمراء.
- في نافذة Explorer، حدد حبة الجومدروب الحمراء.
- في نافذة Properties، أنشئ ثلاث سمات باستخدام القيم التالية.
الاسم النوع القيمة ColorDescription string red HintOrder number 2 LocationDescription string خلف السياج في نافذة Explorer، انتقل إلى Workspace ⟩ HintVolume، ثم:
- أدخل كائن AudioTextToSpeech لإنشاء مولد صوتي للكلام للمنطقة المحيطة بالرنة.
- أدخل كائن AudioEmitter لإصدار تدفق موضعي من HintVolume.
- أدخل كائن Wire لنقل التدفق من مولد الصوت إلى مكبر الصوت.
حدد Wire، ثم في نافذة Properties:
- قم بتعيين SourceInstance إلى AudioTextToSpeech الجديد الخاص بك لتحديد أنك تريد أن يحمل السلك الصوت من مولد الصوت هذا.
- قم بتعيين TargetInstance إلى AudioEmitter الجديد الخاص بك لتحديد أنك تريد أن يحمل السلك الصوت إلى مكبر الصوت هذا داخل المنطقة.
مرة أخرى في نافذة Explorer، انتقل إلى StarterPlayer ⟩ StarterCharacterScripts، ثم أدخل LocalScript، وأعد تسميته إلى PlayContextTTSAudioWhenInVolume، والصق الكود التالي في البرنامج النصي المحلي:
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local humanoid = script.Parent:WaitForChild("Humanoid")
local volumeDetector = Workspace.HintVolume
local trigger = humanoid:WaitForChild("Animator")
local debounce = false
local localPlayer = Players.LocalPlayer
function getRemainingGumdrops(): {Part}
local gumdropsFolder = Workspace.Gumdrops
local gumdrops = gumdropsFolder:GetChildren()
local remainingGumdrops = {};
for _, gumdrop in gumdrops do
if gumdrop:GetAttribute("Active") then
remainingGumdrops[#remainingGumdrops + 1] = gumdrop
end
end
table.sort(remainingGumdrops, function(a, b)
return a:GetAttribute("HintOrder") < b:GetAttribute("HintOrder")
end)
return remainingGumdrops
end
function getReindeerHint(remainingGumdrops: {Part}): string
local remainingGumdrops = getRemainingGumdrops()
if (#remainingGumdrops == 0) then
return "لا توجد حبات جومدروب متبقية. تحقق داخل المنزل."
end
local nextGumdrop = remainingGumdrops[1]
local colorDescription = nextGumdrop:GetAttribute("ColorDescription")
local locationDescription = nextGumdrop:GetAttribute("LocationDescription")
local message = #remainingGumdrops > 1
and "يوجد " .. #remainingGumdrops .. " حبات جومدروب متبقية. ابحث عن " .. colorDescription .. " في " .. locationDescription .. "."
or "يوجد حبة جومدروب واحدة متبقية. إنها " .. colorDescription .. " وهي في " .. locationDescription .. "."
return message
end
volumeDetector.Touched:Connect(function(hit)
if debounce then
return
end
local hitCharacter = hit:FindFirstAncestorWhichIsA("Model")
local hitPlayer = Players:GetPlayerFromCharacter(hitCharacter)
if hitPlayer ~= localPlayer then
return
end
print("اللاعب لمس الحجم.")
debounce = true
local remainingGumdrops = getRemainingGumdrops()
local message = getReindeerHint(remainingGumdrops)
local audioTextToSpeech = Workspace.HintVolume.AudioTextToSpeech
audioTextToSpeech.Text = message
audioTextToSpeech:Play()
audioTextToSpeech.Ended:Wait()
debounce = false
end)يبدأ هذا البرنامج النصي بالحصول على خدمات Workspace و Players حتى يتمكن من الإشارة إلى أطفالهم ووظائفهم. لكل شخصية لاعب يتم تحميلها أو إعادة ظهورها في اللعبة، ينتظر البرنامج النصي:
- كائن الحجم في مساحة العمل المسمى HintVolume.
تقوم وظيفة getRemainingGumdrops() في البرنامج النصي بإرجاع قائمة من كائنات الجومدروب Part داخل مجلد Gumdrops وتصفية أي جزء جمعه اللاعب. يتم فرز حبات الجومدروب المتبقية بترتيب محدد وفقًا لسمات HintOrder لكل حبة جومدروب.
تأخذ وظيفة getReindeerHint(remainingGumdrops) في البرنامج النصي تلك القائمة من getRemainingGumdrops() وتعيد رسالة نصية تصف أين يمكن للاعب العثور على أي حبات جومدروب متبقية، بما في ذلك كل من وصف اللون ووصف الموقع لحبة الجومدروب التالية التي يحتاج اللاعب لجمعها. ومع ذلك، إذا كان اللاعب قد جمع جميع حبات الجومدروب في البيئة، تصف رسالة النص أين يجب أن يذهب بعد جمع جميع حبات الجومدروب في البيئة.
عندما يتصادم أي شيء مع الحجم، تقوم وظيفة معالج الحدث Touched بالحصول على أول سلف يكون Model، والذي يجب أن يكون الشخصية إذا كان BasePart الذي تصادم مع الحجم هو تابع لنموذج شخصية. إذا كان الأمر كذلك، تقوم الوظيفة بعد ذلك:
- تعيين debounce إلى true.
- الحصول على قائمة حبات الجومدروب المتبقية ورسالة النص التي تصف حبة الجومدروب التالية التي يحتاج اللاعب للعثور عليها.
- تحويل النص إلى صوت باستخدام كائن AudioTextToSpeech، وتشغيل الصوت، وانتظار انتهاء الصوت.
- تعيين debounce مرة أخرى إلى false.
يعد تعيين debounce من false إلى true ثم إلى false مرة أخرى بعد انتهاء تشغيل صوت TTS الواعي للسياق نمط debounce يمنع الصوت من التفعيل بشكل متكرر حيث يتصادم اللاعبون باستمرار مع الحجم. لمزيد من المعلومات حول نمط debounce هذا، راجع Debounce - Detect collisions.
اختبر اللعبة لسماع تلميحات سياقية عندما تلمس شخصية اللاعب الخاصة بك الحجم حول الرنة. يتغير صوت TTS وفقًا لعدد وألوان حبات الجومدروب التي وجدتها شخصية اللاعب بالفعل في البيئة.