如何在添加子对象时阻止transform.position被修改?

我怀疑有一个众所周知的,很容易解释我看到的行为的原因,但我很难解释它(可能无法谷歌的答案)。

在向已翻译的父项添加子localPosition会修改子项的localPosition ,以便在应用父项转换子项的position保持不变。 有没有办法这样的情况?

在下面的示例中,我创建一个父对象并将其移动到(1,1,1) ,然后附加该子对象。 我希望孩子的位置是(1,1,1) ,即(0,0,0)相对于父母。 然而,孩子的位置被修改为(-1,-1,-1)因此它相对于世界是(0,0,0)

这是一个repro:

 // Create parent. GameObject parent = new GameObject(); parent.name = "Parent GameObject"; parent.transform.parent = foregroundObject.transform; // Move the parent. parent.transform.Translate(1, 1, 1); // Add a child under the parent GameObject. GameObject child = (GameObject) GameObject.Instantiate(guildiePrefab); child.name = "Child GameObject"; child.transform.parent = parent.transform; // PROBLEM: localPosition is set so that the "global" position is (0,0,0). // How can I add the child object and have its position be (1,1,1)? this.Assert(child.transform.localPosition.ToString() == "(-1.0, -1.0, -1.0)"); this.Assert(child.transform.position.ToString() == "(0.0, 0.0, 0.0)"); 

有没有不同的方式,我应该添加child作为parent的孩子? 或者,在添加孩子之前,我是否应该总是parent的位置清零? 如果是这样的话,我需要这样做的任何理由? 这个deviseselect的合理性是什么?

当您使用Instantiate的默认构造函数Instantiate ,位置设置为(0,0,0)。 您可以使用Instantiate的替代构造函数,并提供一个位置和旋转。 如果您希望子对象相对于父级位置为零,则可以提供父级位置作为实例化的位置。

 GameObject child = (GameObject) GameObject.Instantiate(guildiePrefab, parent.transform.position, parent.transform.rotation); child.name = "Child GameObject"; child.transform.parent = parent.transform; 

或者,如果您有一个特定的偏移量,您只需在实例化时将其添加到位置即可:

 GameObject child = (GameObject) GameObject.Instantiate(guildiePrefab, parent.transform.position + offset, parent.transform.rotation); 

不管怎样,检查员标签中显示的孩子的位置将是孩子相对于父母的位置。 通过transform.positionfind的孩子的位置将是世界的立场。

有一个不同的方法。

代替:

 child.transform.parent = parent.transform; 

使用:

 child.transform.SetParent(parent.transform, false) 

false参数指定不执行您正在讨论的相对调整。

我猜它的默认不这样做的原因是因为代码通常是从编辑器调用,在这种情况下,你可能不希望你分配给一个新的父对象的对象突然重新定位它在父母身上。