簡體   English   中英

子對象變換位置,旋轉,縮放比例是否偏離原點?

[英]Child object transform position,rotation,scale incorrect away from origin?

我們有一個父對象,我們稱其為RectangleParent ,我們想在此曲面內放置子對象(在我們的情況下為Squares ,在運行時確定的總數在1到10的范圍內)。 在我們的父對象RectangleParent的邊界內,彼此之間並從左到右均勻地隔開兩行(每行最多5項,最多兩行,最大等於10平方)。

編輯開始

在此處輸入圖片說明

結束編輯

示例Unity pkg 在這里

正確的例子:

放置十(10)個對象

tenObjs

五(5)個要放置的物體

FiveObjs

當前結果

當前

注意我們的父對象在原點(父對象是拉長的矩形,子對象是較小的正方形)。 它的孩子可以根據需要放置,滿足所有要求。 放置在父級邊界內,兩行在其父級邊界內彼此均勻地隔開,並且每個子對象彼此均勻地隔開。 如十(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的所有幫助)

您必須像這樣使用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
                            );

在此處輸入圖片說明

使用

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);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM