子对象的变换位置,旋转度,缩放度是否偏离原点?

时间:2019-04-29 16:05:38

标签: c# unity3d math 3d transform

我们有一个父对象,我们称其为RectangleParent,并且我们想放置子对象(在我们的情况下为Squares)(运行时确定的总数在1到10的范围内)在这个表面上。在我们的父对象RectangleParent的边界内,彼此之间并且从左到右均匀地隔开了最多两行(每行最多5项,最多两行,最大等于10平方厘米)。

编辑开始

enter image description here

结束编辑

示例Unity pkg here

正确的示例:

十个要放置的对象

tenObjs

要放置的五(5)个对象

fiveObjs

当前结果

current

请注意原始对象的父对象(父对象是拉长的矩形,子对象是较小的正方形)。它的孩子可以根据需要放置,满足所有要求。放置在父级边界内,两行在其父级边界内彼此均匀地隔开,并且每个子对象彼此均匀地隔开。如十(10)个对象示例中所示。

但是请注意,对于不在原点处的父对象-子对象(Squares)未置于其父边界内,两行之间的间距不适合父边界,并且该对象不再是正方形(它们现在看起来像矩形)。但是,每一行中的子对象彼此之间是均匀分布的,因此这里至少满足了一种愿望。

如果我们分配Cube.transform .localPosition 而不是.position

localPosition

原点: 行之间的间距仍然是正确的,但是现在每行中的子对象(正方形)之间的间距不正确,并且所有子对象也未保持在其父范围之内。

原产地: 两行正确对齐,但两行之间的间距不正确。两行不适合其父对象边界。子对象本身有多个问题。它们不是正方形,彼此之间的间距不正确。

那么我们的3d放置数学怎么了?如何固定对象的位置,以便无论父对象在哪里,我们的子对象都位于父对象的边界内?

代码

public class NewBehaviourScript : MonoBehaviour {

    public int NumberOfObjectsToPlace = 10;   //Place 10 objects
    public int maxRows = 5; // how many objects can be placed in a row
    public int maxColumns = 2; // how many objects can be placed in a column

    public GameObject RectangleParent;  //the parentObject instance
    public GameObject CubePrefab;       //the cube prefab

    // Use this for initialization
    void Start () {
        PlaceObjects();
    }

    // Update is called once per frame
    void Update () {

    }

    void PlaceObjects()
    {
        Vector3 center = RectangleParent.GetComponent<MeshRenderer>().bounds.center;
        Vector3 size = RectangleParent.GetComponent<MeshRenderer>().bounds.size;
        Vector3 corner = -new Vector3(size.x / 2, 0, size.z / 2);
        float stepX = size.x / (maxColumns + 1);
        float stepZ = size.z / (maxRows + 2);
        int placedObjects = NumberOfObjectsToPlace;

        for (int i = 0; i < placedObjects; i++)
        {
            GameObject Cube = Instantiate(CubePrefab);
            Cube.transform.parent = RectangleParent.transform;
            Cube.transform.localRotation = Quaternion.identity;
            Cube.transform.position = corner + new Vector3(stepX, 
                center.y + 0.15f, 
                stepZ * 1.5f + i * stepZ
            );

            if (i == maxRows - 1)
            {
                i -= maxRows;
                placedObjects -= maxRows;
                stepX += size.x / (maxColumns + 1);
            }
        }
    }

}

(感谢@ Ali-Baba的所有帮助)

1 个答案:

答案 0 :(得分:2)

您必须像使用RectangleParent的位置和方向

Cube.transform.position = RectangleParent.transform.position 

                          + corner.x * RectangleParent.transform.right 
                          + corner.y * RectangleParent.transform.up 
                          + corner.z * RectangleParent.transform.forward 

                          + stepX * RectangleParent.transform.right 
                          + (center.y + 0.15f) * RectangleParent.transform.up 
                          + (stepZ * 1.5f + i * stepZ) * RectangleParent.transform.forward;

,或者您宁可使用localPosition。这里的问题可能是,如果RectangleParent的小数位数不是1,1,1,则localPosition的值可能会随之缩放,因此您可能想这样做

Cube.transform.localPosition = new Vector3(
                                   corner.x / RectangleParent.transform.localScale.x, 
                                   corner.y / RectangleParent.transform.localScale.y, 
                                   corner.z / RectangleParent.transform.localScale.z)

                               + new Vector3(
                                   stepX / RectangleParent.transform.localScale.x, 
                                   center.y + 0.15f, 
                                   (stepZ * 1.5f + i * stepZ) / RectangleParent.transform.localScale.z
                               );

然后为了正确重置比例,您可能想要做

Cube.transform.localScale = new Vector3(
                                1 / RectangleParent.transform.localScale.x, 
                                1 / RectangleParent.transform.localScale.y, 
                                1 / RectangleParent.transform.localScale.z
                            );

enter image description here

使用

private void PlaceObjects()
{
    var center = RectangleParent.GetComponent<MeshRenderer>().bounds.center;
    var size = RectangleParent.GetComponent<MeshRenderer>().bounds.size;
    var corner = -new Vector3(size.x / 2, 0, size.z / 2);
    var stepX = size.x / (maxColumns + 1);
    var stepZ = size.z / (maxRows + 2);
    var placedObjects = NumberOfObjectsToPlace;

    for (var i = 0; i < placedObjects; i++)
    {
        var cube = Instantiate(CubePrefab);

        cube.transform.parent = RectangleParent.transform;
        cube.transform.localRotation = Quaternion.identity;

        cube.transform.localPosition = new Vector3(
                                           corner.x / RectangleParent.transform.localScale.x,
                                           corner.y / RectangleParent.transform.localScale.y,
                                           corner.z / RectangleParent.transform.localScale.z
                                       )

                                       + new Vector3(
                                           stepX / RectangleParent.transform.localScale.x,
                                           center.y + 0.15f,
                                           (stepZ * 1.5f + i * stepZ) / RectangleParent.transform.localScale.z
                                       );

        cube.transform.localScale = new Vector3(
                                        1 / RectangleParent.transform.localScale.x,
                                        1 / RectangleParent.transform.localScale.y,
                                        1 / RectangleParent.transform.localScale.z
                                    );

        if (i != maxRows - 1) continue;

        i -= maxRows;
        placedObjects -= maxRows;
        stepX += size.x / (maxColumns + 1);
    }
}