一个 CFrame ,简称 坐标框架 ,是用于旋转和定位 3D 对象的数据类型。作为对象属性或独立单元,CFrame 包含全球 x-, y-, 和 z-坐标以及每个轴的旋转数据。此外,CFrames 包含有助于在 3D 空间处理对象的有用功能。
游戏中的一些 CFrame 应用示例可能是:
- 找到一个项目的远离目标点,例如玩家激光发射器瞄准的敌人位置。
- 移动相机以便它专注于特定的 NPC 作为玩家与之交互。
- 直接将状态指示放在玩家的头顶上,显示他们是否被麻痹、强化、中毒等
CFRame 基础
放置一个 CFrame
您可以使用 CFrame.new() 在默认位置(0, 0, 0)创建一个空的 CFrame 。要在特定位置放置 CFrame ,请向 CFrame.new() 提供 x-, y-, 和 z-坐标作为参数。在以下示例中,redBlock部分的CFrame属性更改为newCFrame,重新定位为(-2,2,4)
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlock-- 创建新的 CFramelocal newCFrame = CFrame.new(-2, 2, 4)-- 用新的 CFrame 覆盖红块的当前 CFrameredBlock.CFrame = newCFrame


或者,你可以提供一个新的 Vector3 位置给 CFrame.new() 并获得相同的结果:
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlock-- 创建新的 CFramelocal newVector3 = Vector3.new(-2, 2, 4)local newCFrame = CFrame.new(newVector3)-- 用新的 CFrame 覆盖红块的当前 CFrameredBlock.CFrame = newCFrame
旋转一个 CFrame
要创建旋转的 CFrame ,请使用 CFrame.Angles() 建造器,为所需的轴提供以径为单位的旋转角度。CFrame.Angles() 的参数是在 ради度,不是度。如果你喜欢度数,使用 math.rad() 将度数转换为 ради度。在以下示例中, redBlock 部分在其 y 轴上旋转 45 度逆时针。
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlock-- 创建新的旋转 CFramelocal newCFrame = CFrame.Angles(0, math.rad(45), 0)-- 用新的 CFrame 覆盖红块的当前 CFrameredBlock.CFrame = newCFrame


面向一个点的 CFrame
您可以使用 CFrame.new() 来将 CFrame 的前表面指向世界上的特定位置。在以下示例中,redBlock部件位置在(0,3,0),指向白色圆圈标记的前表面,指向blueCube部件。
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlocklocal blueCube = Workspace.BlueCube-- 为起始位置和目标位置创建一个 Vector3local 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部分相对于蓝色立方体的 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 部分在其 y 轴上旋转 70 度逆时针,在其 z 轴上旋转 20 度。
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-- 为目标位置创建一个 Vector3local 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部分重新位置在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)

