Узнать на сколько нужно сместить после скейла объекта

Есть код:

Transform Transform = Transforms();
for (int i = 0; i < Transform.childCount; ++i) {
    Transform Obj = Transform.GetChild(i);
    Obj.localScale *= 1.5f;
}

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


Ответы (1 шт):

Автор решения: RiotBr3aker

По-хорошему, эта проблема должна решаться на уровне создания полигональной сетки. Любой объект имеет так называемый pivot point, относительно которого и позиционируются вершины полигонов. В том числе с помощью этой точки объекты масштабируются с помощью scale'а.


Данное решение подходит только для объектов с pivot'ом в центре

Но, допустим, нам нужно решить это именно в коде. Все просто - нужно использовать AABB и немного математики:

Любой объект имеет Axis Aligned Bounding Box - данный объект гарантированно вписан в этот прямоугольник. Это очень грубое приближение, однако, в данной задаче это приближение никакого влияния на конечный результат не окажет.

Из этого AABB можно получить высоту объекта, вернее половину его высоты:

float objectExtent = GetComponent<MeshFilter>().sharedMesh.bounds.extents.y;

И на этом все решение и заканчивается, ведь увеличение объекта в n раз перемешает его центральную точку на (высота * n) / 2.

Transform parent = Transforms();
for (int i = 0; i < parent.childCount; ++i) {
    var _transform = parent.GetChild(i);
    var extentY = _transform.GetComponent<MeshFilter>().sharedMesh.bounds.extents.y;

    var pos = _transform.position;
    var scale = _transform.localScale;

    pos.y -= extentY * scale.y;

    scale *= 1.5f;
    _transform.localScale = scale;

    pos.y += extentY * scale.y;
    _transform.position = pos;
}

Очевидно, что вызывать GetComponent<MeshFilter>().sharedMesh.bounds.extents.y каждый раз - медленно. AABB у MeshFilter всегда одинаковый, вне зависимости от текущего scale'а, поэтому это значение можно закешировать и переиспользовать.

→ Ссылка