التطوير / ROBLOX
زر مساعدة في Roblox Studio للحاسوب والهاتف ويد التحكم
أنشئ لوحة محلية مستقلة مع منطقة آمنة وAnchorPoint والتفاف نص طويل وعودة واضحة. خصائص دقيقة وLocalScript أصلي وخطة اختبار بلا نتائج مختلقة.
مساعدة صغيرة تفتح وتغلق بوضوح #
تخيل مشروع تدريب منفصلاً: يرى اللاعب المشهد وزراً صغيراً بعنوان «مساعدة». يفتح التفعيل شرحاً، ويعيد «إغلاق» رؤية المشهد. هذه واجهة على الشاشة وليست إرشاداً مرتبطاً بعنصر في العالم. لا تحتاج إلى ProximityPrompt أو مكافأة خادم أو فحص شراء. نغير الظهور المحلي وموضع القراءة فقط.
لا يعدل التمرين ألعاب مؤلف الموقع الخمس. ابنِ البنية في مشروع Studio مستقل. اكتب أولاً ثلاث نتائج متوقعة: تفتح المساعدة، ويصل القارئ إلى نهاية النص، ويمكن الإغلاق بكل إدخال تدعمه. مستطيل جميل على شاشة كبيرة لا يثبت هذه الشروط. الأبعاد التالية نقطة بداية، وتبقى الملاحظات الفعلية لتسجلها بنفسك. يجب الفصل بين التصميم المقصود وتجربة أجهزة لم تنفذ بعد.
1. ابنِ التسلسل بأسماء دقيقة #
أنشئ ScreenGui باسم HelpGui داخل StarterGui. أضف TextButton باسم HelpButton وFrame باسم HelpPanel وLocalScript عادياً باسم HelpController. يحتوي HelpButton على UISizeConstraint باسم ButtonBounds. يحتوي HelpPanel على UISizeConstraint باسم PanelBounds وUIPadding باسم PanelPadding وTextLabel باسم Title وScrollingFrame باسم Body وثلاثة TextButton: ScrollUp وScrollDown وCloseButton. ضع TextLabel باسم HelpText داخل Body.
لا تترجم أسماء العناصر مع العبارات المرئية. يبحث الكود عن HelpPanel وBody لا عنصر مشابه الاسم. StarterGui قالب البداية، وفي تشغيل اللاعب تظهر الواجهة في PlayerGui الخاص به. لذلك لا تكفي شجرة التحرير وحدها. إذا انتظر WaitForChild، قارن الاسم والأب قبل تغيير الأبعاد أو استبدال الحدث. الاسم الخاطئ ليس مشكلة حجم الخط.
2. اترك مكاناً لواجهة النظام #
اضبط HelpGui على ScreenInsets=CoreUISafeInsets وClipToDeviceSafeArea=true وأبقِ Enabled=true. يحافظ ResetOnSpawn=false على هذه الواجهة عند إعادة ظهور الشخصية في التمرين؛ لا يحفظ تقدم الزيارات. تراعي المنطقة الآمنة الحالية واجهة Roblox الأساسية ومناطق الجهاز. لا تبدأ بنصيحة عامة IgnoreGuiInset=true: إنها تغير سلوك الهوامش ولا تصلح كل تركيب.
لا تعرف المنطقة الآمنة موضع مؤقتك أو خريطتك أو متجرك، ولا تفصل جميع عناصر الشاشة آلياً. ابدأ دون HUD خاصة ثم افحص الجيران الحقيقيين لواجهتك المقبلة. إذا غطى ScreenGui آخر الزر فافحص ترتيب العرض والطبقات. تصغير الحروف لا يزيل تراكباً آخر. افهم مصدر المشكلة قبل تغيير عدة خصائص معاً، وإلا يصعب تفسير ما تحسن ولماذا.
3. لماذا تقع المساعدة أعلى المنتصف #
استخدم HelpButton.AnchorPoint=(0.5,0) وPosition=(0.5,0,0,12) وSize=(0.28,0,0,44). اضبط ButtonBounds.MinSize=(96,44) وMaxSize=(160,44). هذه بداية داخل منطقة HelpGui لا أبعاد مثالية لكل شاشة. يتبع الإحداثي الأفقي منتصف الحاوية، بينما الفراغ العلوي إضافة بكسلات.
نبعد المساعدة العرضية عن منطقتي الحركة والقفز السفليتين في اللمس. قد يكون الوصول للأعلى مراراً مزعجاً خصوصاً على جهاز لوحي؛ لذلك هذا شرح يقرأ أحياناً لا زر قتال جديد. افحص عدادك العلوي والدردشة أيضاً. إذا احتاج اللاعب فتحها باستمرار، راجع الموضع بملاحظات من جهاز حقيقي مع إبقاء الحركة متاحة. وجود الزر داخل المنطقة الآمنة لا يثبت راحة الإبهام؛ وظيفة الزر تحدد ما ينبغي اختباره.
4. حدد اللوحة دون تمديد غير محدود #
اضبط HelpPanel على AnchorPoint=(0.5,0.5) وPosition=(0.5,0,0.5,0) وSize=(0.88,0,0.86,0) وVisible=false. يستخدم PanelBounds القيم MaxSize=(520,420) وMinSize=(0,0). يوفر PanelPadding اثني عشر بكسلاً بكل جانب. Scale جزء من الحاوية وOffset إضافة بكسلات؛ الأعداد الأربعة في UDim2 ليست أربعة إحداثيات شاشة مطلقة.
يثبت الارتكاز الأوسط المركز عند تغير الأبعاد. يمنع الحد الأقصى للعرض تحول شرح قصير إلى شريط ضخم على الحاسوب. تضيق اللوحة على شاشة صغيرة، فتحتاج محتوياتها لفحص منفصل. يحدد الجدول خصائص البداية لبقية العناصر. إذا لم تكفِ المساحة للرأس والأزرار فغير التركيب. لا يضمن قيد الحجم أو النسب واجهة صالحة في كل نافذة يمكن تخيلها.
| خصائص العنصر | قيم بداية التمرين |
|---|---|
| HelpGui · ScreenGui | ScreenInsets=CoreUISafeInsets; ClipToDeviceSafeArea=true; Enabled=true; ResetOnSpawn=false; DisplayOrder=10; ZIndexBehavior=Sibling |
| HelpButton · TextButton | AnchorPoint=(0.5,0); Position=(0.5,0,0,12); Size=(0.28,0,0,44); Visible=true; Active=true; Selectable=true; ZIndex=2; TextSize=20; TextScaled=false; TextWrapped=true |
| ButtonBounds · UISizeConstraint | MinSize=(96,44); MaxSize=(160,44) |
| HelpPanel · Frame | AnchorPoint=(0.5,0.5); Position=(0.5,0,0.5,0); Size=(0.88,0,0.86,0); Visible=false; Active=false; Selectable=false; ZIndex=2; BackgroundColor3=(20,30,44); BackgroundTransparency=0; BorderSizePixel=0 |
| PanelBounds · UISizeConstraint | MinSize=(0,0); MaxSize=(520,420) |
| PanelPadding · UIPadding | PaddingLeft / Right / Top / Bottom = (0,12) |
| Title · TextLabel | Position=(0,0,0,0); Size=(1,0,0,28); TextSize=22; TextScaled=false; TextWrapped=false; BackgroundTransparency=1; Active=false; Selectable=false; ZIndex=3 |
| Body · ScrollingFrame | Position=(0,0,0,40); Size=(1,0,1,-96); CanvasSize=(0,0,0,0); AutomaticCanvasSize=Y; ScrollingDirection=Y; ScrollingEnabled=true; ScrollBarThickness=6; BackgroundTransparency=1; BorderSizePixel=0; Active=true; Selectable=false; ClipsDescendants=true; ZIndex=3 |
| HelpText · TextLabel | Position=(0,0,0,0); Size=(1,-12,0,0); AutomaticSize=Y; TextSize=18; TextWrapped=true; TextScaled=false; TextYAlignment=Top; BackgroundTransparency=1; Active=false; Selectable=false; ZIndex=4 |
| ScrollUp / ScrollDown / CloseButton · TextButton | AnchorPoint=(0,1); Position: (0,0,1,0) / (0.25,0,1,0) / (0.5,0,1,0); Size: (0.25,-6,0,40) / (0.25,-6,0,40) / (0.5,-6,0,40); Visible=true; Active=true; Selectable=true; TextSize=18; TextScaled=false; TextWrapped=true; ZIndex=3 |
| * | UDim2 = (XScale,XOffset,YScale,YOffset); AnchorPoint=Vector2(X,Y). Title/Body/HelpText: AnchorPoint=(0,0); Visible=true. |
| * | HelpButton/ScrollUp/ScrollDown/CloseButton: BackgroundColor3=(230,120,65); BackgroundTransparency=0; TextColor3=(20,25,30); BorderSizePixel=0; AutoButtonColor=true. |
| * | Title/HelpText: TextColor3=(245,247,250). Title.TextXAlignment=Center. HelpText.TextXAlignment=Right. HelpController.Enabled=true. |
5. افصل النص المقروء عن نافذة القراءة #
استخدم HelpText.TextWrapped=true وTextScaled=false وTextSize=18 وAutomaticSize=Y. يتبع العرض Body ويزيد الارتفاع بالنص. يستخدم Body القيم AutomaticCanvasSize=Y وCanvasSize=(0,0,0,0) وScrollingDirection=Y وScrollingEnabled=true. تبقى النافذة محدودة ويجوز أن يتجاوزها المحتوى ارتفاعاً. يوفر أعلى وأسفل طريقاً إضافياً لنص طويل.
لا تصغر فقرة كاملة حتى تصبح حروفاً بالكاد ترى. حسّن التعليمات أولاً: فعل واحد ونتيجة متوقعة وطريق عودة، ثم جرب نسخة تدريب أطول عمداً. لا ينشئ الكود مهمة حقيقية؛ استبدل النص بمحتواك. أبقِ أسماء الأزرار والعنوان قصيرة. التفاف الجسم لا يصلح زرّاً آخر متجاوز الحدود، وظهور البداية لا يثبت إمكانية الوصول للجملة الأخيرة. تحرك فعلاً إلى النهاية أثناء الفحص.
6. اختر لغة هذا المثال المحلي #
يقبل UI_LANGUAGE القيم ru وen وde وes وzh وar؛ اختر "ar" مثلاً. يغير القاموس العبارات المرئية، وتظل HelpController وCloseButton أسماء عناصر. يبقي AutoLocalize=false السلاسل المختارة واضحة. هذا اختيار لغة للتمرين في العميل، لا نظاماً كاملاً يختار لغة كل لاعب آلياً في لعبة منشورة.
يحاذى الجسم العربي إلى اليمين. يظل النص المختلط والأرقام والعلامات والتفاف الأسطر بحاجة لفحص بصري. قد يكشف Schließen وشرح ألماني أطول مشكلة لا يظهرها Close القصير. افحص اللغات الست بنافذة ضيقة. لا توسع زراً حتى يختفي جاره. في التوطين الحقيقي حافظ على معنى الفعل وافحص الخط واستخدم نظام ترجمة مستقل؛ يسهل القاموس التعلم لكنه لا يستبدل ذلك العمل.
7. صل LocalScript واحداً #
ضع المثال الأصلي في HelpController. يجد العناصر المعدة ويختار العبارات ويرتب الاختيار ويربط Activated. يغير setOpen القيم HelpPanel.Visible وHelpButton.Visible. تخفي اللوحة المفتوحة زر فتحها ويعيده الإغلاق. لا يوجد RemoteEvent أو طلب خادم أو كتابة DataStore.
فُعل GuiNavigationEnabled وAutoSelectGuiEnabled صراحة لهذا المشروع المستقل. يؤثران عموماً في تنقل العميل؛ يجب تنسيقهما مع القوائم الموجودة في لعبة فعلية. لا تضف نسخة معالج ثانية لإصلاح اسم خاطئ. لا توقف اللوحة الشخصية ولا تعلق لعبة الخادم. تتطلب قائمة تحجب الحركة سلوكاً وفحصاً آخرين. أبقِ النتيجة الأولى صغيرة بما يكفي لفهمها من الكود قبل توسيع المظهر، دون تحويل شرح بسيط إلى نظام قوائم كامل.
local GuiService = game:GetService("GuiService")
local gui = script.Parent
local help = gui:WaitForChild("HelpButton")
local panel = gui:WaitForChild("HelpPanel")
local title = panel:WaitForChild("Title")
local body = panel:WaitForChild("Body")
local bodyText = body:WaitForChild("HelpText")
local up = panel:WaitForChild("ScrollUp")
local down = panel:WaitForChild("ScrollDown")
local close = panel:WaitForChild("CloseButton")
local UI_LANGUAGE = "en" -- One chosen language for this local exercise.
local labels = {
ru = {help="Помощь", title="Подсказка", up="Выше", down="Ниже", close="Закрыть", body="Это учебная панель. Прочитай подсказку и закрой её, чтобы снова видеть сцену. Здесь можно объяснить одно действие: что выбрать, какой результат ожидать и куда вернуться.\n\nЕсли текст не помещается, используй кнопки Выше и Ниже. Закрытие панели не завершает задание и не выдаёт награду."},
en = {help="Help", title="Quick help", up="Up", down="Down", close="Close", body="This is a practice panel. Read the hint and close it to see the scene again. Explain one action here: what to select, which result to expect and where to return.\n\nIf the text does not fit, use Up and Down. Closing the panel does not complete a task or grant a reward."},
de = {help="Hilfe", title="Kurze Hilfe", up="Hoch", down="Runter", close="Schließen", body="Dies ist ein Übungsfenster. Lies den Hinweis und schließe es, um die Szene wieder zu sehen. Erkläre hier eine Handlung: was auszuwählen ist, welches Ergebnis erwartet wird und wohin man zurückkehrt.\n\nWenn der Text nicht passt, nutze Hoch und Runter. Das Schließen erfüllt keine Aufgabe und vergibt keine Belohnung."},
es = {help="Ayuda", title="Ayuda breve", up="Arriba", down="Abajo", close="Cerrar", body="Este es un panel de práctica. Lee la indicación y ciérralo para volver a ver la escena. Explica una acción: qué seleccionar, qué resultado esperar y adónde regresar.\n\nSi el texto no cabe, usa Arriba y Abajo. Cerrar el panel no completa una misión ni entrega una recompensa."},
zh = {help="帮助", title="简短提示", up="上翻", down="下翻", close="关闭", body="这是练习面板。读完提示后关闭它,再次查看场景。这里可以解释一个动作:选择什么、预期结果是什么,以及之后回到哪里。\n\n如果文字显示不全,请使用上翻和下翻按钮。关闭面板不会完成任务,也不会发放奖励。"},
ar = {help="مساعدة", title="إرشاد قصير", up="أعلى", down="أسفل", close="إغلاق", body="هذه لوحة تدريب. اقرأ الإرشاد ثم أغلقها لرؤية المشهد مجدداً. اشرح فعلاً واحداً: ماذا يختار اللاعب، وما النتيجة المتوقعة، وإلى أين يعود.\n\nإذا لم يظهر النص كله، استخدم أعلى وأسفل. إغلاق اللوحة لا يكمل مهمة ولا يمنح مكافأة."},
}
local words = assert(labels[UI_LANGUAGE], "Unknown UI_LANGUAGE")
for object, key in {[help]="help", [title]="title", [up]="up", [down]="down", [close]="close", [bodyText]="body"} do
object.AutoLocalize = false
object.Text = words[key]
end
bodyText.TextXAlignment = UI_LANGUAGE == "ar" and Enum.TextXAlignment.Right or Enum.TextXAlignment.Left
GuiService.GuiNavigationEnabled = true
GuiService.AutoSelectGuiEnabled = true
help.SelectionOrder = 1
up.SelectionOrder = 2
down.SelectionOrder = 3
close.SelectionOrder = 4
up.NextSelectionRight = down
down.NextSelectionLeft = up
down.NextSelectionRight = close
close.NextSelectionLeft = down
panel.Visible = false
help.Visible = true
local function fromGamepad(input)
return input ~= nil and input.UserInputType.Name:match("^Gamepad") ~= nil
end
local function setOpen(open, controller)
local selected = GuiService.SelectedObject
panel.Visible = open
help.Visible = not open
if controller then
GuiService.SelectedObject = open and close or help
elseif selected == help or selected == up or selected == down or selected == close then
GuiService.SelectedObject = nil
end
end
local function scrollPage(direction)
local height = body.AbsoluteWindowSize.Y
local limit = math.max(0, body.AbsoluteCanvasSize.Y - height)
local nextY = math.clamp(body.CanvasPosition.Y + direction * height * 0.8, 0, limit)
body.CanvasPosition = Vector2.new(0, nextY)
end
help.Activated:Connect(function(input) setOpen(true, fromGamepad(input)) end)
close.Activated:Connect(function(input) setOpen(false, fromGamepad(input)) end)
up.Activated:Connect(function() scrollPage(-1) end)
down.Activated:Connect(function() scrollPage(1) end)8. يحتاج Activated طريقاً إلى الزر #
يدعم Activated النقر واللمس وتفعيل زر GUI مختار بيد التحكم. ادخل التنقل عبر Select، وابحث عن مساعدة المميزة، ثم اضغط A وأفلتها. لا يعد ضغط A بلا GUI مختار بفتح شيء. تحتاج الأزرار الأربعة إلى Selectable=true؛ ينبغي ألا تأخذ الخلفية والنص الاختيار.
عند الفتح بيد التحكم يختار الكود CloseButton. يتحرك اليسار إلى ScrollDown ثم ScrollUp واليمين يعيد المسار. يعيد الإغلاق باليد الاختيار إلى HelpButton. لا ينشئ الفأر أو اللمس تركيز يد جديداً؛ يمسح اختياراً سابقاً لأزرارنا عند تغيير اللوحة بهما. لا ينبغي أن تحصل قوائم أخرى على تركيز جديد بسبب نقر مساعدة عادي. هذه منطقية المثال وما زالت تحتاج إلى إدخال حقيقي؛ الرسم على الموقع لا يثبت صحة التمييز والتنقل بالمحرك.
9. افهم زري القراءة #
يقيس scrollPage ارتفاع المنطقة المرئية ويحرك CanvasPosition بنحو ثمانين في المئة منه. يساعد الجزء المتداخل على العثور على الاستمرار. يقيد الموضع بين الصفر وارتفاع المحتوى ناقص ارتفاع النافذة. إذا لم يلزم التمرير فالحد صفر. ينبغي ألا تدفع التفعيلات المتكررة النص خلف نهايته.
يبقى التمرير محلياً ولا يغير النص أو حالة مهمة. لا نعد بأن أي عصا تمرر ScrollingFrame مختاراً آلياً؛ تقدم الأزرار طريق اختيار واضحاً. افحص أيضاً عجلة الفأر والسحب داخل المنطقة على الهاتف. يحتفظ الإغلاق بموضع القراءة لأن الكود لا يعيد CanvasPosition كل مرة. إن أردت البداية دائماً فأضف ذلك كقاعدة واعية. تغير الظهور وحده لا يعني وجوب تصفير موضع المحتوى أو يحدد توقع القارئ.
10. حاكِ أولاً ثم افحص شاشة حقيقية #
ابدأ Test/F5 مع لاعب في Studio. لا يستبدل Run/F8 دون شخصية فحص PlayerGui أثناء اللعب. يساعد Device Simulator على الأبعاد والاتجاهات، وController Emulator على فحص تنقل مبكر. قد تترجم أسماء القوائم. قارن عرضاً ضيقاً وواسعاً، واتجاهاً عمودياً وأفقياً، ونصاً قصيراً وطويلاً، وحالتي الفتح والإغلاق.
افحص بعدها هاتفاً ويد تحكم مادية موصولة عادة. امشِ واقفز باللمس والمساعدة مغلقة؛ يجب ألا تغطي عناصر التحكم الزر. افتح اللوحة واعثر على إغلاق دون بحث بالأركان. لا يقيس المحاكي راحة إبهامك على جهازك ولا أداء الهاتف الحقيقي. الجدول التالي خطة غير معبأة؛ لا تقدم توقعاً باعتباره ملاحظة من اختبار لعب منجز. سجل النسخة والجهاز والظاهرة الفعلية لتسهيل إعادة الفحص.
| السيناريو | المتوقع | الجهاز / النسخة / الملاحظة |
|---|---|---|
| حاسوب، نقر فتح وإغلاق | يتغير الظهور دون إنشاء اختيار GUI جديد | — |
| هاتف ضيق بالاتجاهين | مساعدة وإغلاق متاحان والتحكم غير مغطى | — |
| كل لغة ونص طويل | آخر سطر متاح والأزرار المجاورة ظاهرة | — |
| Select ثم Help مختار ثم A | يفتح ويختار Close؛ اليسار للقراءة واليمين للعودة | — |
| أعلى وأسفل متكرران | CanvasPosition داخل حدود المحتوى | — |
| يد ثم فأر/لمس وGUI آخر | يمسح اختيار أزرارنا السابق ولا يعين اختياراً غريباً | — |
| إغلاق وإعادة فتح وظهور | لا يصفر الكود موضع القراءة؛ ResetOnSpawn=false | — |
11. أصلح السبب وسجل حدود الفحص #
عند غياب الزر افحص Enabled وVisible وشجرة PlayerGui والتراكب. إذا ظهر ولم يستجب افحص LocalScript والأسماء وActive وOutput. إذا اختفى آخر النص افحص عرض HelpText وAutomaticSize وAutomaticCanvasSize وطريق السطر الأخير. عند صمت اليد ابدأ بالتمييز وSelectable وGuiService.SelectedObject قبل استبدال Activated بحدث للفأر فقط.
فُحصت بنية المادة وXML رسومنا وصياغة Luau؛ وفحص نموذج محلي منفصل انتقالات الظهور وحدود التمرير. لم يعمل الكود في Studio أو هاتف أو يد مادية. احفظ نسخة التمرين وملاحظاتك. النتيجة المطلوبة مساعدة مقروءة وعودة متاحة؛ يمكن تحسين الزينة لاحقاً دون خلط حالة الواجهة بتقدم الخادم أو تقديم أجهزة غير مجربة دليلاً. توضيح نطاق الفحص جزء من تسليم مثال مفيد لمن يكمل العمل.
المصادر الأصلية
Roblox Creator Hub — Text & image buttonsScreenGui
ScreenInsets
Position and size UI objects
GuiObject
UDim2
GuiButton
GuiService
Scrolling frames
Studio testing modes