التطوير / ROBLOX
نقاط التقدم في Roblox Studio: مسار تدريب مستقل
أنشئ نقطتين وحدد مكان إعادة الظهور لكل لاعب، ثم افحص الموت واللمس المتكرر والترتيب ومغادرة الجلسة.
حدد قاعدة الآلية الصغيرة أولًا #
ابن مسارًا قصيرًا فيه Start وCheckpoint1 وCheckpoint2. يصل اللاعب بالترتيب؛ وبعد قبول لمس النقطة التالية يعيده الموت إليها. الرجوع إلى منصة أقدم لا يخفض تقدمه. للاعب الثاني حالة ومكان ظهور مستقلان. بهذه القاعدة يمكنك مقارنة المتوقع بما تراه فعلًا بدل الاكتفاء بأن المشهد بدأ.
هذا نموذج تعليمي جديد، لا تنفيذ Stone Trail أو لعبة أخرى لصاحب الموقع. كتبنا السكربت لهذا الدرس وراجعنا منطقه، لكن لم ننفذه هنا في محرك Roblox. التقدم في ذاكرة الخادم الحالي فقط. لا نضيف حفظًا بين الزيارات أو جوائز أو حماية من جميع طرق تجاوز الطريق. افحص الآلية المحدودة قبل التوسع. الرسوم أيضًا تخطيط أصلي وليست خريطة لعبة حقيقية أو لقطة Studio.
1. جهز مشهدًا مستقلًا بأسماء دقيقة #
احفظ مشروعًا صغيرًا جديدًا كي لا يتدخل التدريب في لعبة عاملة. يحتاج Workspace إلى SpawnLocation اسمه Start وFolder اسمه Checkpoints. داخل المجلد أنشئ SpawnLocation باسم Checkpoint1 وآخر باسم Checkpoint2. أضف Script عاديًا باسم CheckpointServer في ServerScriptService. المسارات النهائية Workspace.Start وWorkspace.Checkpoints.Checkpoint1 وWorkspace.Checkpoints.Checkpoint2 وServerScriptService.CheckpointServer. تتطابق الكتابة؛ Checkpoint 1 مع مسافة اسم مختلف.
يمكن أن تكون بقية الطريق Parts مثبتة. أما النقاط فيجب أن تكون SpawnLocation فعلًا، لا Parts متشابهة اللون. أزل نقاط الظهور الإضافية غير التابعة لهذا المشهد الجديد. لا تحتاج حزمة نموذج ذات سكربتات مجهولة: منصاتك وملف خادم واحد كافية. قبل الكود تأكد أن النقاط الثلاث ظاهرة ولا تتداخل. الطريق القصير الواضح يسهل ربط اللمس بالنتيجة.
2. اضبط اللمس ومساحة الظهور الآمنة #
ضع Start ثم Checkpoint1 ثم Checkpoint2 على طريق آمن قصير. اترك مسافة تسمح بلمس كل نقطة وحدها. وفر فراغًا فوق SpawnLocation حتى لا يظهر الشخص داخل جدار أو تحت سقف منخفض أو عند حافة سقوط. اللون والاسم يميزان المنصات ولا يسجلان التقدم وحدهما. ليست الفخاخ الصعبة ضرورية في الفحص الأول.
يعرض الجدول إعداد هذا التدريب، ويعيد السكربت ضبط القيم عند البدء. تسمح النقاط بظهور لا يعتمد على الفريق، مع تعطيل تغيير الفريق باللمس. يسمح CanTouch بالأحداث ويثبت Anchored المنصة. إضافة فرق أو collision groups لاحقًا تتطلب فحص أهلية الظهور والتلامس مجددًا. أبق تحميل الشخصيات التلقائي المعتاد مفعّلًا الآن؛ التحميل المخصص خارج هذا النموذج.
| الخاصية | القيمة | الغرض في التدريب |
|---|---|---|
| Class | SpawnLocation | منصات الظهور والعودة |
| Anchored | true | المنصات ثابتة |
| CanCollide | true | يمكن للشخصية الوقوف |
| CanTouch | true | يسمح بكشف التلامس |
| Enabled | true | الظهور متاح |
| Neutral | true | لا قيد فريق |
| AllowTeamChangeOnTouch | false | اللمس لا يغير الفريق |
3. ضع السكربت كاملًا على الخادم #
افتح CheckpointServer في ServerScriptService واستبدل محتواه بالمثال الكامل أدناه. انسخ الإعداد والتهيئة مع معالج Touched، لا المعالج وحده. يحدد جدول checkpoints ترتيبًا ثابتًا ولا يعتمد على ترتيب GetChildren. يفحص configure أنواع العناصر ويضبط خصائصها. ينتظر WaitForChild الأسماء الغائبة، ويبلغ assert عن نوع خاطئ. أصلح الهيكل قبل اختبار الطريق.
يعين الخادم Player.RespawnLocation ويحفظ progress بمفتاح Player. ليس LocalScript في StarterPlayerScripts بديلًا لهذا الموضع. تجنب سكربتًا آخر يغير RespawnLocation في الاختبار. ابدأ جلسة جديدة بعد تجهيز المشهد. إدراج الكود في اختبار جار لا ينقل الشخصية الحية فورًا إلى Start: هو يحدد ظهورًا مقبلًا لا أمر انتقال آني. لذلك قارن بعد موت وعودة طبيعيين.
local Players = game:GetService("Players")
local start = workspace:WaitForChild("Start")
local folder = workspace:WaitForChild("Checkpoints")
local checkpoints = {
folder:WaitForChild("Checkpoint1"),
folder:WaitForChild("Checkpoint2"),
}
local progress = {}
local function configure(spawn)
assert(spawn:IsA("SpawnLocation"), "Expected SpawnLocation")
spawn.Anchored = true
spawn.CanCollide = true
spawn.CanTouch = true
spawn.Enabled = true
spawn.Neutral = true
spawn.AllowTeamChangeOnTouch = false
end
configure(start)
for _, checkpoint in ipairs(checkpoints) do
configure(checkpoint)
end
local function initialize(player)
if progress[player] ~= nil then return end
progress[player] = 0
player.RespawnLocation = start
end
Players.PlayerAdded:Connect(initialize)
Players.PlayerRemoving:Connect(function(player)
progress[player] = nil
end)
for _, player in ipairs(Players:GetPlayers()) do
initialize(player)
end
for index, checkpoint in ipairs(checkpoints) do
checkpoint.Touched:Connect(function(hit)
local character = hit:FindFirstAncestorOfClass("Model")
if not character then return end
local player = Players:GetPlayerFromCharacter(character)
if not player or player.Character ~= character then return end
local humanoid = character:FindFirstChildOfClass("Humanoid")
if not humanoid or humanoid.Health <= 0 then return end
local current = progress[player]
if current == nil or index ~= current + 1 then return end
player.RespawnLocation = checkpoint
progress[player] = index
end)
end4. تعرف على اللاعب وراء القطعة الملامسة #
يعطي Touched القطعة الأخرى، وقد تتبع شخصية أو مكعبًا ساقطًا أو غرضًا. يجد المعالج أقرب Model ويسأل GetPlayerFromCharacter هل يمثل لاعبًا، ثم يقارن player.Character ويفحص Humanoid ذا Health موجب. من دون الشروط قد يغير غرض أو شخصية ميتة التقدم خطأ. ينتهي اللمس غير الصالح بـreturn قبل تعيين مكان الظهور.
يفترض المثال شخصية معتادة وHumanoid داخل نموذجها. يحتاج rig مخصص متداخل إلى بحث نموذج معدّل بعناية؛ لا تحذف تحقق اللاعب لإخفاء عرض. لمس يراه الخادم ليس دليلًا أن الطريق اكتمل بنزاهة. تحتاج الحركة والفيزياء تحليل أمن منفصلًا. هدفنا نقاط شخصية صحيحة في مسار تدريب عادي، لا نظام مكافحة غش كامل.
5. احفظ الترتيب دون حجب الجميع #
يبدأ اللاعب الجديد بـprogress يساوي 0. يقبل فقط current + 1: الفهرس 1 ثم 2. بعد قبول الأولى، لا يطابق لمس آخر بالقدم أو جزء آخر الفهرس التالي. وبعد الثانية ترفض الأولى أيضًا. يمنع الشرط الرجوع وتجاوز النقطة الأولى. هذه قاعدة التدريب المختارة؛ مسار يسمح بترتيب حر يحتاج عقدًا آخر.
لا يوجد debounce عام يغلق المنصة أمام الجميع بعد لمس شخص واحد. لكل Player مفتاح خاص. الفحص والتعيينان لا يحتويان task.wait أو انتظارًا آخر، فيتقدم اللاعبان مستقلين. هذا تحليل منطقي لمعالج قصير، لا ضمان لإضافات غير متزامنة لاحقة. عند إضافة جوائز أو طلب بيانات أو تأخير، راجع تكرار الاستدعاء وتوقيت تعديل الحالة من جديد.
6. ميز الموت عن إعادة البدء والدخول #
يغير اللمس المقبول RespawnLocation لذلك Player. تبقى الشخصية الحية مكانها؛ افحص التعيين في الظهور الطبيعي التالي. ينشئ الموت Model شخصية جديدًا لكن Player يبقى في الجلسة وسجله progress محفوظ. لا تصفر progress في CharacterAdded، وإلا يمحو كل موت النقطة التي وصل إليها اللاعب.
تحذف PlayerRemoving السجل عند الخروج. يعيد الدخول الجديد التهيئة إلى 0 وStart. إيقاف اختبار Studio وبدء آخر ينشئ جلسة جديدة أيضًا. لا يتضمن المثال زر تصفير كامل داخل اللعبة. إذا أضفته لاحقًا فيجب تصفير الفهرس وRespawnLocation معًا؛ تغيير نص لا يكفي. حفظ المشروع يحفظ المشهد والكود، لا ذاكرة جدول اللاعبين أثناء التشغيل.
7. نفذ اختبار اللاعب الواحد خطوة بخطوة #
اختر Test من قائمة الاختبارات في Studio وابدأ. يدرج هذا الوضع شخصية؛ يشغل Run محاكاة بلا شخصية وليس مناسبًا لفحص المشي الأول. ابدأ جلسة جديدة وتأكد من الظهور عند Start. امش طبيعيًا إلى Checkpoint1 وقف عليها، ثم سبب موتًا في منطقة سقوط صممتها منفصلة في النموذج. انتظر الظهور المعتاد وسجل المكان.
كرر عند Checkpoint2. بعدها عد فعليًا إلى الأولى وافحص موتًا آخر: يجب بقاء الثانية مختارة. لا تخلط ذلك مع Stop واختبار Test جديد، فالجديد يمحو الذاكرة عمدًا. سجل النتيجة الحقيقية منفصلة عن التوقع. إن لم تقتل منطقة السقوط الشخصية، فليس ذلك اختبار RespawnLocation فاشلًا بعد. أثبت أولًا موتًا وظهور شخصية جديدة.
8. افحص غرضًا وتجاوزًا ولمسًا متكررًا #
المس Checkpoint2 قبل Checkpoint1 في محاولة مستقلة: ينبغي أن يبقي شرط الترتيب Start. ثم أكمل النقطتين طبيعيًا. لفحص الغرض أنشئ مكعبًا عاديًا غير مثبت واتركه يسقط فيزيائيًا على النقطة. لا يقابل Player فلا ينبغي أن يغير تقدم أي لاعب. قارن حالة الخادم أو ظهور اللاعب المعني لاحقًا، لا لون المنصة فقط.
يعتمد Touched على حركة فيزيائية. تعديل CFrame لتداخل قطعتين مثبتتين ليس اختبارًا مكافئًا للحدث. إن لم يحدث تلامس فافحص CanTouch في الطرفين وقواعد collision groups. لا تنشر نتيجة مختلقة «المكعب رُفض» قبل تنفيذ التجربة. جدول الحالات اللاحق يعرض المتوقع، لا تقرير اختبار هذا السكربت في محرك Roblox. حافظ على هذا الفرق في ملاحظاتك.
9. افحص لاعبين بتقدم مختلف #
اختر Server & Clients بعميلين ثم ابدأ عبر Play أو F7. يصل A إلى الأولى ويبقى B عند Start. بعد الموت ينبغي ظهور A عند Checkpoint1 وB عند Start. ثم يبلغ B الأولى وA الثانية، وقارن النتيجتين. جرب كذلك لمس الاثنين للأولى بتوقيت متقارب: لا يجب أن يحرم قفل عام أحدهما من تقدمه الشخصي.
رؤية منصة ملونة واحدة من كاميرتين لا تثبت الحالة الفردية. لون عنصر Workspace مشترك، أما RespawnLocation فيخص Player. سجل العميل الذي تصرف والشخصية التي ظهرت مجددًا. استخدم End Session لإنهاء الجلسة المتعددة كلها عند الانتهاء. يفحص عميلان محليان حالات محددة ولا يثبتان أداء خادم كبير أو دعم شخصيات متداخلة أو كل تسلسل لمس غير عادي.
10. ابحث عن شرط واحد فشل #
ابدأ من الهيكل إلى الحالة: المسار الدقيق، نوع SpawnLocation، Script خادم عادي، CanTouch، Player حي، فهرس متوقع وأهلية ظهور. خطأ الاسم ورفض الفهرس 2 المقصود سببان مختلفان. استخدم دليل Output المرتبط لأخطاء التنفيذ؛ لا نكرر درس وحدة الإخراج كاملًا هنا. لا توجد علامات نجاح في الجدول. املأ المشاهدة الحقيقية بجانب المتوقع.
تحقق خصوصًا من عدم تعطيل Enabled أو تعديل Neutral بعد البدء. يجب بقاء النقطة في Workspace ومناسبتها للاعب. قد يغير سكربت آخر الخصائص أو RespawnLocation لاحقًا. إن ظهر اللاعب في مكان خاطئ، اكتب تسلسل الأفعال والمنصة الحقيقية بدل «معطل» وحدها. افحص تصحيحًا واحدًا في محاولة واضحة. الانتظار بلا نهاية لا يصلح شرط ترتيب خاطئًا.
| الحالة | الحالة المتوقعة | الفحص |
|---|---|---|
| Test جديد أو دخول | 0؛ Start | الظهور الأول الحقيقي |
| Checkpoint1 ثم موت | 1؛ Checkpoint1 | انتظار شخصية جديدة |
| Checkpoint1 مجددًا | دون تغيير | أجزاء جسم مختلفة |
| Checkpoint2 بعد الأولى | 2؛ Checkpoint2 | الموت يعيد للثانية |
| الأولى بعد الثانية | 2؛ Checkpoint2 | لا تراجع |
| الثانية قبل الأولى | 0؛ Start | رفض التجاوز |
| مكعب أو Model غير لاعب | دون تغيير | لا Player مطابق |
| شخصية ميتة أو قديمة | دون تغيير | Health وCharacter الحالي |
| تقدم A دون B | هدفان مستقلان | فحص الاثنين بعد الموت |
| خروج أو Stop واختبار جديد | حالة جديدة 0 | لا حفظ دائم |
11. احفظ النتيجة واختر توسعة واحدة #
أنه الاختبار واحفظ النموذج باسم واضح. سجل الهيكل ونسخة السكربت وافتراض التحميل التلقائي والحالات الفردية والمتعددة المنفذة والمكان المتوقع والفعلي. مراجعة منطق المقال لا تعني أن مشروعك اجتاز Studio. قارن الحالات المهمة في مشهدك قبل نقل الآلية إلى لعبة عاملة، ولا تنقل ادعاء نجاح لم تجربه بنفسك.
يمكن أن تكون الخطوة المقبلة رسالة تأكيد شخصية أو زر تصفير واضح. الحفظ الدائم مهمة منفصلة فيها تحميل وفشل كتابة ونسخ بيانات وقواعد تصفير؛ لا نستخدم DataStore هنا. لا تعد اللاعب بتقدم أبدي. احفظ القاعدة الواضحة أولًا: الموت يعيد إلى النقطة أثناء الزيارة الحالية، والخروج ينهي تقدم هذا التدريب في الذاكرة. قاعدة صغيرة مفحوصة أسهل توسعة من أنظمة كثيرة غير مختبرة.
المصادر الأصلية
Roblox Creator HubRoblox Creator Hub — Player.RespawnLocation
Roblox Creator Hub — BasePart.Touched and CanTouch
Roblox Creator Hub — Studio testing modes
Roblox Creator Hub — Players lifecycle
Roblox Creator Hub — ServerScriptService