使子对象不受父对象旋转影响-Unity

8
我有两个游戏对象在我的角色里,称为right_obj和left_obj,我希望它们忽略父对象的旋转,就像如果玩家改变方向(左、右),这两个游戏对象保持它们的位置和旋转,到目前为止我使用了两种方法但失败了。这是我的代码,我在我的两个游戏对象上使用这个脚本,但它们忽略了这些行。
// first one approch
Quaternion rotation;
void Awake()
{
    rotation = transform.rotation;
}

void LateUpdate () 
{
    transform.rotation = rotation;
}

// 2nd approch
void LateUpdate () 
{
    transform.rotation = Quaternion.identity;;
}

另一种选择可能是为子对象添加一个具有“kinematic”属性和锁定旋转的“RigidBody”组件。 - derHugo
谢谢回复,但它还是在移动,没生效。 - Ali
你可以将相反的旋转应用于子对象,以应用于父对象。这样看起来就像子对象没有旋转一样。 - JMadelaine
5个回答

12

您真的需要这种关系吗?
如果您不需要父/子关系,可以在0,0,0处生成一个空GameObject,并将实际的父级和子级作为场景中央GameObject的子级生成,这样它们仍将被分组成一定的关系,但是 不再是父/子关系,而是 兄弟/兄弟关系,使第一个与第二个独立。

如果您需要使两个对象相互依赖,但不是完全按照父/子的方式进行,可以尝试使用Parent Constraints

这样,您将获得以下类型的层次结构:
- Father GO(在0,0,0处)
-- Child1(您的实际父级)
-- Child2(您的实际子级)

Child1和Child2通过其ParentConstraint同步位置,但不协同旋转。

否则就只能将相反的旋转应用到子级上了。


5
如果您真的不想破坏父子层级关系,您可以每帧旋转子对象来抵消父对象的旋转。假设我们有以下场景:

enter image description here

将以下的 RestoreOriginRotation.cs 添加到子对象中,我们可以获得一个稳定的子对象旋转。

enter image description here

我们能得到什么。

enter image description here

如果您不关心底层数学,您可以在此停止。

enter image description here


2
优秀的答案和解释很有道理,虽然已经很晚了但是非常值得。 - Ali

4
你也可以使用旋转约束组件。这与上面提到的父级约束类似,但我认为更容易理解 - 它仅使用你放置其中的游戏对象的旋转而不是其他属性。
你只需要创建一个空的游戏对象并将其旋转设置为0,0,0,然后将此空游戏对象设置为旋转约束的源。我在我的游戏中就有这样的设置,并覆盖了实际父级的旋转,这正是我想要的。
也许不是最干净的解决方案,但值得考虑。
这里是文档链接-https://docs.unity3d.com/Manual/class-RotationConstraint.html

这实际上是一个很好的答案。我能够通过在我不想旋转的GO上添加旋转约束组件来设置它。然而,当它旋转时,我希望它围绕其父组件移动,从而保持其旋转为0。这很容易让它围绕父级旋转并保持垂直。 - Andrew Senner

4
正如@aaronrums所说,旋转约束(Rotation Constraint)是实现此目的的一种简单方法。 rotating player 在这里,我有三个游戏对象。主父对象容器(“Player Seat”)持有所有子对象,始终将其设置为Z轴上的0度旋转。我想要保持垂直位置(以便文字和头像不旋转)的GO是“DrewPlayer”。我将其在X轴上偏移了100个单位放置在其父级“Player Position”中。然后我在不想旋转的对象上(即“DrewPlayer”)添加了一个旋转约束。一旦应用了限制,我就将“Player Seat”拖到源列表中,当我旋转“Player Seat”时,就能够在下面的gif中实现所需的效果。
谢谢@aaronrums!让我节省了些功夫。 :)

你如何使用代码设置它的来源? - Kepol

3

LeviathanCode的“父级约束”解决方案只能在Unity 2018.1+中使用,因为这是一个新添加的功能。

我的建议并非是一种“漂亮”的解决方案,但如果您想防止模拟旋转同时仍然复制移动,则其也可用于旧版本:

摆脱父/子关系,添加一个新的父游戏对象(如LeviathanCode所建议的),并向其添加一个简单地每帧复制玩家移动的脚本:

public GameObject player; //Drag the "player" GO here in the Inspector    

public void LateUpdate() {
    transform.position = player.transform.position;
}

这样,您的“right_obj”和“left_obj”将不会像玩家一样旋转,但仍会“跟随”它移动。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接