A CFrame , สั้นสําหรับ กรอบความสัมพันธ์ , เป็นประเภทข้อมูลที่ใช้เพื่อหมุนและตําแหน่งวัตถุ 3Dในฐานะที่เป็นคุณสมบัติของวัตถุหรือหน่วยยืนอิสระ, CFrame ประกอบด้วยพิกัด x-, y-, และ z-ทั่วโลกรวมทั้งข้อมูลการหมุนสำหรับแต่ละแกนนอกจากนี้ CFrames มีฟังก์ชันที่มีประโยชน์สำหรับการทำงานกับวัตถุในพื้นที่ 3D
ตัวอย่างบางส่วนของแอปพลิเคชัน CFrame ในเกมอาจเป็น:
- ค้นหาจุดเป้าหมายที่ไกลออกไปสำหรับกระสุน, เช่นตำแหน่งของศัตรูที่ถูกเล็งโดยเลเซอร์ของผู้เล่น
- ย้ายกล้องเพื่อให้มุ่งเน้น NPC เฉพาะที่เป็นผู้เล่นโต้ตอบกับพวกเขา
- วางตัวบ่งบอกสถานะไว้ที่ด้านบนหัวของผู้เล่นเพื่อแสดงว่าพวกเขาถูกอัมพาต เพิ่มขึ้น ถูกวางยาพิษ ฯลฯ
พื้นฐานของ CFrame
ตำแหน่ง CFrame
คุณสามารถสร้างว่างเปล่า CFrame ที่ตำแหน่งเริ่มต้นของ (0, 0, 0) โดยใช้ CFrame.new()เพื่อตำแหน่ง CFrame ที่จุดเฉพาะให้ x-, y-, และ z-coordinates เป็นอาร์กิวเมนต์ของ CFrame.new()ในตัวอย่างต่อไปนี้ คุณสมบัติของส่วน redBlock ในส่วน CFrame จะเปลี่ยนเป็น 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.Angles() โดยให้มุมหมุนในรัศมีสําหรับแกนที่ต้องการพารามิเตอร์ไปที่ CFrame.Angles() อยู่ในรัศมีไม่ใช่องศาหากคุณต้องการองศา ให้ใช้ math.rad() เพื่อแปลงองศาเป็นรัศมีในตัวอย่างต่อไปนี้ส่วน redBlock หมุน 45 องศาในทิศทางตรงกันข้ามบนแกน y
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlock-- สร้าง CFrame หมุนใหม่local newCFrame = CFrame.Angles(0, math.rad(45), 0)-- เขียนทับ CFrame ปัจจุบันของบล็อกสีแดงด้วย CFrame ใหม่redBlock.CFrame = newCFrame


เผชิญหน้ากับ CFrame ไปยังจุด
คุณสามารถใช้ CFrame.new() เพื่อชี้พื้นผิวด้านหน้าของ CFrame ที่จุดเฉพาะในโลกในตัวอย่างต่อไปนี้ redBlock ตำแหน่งส่วนที่อยู่ที่ (0, 3, 0) และชี้พื้นผิวด้านหน้าที่ถูกทำเครื่องหมายด้วยวงกลมสีขาวไปที่ส่วน blueCube
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlocklocal blueCube = Workspace.BlueCube-- สร้าง Vector3 สำหรับตำแหน่งเริ่มต้นและตำแหน่งเป้าหมายlocal startPosition = Vector3.new(0, 3, 0)local targetPosition = blueCube.Position-- วางบล็อกสีแดงที่ 'startPosition' และชี้พื้นผิวด้านหน้าไปที่ 'targetPosition'redBlock.CFrame = CFrame.new(startPosition, targetPosition)


ชดเชย 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.Angles() สามารถเลื่อนหรือหมุนวัตถุในตําแหน่งที่เฉพาะภายในโลก แต่คุณบางครั้งไม่สามารถพึ่งพาตําแหน่งโลกคงที่และระยะการหมุนได้ตัวอย่าง:
- วางสมบัติลอยตัวโดยตรงข้างหน้าผู้เล่นที่อาจยืนอยู่ที่ใดก็ได้ในโลก หันไปทางใดทางหนึ่ง
- ทำให้เจ้าวายุวิเศษปรากฏขึ้นโดยตรงบนไหล่ขวาของผู้เล่น
ในกรณีเหล่านี้ใช้วิธี CFrame แทนที่จะใช้คอนสตรัคเตอร์ของพวกเขา
ตำแหน่ง相対
ฟังก์ชัน CFrame:ToWorldSpace() เปลี่ยนตัวแปรของวัตถุ CFrame — เคารพการจัดตำแหน่งท้องถิ่นของตัวเอง — เป็นการจัดตำแหน่งโลกใหม่ **** สิ่งนี้ทำให้เหมาะสำหรับการชดเชยส่วนที่เกี่ยวข้องกับตัวเองหรือวัตถุอื่น ไม่ว่าจะตำแหน่งหรือหมุนอย่างไรในปัจจุบัน
ในตัวอย่างต่อไปนี้ ส่วน redBlock จะชดเชย 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() เพื่อหมุนวัตถุที่เกี่ยวข้องกับตัวเองในตัวอย่างต่อไปนี้ส่วน redBlock จะหมุน 70 องศาในแนวนอนบนแกน y และ 20 องศาในแนวนอนบนแกน z
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlocklocal rotatedCFrame = CFrame.Angles(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-- สร้าง Vector3 สำหรับตำแหน่งเป้าหมายlocal targetPosition = blueCube.Position-- ชี้พื้นผิวด้านหน้าของ redBlock ไปที่ 'targetPosition'redBlock.CFrame = CFrame.new(redBlock.Position, targetPosition)-- ตอนนี้พื้นผิวด้านหน้าของ redBlock (วงกลมสีขาว) ชี้ไปที่ blueCube-- หมุน CFrame ของ redBlock เกี่ยวกับตัวเองเพื่อให้พื้นผิวด้านบน (ไม่ใช่ด้านหน้า) ชี้ไปที่เป้าหมายlocal rotatedCFrame = CFrame.Angles(math.rad(-90), 0, 0)redBlock.CFrame = redBlock.CFrame:ToWorldSpace(rotatedCFrame)-- Now the redBlock's top surface (black circle) is pointing towards the blueCube (as seen in After below)


ค้นหาจุดระหว่างจุด
คุณสามารถใช้ การคูณเชิงเส้น หรือ lerp เพื่อตำแหน่ง CFrame ระหว่างจุดสองจุดในตัวอย่างต่อไปนี้ส่วน redBlock จะย้ายตำแหน่งระหว่างส่วน 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)

