У нас есть родительский объект, назовем его RectangleParent, и мы хотим разместить дочерние объекты, в нашем случае Squares, (общее количество определяется во время выполнения в диапазоне от 1 до 10) внутри этой поверхности. Оба внутри границ нашего родительского объекта, RectangleParent, на равном расстоянии друг от друга и слева направо максимум в двух рядах (максимум 5 элементов в ряду, максимум два ряда, максимум 10 квадратов).
РЕДАКТИРОВАТЬ начало
конец РЕДАКТИРОВАТЬ
Образец пакета Unity здесь
Правильный пример(ы):
Десять (10) объектов для размещения
Пять (5) объектов для размещения
Текущий результат
Обратите внимание на наш родительский объект в начале координат (родительские объекты — вытянутые прямоугольники, дочерние объекты — квадраты меньшего размера). Его дети размещаются по желанию, отвечая всем требованиям. Размещены в родительских границах, две строки на равном расстоянии друг от друга в пределах своих родительских границ, и каждый дочерний объект равномерно удален друг от друга. Как показано в примере с десятью (10) объектами.
Но затем обратите внимание, что для родительского объекта, расположенного не в начале координат, дочерние объекты (квадраты) не помещены в границы своих родителей, интервал между двумя строками не соответствует границам родителей, и объекты больше не являются квадратами (они выглядят как теперь прямоугольники). Однако дочерние объекты в каждой строке расположены на равном расстоянии друг от друга, поэтому здесь выполняется по крайней мере одно желание.
Если мы назначим Cube.transform.localPosition вместо .position
По происхождению: Расстояние между строками по-прежнему правильное, но теперь расстояние между дочерними объектами (квадратами) в каждой строке неверно, а также все дочерние объекты не укладываются в границы своих родителей.
Вдали от происхождения: Две строки выровнены правильно, но интервал между двумя строками неправильный. Две строки не вписываются в границы своих родительских объектов. Сами дочерние объекты имеют множество проблем. Они не квадраты, и расстояние между ними неправильное.
Так что же не так с нашей 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);
}
}
Я не знаю, что именно вы имеете в виду .. у меня это работает, смотрите добавленный gif.
это выглядит почти там! См. иллюстрацию, добавленную к op. Это фиксирует пространство между дочерними элементами при назначении
localPosition, но две строки все еще находятся за пределами своего родителя (используя ваше альтернативное решение)