How to measure the height of 3D objects.

3D objects with different shapes are stacked at some point. And I want to measure the maximum height of the point. Each 3D object is a thing, not a simple figure. As objects stacked, their heights also change. How should i measure the height? First, the way I think is: It is a way to use trigger. Move the trigger up and wait for OnTriggerExit() to be called. Is there a better way than this?

Use a bounding box to calculate the height

The quickest and most accurate calculation is with Collider.bounds.size. Here is an example script that will grab the total bounding box size of all child objects under the object it is attached to. Then you simply grab the y value of the bounding box size to get the overall height.

using UnityEngine;

public class BoundsDebug : MonoBehaviour
{
    // Visual display of the bounding box for testing.
    private void OnDrawGizmos()
    {
        // Draw each child's bounds as a green box.
        Gizmos.color = new Color(0f, 1f, 0f, 0.3f);
        foreach (var child in GetComponentsInChildren<Collider>())
        {
            Gizmos.DrawCube(child.bounds.center, child.bounds.size);
        }

        // Draw total bounds of all the children as a white box.
        Gizmos.color = new Color(1f, 1f, 1f, 0.1f);
        var maxBounds = GetMaxBounds(gameObject);
        Gizmos.DrawCube(maxBounds.center, maxBounds.size);
        Debug.Log("Total height is " + maxBounds.size.y);
    }

    Bounds GetMaxBounds(GameObject parent)
    {
        var total = new Bounds(parent.transform.position, Vector3.zero);
        foreach (var child in parent.GetComponentsInChildren<Collider>())
        {
            total.Encapsulate(child.bounds);
        }
        return total;
    }
}

This script will produce the following results in the editor when you place game objects with colliders under a game object with this script attached to it.
101672-bounds-test.png
It works quite well, but you’ll notice that the upper left object here has gaps around it. This is because it appears that mesh colliders are automatically converted into box colliders for bounds calculations and this is what produces the gaps you see for non-square objects when rotated.

Use a raycast hit to calculate the height

Alternatively you could use a raycast to get more accurate readings for mesh colliders. However, the problem with this is you would need to figure out where to shoot the ray from to actual get the very top of the object. This would be no easy task, so it’s probably a better idea to just check the actual height of the vertices on the meshes instead as suggested by fafase.

If you need exact value, you can use the mesh and iterate through the vertices. If you consider the bottom object wont change because it is below it all, you can just store that guy for the rest.

  1. Get highest object
  2. Get lowest object ( you store this one as it may be the first item to be placed)
  3. Iterate vertices from 1 to find highest y value
  4. iterate vertices from 2 to find lowest y value (store that one if not likely to change)
  5. Do 3 - 4 to get the distance

Make sure that for steps 3 and 4 you convert their position to world space (vertex value is local space).

This will give exact distance regardless of the collider shape or the rotation of the objects.

As mentioned in the comment, you can use generation process to find the highest object on top. Iterate the collection of placed items, when one failed to be on top after 3 runs (or 4, or 2) remove it as it will never be on top. This will gradually set your collection to only the top items. Then iterate the y values only if you have a new topper.

If the object has a renderer,

Vector3 sizeVec = GetComponent<Renderer>().bounds.size;

Next best thing would probably be collider

Vector3 sizeVec = GetComponent<Collider>().bounds.size;

Debug.Log(sizeVec.x);
Debug.Log(sizeVec.y);
Debug.Log(sizeVec.z);

You can also watch this video tutorial