Решение 1: Используйте Mesh.bounds
Вы можете получить высоту, используя Mesh.bounds
. В отличие от MeshRenderer.bounds
(или Renderer.bounds
), это ограничивающий ось ограничивающий прямоугольник сетки в его локальном пространстве (т.е. не подвержен преобразованию).
Вам по-прежнему необходимо учитывать масштаб объекта GameObject, используя transform.lossyScale
следующим образом:
public class Example : MonoBehaviour
{
private Mesh _mesh;
private void Awake()
{
_mesh = GetComponent<MeshFilter>().mesh;
}
private void Update()
{
float height = _mesh.bounds.size.y * transform.lossyScale.y;
Debug.Log(height);
}
}
(Обратите внимание, что при использовании transform.lossyScale
значение может быть немного неточным. Это то, на что следует обратить внимание, если вам нужна предельная точность. См. документацию по transform.lossyScale :)
Обратите внимание, что если у вас есть родительское преобразование со шкалой и ребенок
то, что произвольно повернуто, масштаб будет перекошен. Таким образом, масштаб может
не будет правильно представлен в 3-компонентном векторе, а только в 3х3
матрица. С таким представлением неудобно работать
тем не мение. lossyScale - это удобное свойство, которое пытается сопоставить
фактический мировой масштаб, насколько это возможно. Если ваши объекты не
искаженное значение будет полностью правильным и, скорее всего, значение
не будет сильно отличаться, если он также содержит перекос.
Решение 2 (Обходной путь): Кэшировать необращенные границы MeshRenderer
В качестве альтернативы, если в вашем контексте вы можете создать экземпляр GameObject
без поворота и вам нужно только повернуть GameObject
после инициализации, одним из обходных решений является кэширование границ из MeshRenderer
в Awake
метод, следующий:
public class Example : MonoBehaviour
{
private Bounds _initialUnrotatedBounds;
private void Awake()
{
InitializeUnrotatedBounds();
}
private void InitializeUnrotatedBounds()
{
Assert.IsTrue(transform.rotation == Quaternion.identity);
_initialUnrotatedBounds = GetComponent<MeshRenderer>().bounds;
}
private void Update()
{
// Use the cached bounds. Now, even for moving objects,
// it doesn't matter if the rotation changes
float height = _initialUnrotatedBounds.size.y;
Debug.Log(height);
}
}