为什么当我同时使用移动和转弯时,转弯不起作用

Why when I use movement and turn together, the turn does not work

为什么如果我使用它代码 - 旋转有效

p_partnew.Position = Vector3.new (i,p_coord_y, p_coord_z)    
p_partnew.CFrame = p_partnew.CFrame*CFrame.Angles(p_angles_x,p_angles_y, p_angles_z)

如果我使用它代码 - 旋转不起作用

p_partnew.CFrame = CFrame.new (i,p_coord_y, p_coord_z)        
p_partnew.CFrame = p_partnew.CFrame*CFrame.Angles(p_angles_x,p_angles_y, p_angles_z)
        

在第一个示例中,仅修改了零件的位置,然后应用了旋转。第二个示例将整个 CFrame 设置到将覆盖对象原始旋转的位置,然后应用旋转。

简单地说,#1将旋转添加p_angles,而#2将旋转设置为p_angles。

要了解发生了什么,请查看 Understanding CFrames

CFrame 是一个 4x3 矩阵,其组件对应于零件的位置和方向。当您获取或设置部件的位置 属性 时,它只是读取和写入 CFrame 值的特定部分。

让我们看一些示例 CFrames :

Example CFrame Components
A Part located at (0, 0, 0) with no rotation
Part.CFrame = CFrame.new(0,0,0)
0 0 0 1
0 0 0 1
0 0 0 1
A Part located at (1, 2, 3) with no rotation
Part.CFrame = CFrame.new(1,2,3)
1 2 3 1
0 0 0 1
0 0 0 1
A Part located at (0, 0, 0) with (90, 0, 0) rotation
Part.CFrame = CFrame.new(0,0,0) * CFrame.Angles(math.rad(90), 0, 0)
0 0 0 1
0 0 0 A
-1 0 1 A
A Part located at (0, 0, 0) with (0, 90, 0) rotation
Part.CFrame = CFrame.new(0,0,0) * CFrame.Angles(0, math.rad(90), 0)
0 0 0 A
0 1 0 1
0 -1 0 A
A Part located at (0, 0, 0) with (0, 0, 90) rotation
Part.CFrame = CFrame.new(0,0,0) * CFrame.Angles(0, 0, math.rad(90))
0 0 0 A
-1 0 1 A
0 0 0 1
A Part located at (1, 2, 3) with (90, 90, 90) rotation
Part.CFrame = CFrame.new(1,2,3) * CFrame.Angles(math.rad(90), math.rad(90), math.rad(90))
1 2 3 1
0 A A B
-1 0 1 B
Terms Values
A -4.3711388286738e-08
B 1.9106854651647e-15

在您的第一个代码示例中,您首先设置了 Position。这会保留原始 CFrame,并仅更新 Position 的值。

-- imagine that p_partnew.CFrame looks like this :
-- ? ? ? ?
-- ? ? ? ?
-- ? ? ? ?

-- set just the position values in the CFrame, keep everything else
p_partnew.Position = Vector3.new(i, p_coord_y, p_coord_z)

-- p_partnew.CFrame now looks like this :
-- i p_coord_y p_coord_z ?
-- ? ? ? ?
-- ? ? ? ?

-- apply a transformation of angles
p_partnew.CFrame = p_partnew.CFrame * CFrame.Angles(p_angles_x, p_angles_y, p_angles_z)

在第二个代码示例中,您首先仅使用位置值设置整个 CFrame。这会清除该 CFrame 之前存在的所有其他数据。

-- set the entire CFrame
p_partnew.CFrame = CFrame.new(i, p_coord_y, p_coord_z)

-- p_partnew.CFrame now looks like this :
-- i p_coord_y p_coord_z 1
-- 0 0 0 1
-- 0 0 0 1

-- apply a transformation of angles
p_partnew.CFrame = p_partnew.CFrame * CFrame.Angles(p_angles_x, p_angles_y, p_angles_z)

因此,如果第一个示例适用于旋转,但第二个示例不适用,则答案是当您设置 CFrame 时原始旋转信息丢失了。您可以尝试先保存该信息,然后将其应用到新位置,然后应用您的更改(假设您的更改是小增量)。那看起来像这样:

-- store the previous orientation
local o = p_partnew.Orientation

-- create a set of changes based on new angles
local angles = CFrame.Angles(math.rad(o.X) + p_angles_x, math.rad(o.Y) + p_angles_y, math.rad(o.Z) + p_angles_z)

-- set the new CFrame
p_partnew.CFrame = CFrame.new(i, p_coord_y, p_coord_z):ToWorldSpace(angles)