CFrames

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

A CFrame , 簡稱 坐標框架 , 是用於旋轉和定位 3D 物件的數據類型。作為對象屬性或獨立單元,CFrame 包含全球 x-, y-, 和 z-坐標以及每個軸的旋轉數據。此外, CFrames 包含有用的功能,用於在3D空間中與對象工作。

遊戲中的 CFrame 應用程式的一些例子可能是:

  • 尋找一個項目的遠端目標點,例如玩家的雷射發射器瞄準的敵人位置。
  • 移動相機,將其聚焦在特定的 NPC 上,因為玩家與它們互動。
  • 直接放置狀態指示器在玩家的頭上,以顯示他們是否被麻痺、強化、中毒等等

CFRame 基礎

放置 CFrame

您可以使用 CFrame.new() 在預設位置(0, 0, 0)創建空的 CFrame 。若要在特定點位置置入 CFrame ,請提供 x-, y-, 和 z-座標作為 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 部分在其 y 軸上旋轉 45 度順時針。


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.RedBlock
local 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.RedBlock
redBlock.CFrame = CFrame.new(redBlock.Position) + Vector3.new(0, 1.25, 0)

之前
>

之後
>

您可以使用相同的技巧來抵消對象從另一個對物件的位置。在下面的例子中,一個 Vector3 在藍方塊的位置而不是方磚塊的位置創建了一個新的 CFrame


local Workspace = game:GetService("Workspace")
local redBlock = Workspace.RedBlock
local blueCube = Workspace.BlueCube
redBlock.CFrame = CFrame.new(blueCube.Position) + Vector3.new(0, 2, 0)

之前
>

之後
>

動態 CFrame 方向

和 建造者重新定位或旋轉世界內的對象至特定方向,但有時候您無法依靠固定的世界位置和旋轉角度。例如:

  • 直接將漂浮的寶物放置在世界上任何地方的玩家面前,面向任何方向。
  • 讓神奇的精靈直接出現在玩家右肩上。

在這些情況下,使用 CFrame 方法而不是它們的建造者。

相對位置

CFrame:ToWorldSpace()將對物件的CFrame轉換為新的 世界 方向。這使得它非常適合抵消零件與自身或其他物件的關係,無論如何現在位置/旋轉。

在下面的例子中,redBlock部分與藍色立方體的y軸相對移動2個單位(綠色箭頭通過它指向)和 相對於全球y軸直接指向上。


local Workspace = game:GetService("Workspace")
local redBlock = Workspace.RedBlock
local blueCube = Workspace.BlueCube
local offsetCFrame = CFrame.new(0, 2, 0)
redBlock.CFrame = blueCube.CFrame:ToWorldSpace(offsetCFrame)

之前
>

之後
>

相對旋轉

您也可以使用 CFrame:ToWorldSpace() 來旋轉與自身相關的對象。在下列示例中,redBlock 部分在其 y 軸上旋轉 70 度反時針,在其 z 軸上旋轉 20 度。


local Workspace = game:GetService("Workspace")
local redBlock = Workspace.RedBlock
local rotatedCFrame = CFrame.Angles(0, math.rad(70), math.rad(20))
redBlock.CFrame = redBlock.CFrame:ToWorldSpace(rotatedCFrame)

之前
>

之後
>

面向一個點的特定表面

您可以使用 Vector3 點作為 CFrame.new() 的第二個參數,將對象的前面轉向另一個對象。您也可以使用相對旋轉來將物體的任何面指向 Vector3 點。以下示例執行兩個連續的 CFrame 操作:

  1. 表面,由白色圓圈標示,指向目標。
  2. 旋轉 CFrame 以使黑色圓圈標記的 頂部 表面指向目標。

local Workspace = game:GetService("Workspace")
local redBlock = Workspace.RedBlock
local blueCube = Workspace.BlueCube
-- 為目標位置創建 Vector3
local targetPosition = blueCube.Position
-- 將紅色方塊的前表面指向「目標位置」
redBlock.CFrame = CFrame.new(redBlock.Position, targetPosition)
-- 現在紅色方塊的前面(白色圓圈)指向藍色方塊
-- 將紅塊的 CFrame 相對於自身旋轉,使其頂部表面(不是前面)指向目標
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部分重新位置在greenCubecyanCube部分之間。值 0.7 將它放置在綠色立方體的距離的 70% 之外。


local Workspace = game:GetService("Workspace")
local redBlock = Workspace.RedBlock
local greenCube = Workspace.GreenCube
local cyanCube = Workspace.CyanCube
redBlock.CFrame = greenCube.CFrame:Lerp(cyanCube.CFrame, 0.7)

之前
>

之後
>