How to evenly space object based on their average distance from eachother.,How can i set multiple objects to be evenly spaced based on their average distance from eachother?
So im making a program thats supposed to take an input in form of a number of rectangles in a column that are unevenly spaced. It should then find the average distance between theese rectangles and set their distances from eachother so that they are evenly spaced.
For example, if the boxes are placed like this: I would want the program to place them like so:
Thanks in advance!:),So im making a program thats supposed to take an input in form of a number of rectangles in a column that are unevenly spaced. It should then find the average distance between theese rectangles and set their distances from eachother so that they are evenly spaced.
For example, if the boxes are placed like this: I would want the program to place them like so:
Thanks in advance!:)
Answer by jmhoubre · Dec 17, 2021 at 10:09 PM
Try this script on an empty object :
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Rule : align the centers on X axis on the highest rectangle.
/// Rule : align the centers on Y axis from the highest rectangle (highest and lowest don't move).
/// </summary>
public class EvenlySpacedRectangles : MonoBehaviour
{
// In inspector, add all the rectangles to evenly space.
[SerializeField] private List<Transform> chaosRectangles;
// Custom sort method.
private IComparer<Transform> yPositionComparer;
private void Start ()
{
// Initialize the sort method.
yPositionComparer = new RectangleReverseSortByY ();
Space ();
}
public void Space ()
{
// Stop 1 : sort the rectangles by y position, form highest to lowest.
chaosRectangles.Sort (yPositionComparer);
// Step 2 : compute the highest (first in the list) and the lowest (the last).
float highest = chaosRectangles[0].position.y;
Debug.Log ($"highest : {highest}");
float lowest = chaosRectangles[chaosRectangles.Count - 1].position.y;
Debug.Log ($"lowest : {lowest}");
// Step 3 : compute the distance between two centers,
float distance = highest - lowest;
Debug.Log ($"distance between centers : {distance}");
// then remove the height of each rectangle,
foreach (Transform t in chaosRectangles)
{
distance -= t.lossyScale.y;
}
// and add the half height of the first and the last (avoid putting some if).
distance += chaosRectangles[0].lossyScale.y * 0.5f;
distance += chaosRectangles[chaosRectangles.Count - 1].lossyScale.y * 0.5f;
Debug.Log ($"final distance : {distance}");
// Step 4 : compute the distance between 2 rectangles.
distance /= chaosRectangles.Count - 1;
Debug.Log ($"free space : {distance}");
// Step 5 : move the rectangles from the highest.
Vector3 origin = chaosRectangles[0].position;
Debug.Log ($"Origin Y : {origin.y}");
// We correct heightPredecessors.
float heightPredecessors = 0f;
// Each rectangle (except the first) is down from the offset and the height from predecessors.
for (int i = 1; i < chaosRectangles.Count; i++)
{
heightPredecessors += (chaosRectangles[i - 1].lossyScale.y + chaosRectangles[i].lossyScale.y) * 0.5f;
Debug.Log ($"heightPredecessors : {heightPredecessors}");
chaosRectangles[i].position = origin + (Vector3.down * (heightPredecessors + (i * distance)));
Debug.Log ($"Position Y : {chaosRectangles[i].position.y}");
}
}
}
public class RectangleReverseSortByY : IComparer<Transform>
{
public int Compare (Transform x, Transform y)
{
if (x.position.y.CompareTo (y.position.y) < 0)
{
return 1;
}
else if (x.position.y.CompareTo (y.position.y) > 0)
{
return -1;
}
else
{
return 0;
}
}
}
Your answer
![](https://koobas.hobune.stream/wayback/20220613050634im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Delete item in inventory 0 Answers
Google play services won't start. 0 Answers
Lerping Camera Between Two Points 0 Answers
C# Newbie Programming Questions 0 Answers
Hiding part of mesh 0 Answers