A CFrame، اختصار لـ إطار الإحداثيات، هو نوع بيانات يُستخدم لتدوير وتحديد مواقع الأجسام ثلاثية الأبعاد. سواء كان كخاصية كائن أو وحدة مستقلة، يحتوي CFrame على X، Y، وZ إحداثيات عالمية بالإضافة إلى بيانات التدوير لكل محور. بالإضافة إلى ذلك، تحتوي CFrames على وظائف مفيدة للعمل مع الكائنات في الفضاء ثلاثي الأبعاد.
تحديد موقع CFrame
يمكنك إنشاء CFrame فارغ في الموضع الافتراضي لـ (0, 0, 0) باستخدام CFrame.new(). لتحديد موقع CFrame في نقطة معينة، قدم إحداثيات X، Y، وZ كوسائط إلى CFrame.new(). في المثال التالي، يتم تغيير خاصية CFrame لجزء redBlock إلى newCFrame، مما يعيد ترتيبه إلى (-2, 2, 4).
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlock-- إنشاء CFrame جديدlocal newCFrame = CFrame.new(-2, 2, 4)-- استبدال CFrame الحالي للكتلة الحمراء بـ CFrame الجديدredBlock.CFrame = newCFrame


بدلاً من ذلك، يمكنك تقديم موقع جديد من نوع Vector3 إلى CFrame.new() لتحقيق نفس النتيجة:
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlock-- إنشاء CFrame جديدlocal newVector3 = Vector3.new(-2, 2, 4)local newCFrame = CFrame.new(newVector3)-- استبدال CFrame الحالي للكتلة الحمراء بـ CFrame الجديدredBlock.CFrame = newCFrame
تدوير CFrame
لإنشاء CFrame مُدور، استخدم البناء CFrame.fromEulerAnglesXYZ()، وقدم زاوية تدوير بالراديان للمحاور المطلوبة. المعاملات لـ CFrame.fromEulerAnglesXYZ() تكون بالراديان، وليست بالدرجات؛ إذا كنت تفضل الدرجات، استخدم math.rad() لتحويل الدرجات إلى راديان. في المثال التالي، تدور الكتلة الحمراء بمقدار 45 درجة عكس عقارب الساعة على محور Y الخاص بها.
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlock-- إنشاء CFrame جديد مُدورlocal newCFrame = CFrame.fromEulerAnglesXYZ(0, math.rad(45), 0)-- استبدال CFrame الحالي للكتلة الحمراء بـ CFrame الجديدredBlock.CFrame = newCFrame


توجيه CFrame نحو نقطة
يمكنك استخدام CFrame.lookAt() لتوجيه السطح الأمامي لـ CFrame نحو نقطة معينة في العالم. المثال التالي يحدد موضع redBlock عند (0, 3, 0) ويشير سطحه الأمامي، الذي يُشار إليه بالدائرة البيضاء، نحو جزء blueCube.
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlocklocal blueCube = Workspace.BlueCuberedBlock.Position = Vector3.new(0, 3, 0)-- توجيه السطح الأمامي للكتلة الحمراء نحو المكعب الأزرقredBlock.CFrame = CFrame.lookAt(redBlock.Position, blueCube.Position)


إزاحة CFrame
لإزاحة كائن بمقدار معين من النقاط من موضعه الحالي، أضف أو اطرح Vector3 من CFrame جديد عند موضع الكائن. للحصول على موضع Vector3 المُنسق بشكل صحيح لكائن لاستخدامه مع CFrame.new()، كما هو موضح هنا، فإن خاصية Position (redBlock.Position) هي اختصار مريح.
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlockredBlock.CFrame = CFrame.new(redBlock.Position) + Vector3.new(0, 1.25, 0)


يمكنك استخدام نفس التقنية لإزاحة كائن من موضع كائن آخر. في المثال التالي، تتم إضافة Vector3 إلى CFrame جديد تم إنشاؤه عند موضع المكعب الأزرق بدلاً من موضع الكتلة.
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlocklocal blueCube = Workspace.BlueCuberedBlock.CFrame = CFrame.new(blueCube.Position) + Vector3.new(0, 2, 0)


توجيه CFrame الديناميكي
تقوم البانيات CFrame.new() و CFrame.fromEulerAnglesXYZ() بإعادة وضع أو تدوير كائن عند توجيه معين داخل العالم، ولكن في بعض الأحيان لا يمكنك الاعتماد على موضع وتدوير ثابت في العالم. على سبيل المثال:
- وضع كنز طائر مباشرة أمام لاعب قد يقف في أي مكان في العالم، ويواجه أي اتجاه.
- جعل جني سحري يظهر مباشرة فوق كتف اللاعب اليمنى.
في هذه الحالات، استخدم طرق CFrame بدلاً من البانيات الخاصة بها.
الموضع النسبي
تقوم دالة CFrame:ToWorldSpace() بتحويل CFrame الخاص بكائن ما — مع احترام توجيهه المحلي — إلى توجيه عالمي جديد. هذا يجعلها مثالية لإزاحة جزء بالنسبة لنفسه أو لكائن آخر، بغض النظر عن كيفية وضعه/تدويره حالياً.
في المثال التالي، تتم إزاحة الكتلة الحمراء بقدر 2 نقطة بالنسبة لمحور Y للمكعب الأزرق (السهم الأخضر الذي يمر من خلاله) وليس بالنسبة لمحور Y العالمي الذي يشير لأعلى مباشرة.
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlocklocal blueCube = Workspace.BlueCubelocal offsetCFrame = CFrame.new(0, 2, 0)redBlock.CFrame = blueCube.CFrame:ToWorldSpace(offsetCFrame)


الدوران النسبي
يمكنك أيضًا استخدام CFrame:ToWorldSpace() لتدوير كائن بالنسبة لنفسه. في المثال التالي، تدور الكتلة الحمراء بمقدار 70 درجة عكس عقارب الساعة على محور Y الخاص بها و20 درجة في اتجاه عقارب الساعة على محور Z الخاص بها.
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlocklocal rotatedCFrame = CFrame.fromEulerAnglesXYZ(0, math.rad(70), math.rad(20))redBlock.CFrame = redBlock.CFrame:ToWorldSpace(rotatedCFrame)


توجيه سطح معين نحو نقطة
يمكنك جعل مقدمة كائن تشير نحو كائن آخر عن طريق تزويد نقطة Vector3 كمعامل ثانٍ لـ CFrame.new(). يمكنك أيضًا استخدام الدوران النسبي لجعل أي وجه من الكائن يشير نحو نقطة Vector3. المثال التالي ينفذ عمليتين متتاليتين من CFrame:
- توجيه الواجهة الأمامية، المميزة بالدائرة البيضاء، نحو الهدف.
- تدوير CFrame لجعل السطح العلوي، المميز بالدائرة السوداء، يشير نحو الهدف.
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlocklocal blueCube = Workspace.BlueCube-- توجيه السطح الأمامي للكتلة الحمراء نحو المكعب الأزرقredBlock.CFrame = CFrame.lookAt(redBlock.Position, blueCube.Position)-- تدوير CFrame بالنسبة لنفسه بحيث يشير السطح العلوي (ليس الأمامي) نحو المكعب الأزرقlocal rotatedCFrame = CFrame.fromEulerAnglesXYZ(math.rad(-90), 0, 0)redBlock.CFrame = redBlock.CFrame:ToWorldSpace(rotatedCFrame)


العثور على نقطة بين نقطتين
يمكنك استخدام التداخل الخطي، أو lerp، لوضع CFrame بين نقطتين. في المثال التالي، تُعاد موضع الكتلة الحمراء بين جزأي greenCube وcyanCube. قيمة 0.7 تضعها على بُعد 70% من المسافة بعيدًا عن المكعب الأخضر.
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlocklocal greenCube = Workspace.GreenCubelocal cyanCube = Workspace.CyanCuberedBlock.CFrame = greenCube.CFrame:Lerp(cyanCube.CFrame, 0.7)

