Положение, вращение, масштаб дочернего объекта неверно от исходного положения? - PullRequest
0 голосов
/ 29 апреля 2019

У нас есть родительский объект, назовем его RectangleParent, и мы хотим разместить дочерние объекты, в нашем случае Squares (общее значение, определенное во время выполнения в диапазоне 1-10) в пределах этой поверхности.Как внутри границ нашего родительского объекта, RectangleParent, равномерно отстоящих друг от друга, так и слева направо максимум в две строки (максимум 5 элементов в строке, максимум в две строки, равно максимум 10 квадратных).

EDIT начало

enter image description here

end EDIT

ОбразецUnity pkg здесь

Правильный пример (ы):

Десять (10) объектов для размещения

tenObjs

Пять (5) объектов для размещения

fiveObjs

Текущий результат

current

Обратите внимание на наш родительский объект в начале координат (родительские объекты - это вытянутые прямоугольники, дочерние объекты - меньшие квадраты).Это дети расставлены по желанию, отвечающие всем требованиям.Размещенные в пределах родительских границ, Два ряда равномерно отстоят друг от друга в пределах родительских границ, и Каждый дочерний объект равномерно расположен друг от друга.Как показано в примере с Десятью (10) объектами.

Но затем обратите внимание, что для родительского объекта, не расположенного в источнике - дочерних объектов (квадратов), не расположенных в пределах границ своих родителей, расстояние между двумя строками невписывается в границы родителей, и объекты больше не являются квадратами (теперь они выглядят как прямоугольники).Однако дочерние объекты в каждой строке равномерно распределены между собой, поэтому здесь встречается хотя бы одно желание.

Если мы назначим 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);
            }
        }
    }

}

(спасибо @ Али-Бабе за помощь)

1 Ответ

2 голосов
/ 29 апреля 2019

Вы должны использовать положение и направления 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);
    }
}
...