Pivot vs center

I’ve seen a lot of posts similar to this but nothing so far that answers the question. You know when you have a prefab of a group of objects highlighted? There is an Editor button at the top left that toggles between “Center” and “Pivot”. Highlight a prefab and switch to “R” for rotation. Keep clicking the Center/Pivot button. Obviously, Unity knows the difference between these two points because you can see the rotator sphere tool shift between the two points (if you object’s pivot isn’t center).

My question is, HOW do I get this offset? I want to throw my prefab into an empty GameObject and then give the single child an offset to counteract this difference. Thus far, I have been eyeballing this shift and changing the X and Z until there was no shift. I want to do this in code. My way is tedious! Please help :slight_smile:

I don’t know how complicated your prefab is, but the actual code used to collect the bounds that gets used for Tools.handlePosition is quite a bit more complex, totally arbitrary, and subject to change.

Today, as of 2017.1/2, it will first include the collider’s bounds. It will then check if the object has a renderer and, if so, add its bounds. If there is no renderer, it will add the bounds of the MeshFilter if there is one. If there is neither a renderer nor mesh filterer, then it moves on to check a variety of component types (Light, which has its own bounds calculation; ReflectionProbe, RectTransform, and then ultimately just its Transform’s position).

The only actual way to get the delta you want programmatically is something like:

Tools.pivotMode = PivotMode.Center;
var center = Tools.handlePosition;
Tools.pivotMode = PivotMode.Pivot;
var delta = center - Tools.handlePosition;

Do you really want the exact same result as Unity gives you? Unity does calculate the bounding volume of all objects selected. This is only based on the worldspace bounds of all Renderers and all Colliders on those objects.

So this should give you the same worldspace position as Unity when you select “center”.:

public static Vector3 CalculateCenter(params Transform[] aObjects)
{
    Bounds b = new Bounds();
    foreach(var o in aObjects)
    {
        var renderers = o.GetComponentsInChildren<Renderer>();
        foreach(var r in renderers)
        {
            if (b.size == Vector3.zero)
                b = r.bounds;
            else
                b.Encapsulate(r.bounds);
        }
        var colliders = o.GetComponentsInChildren<Collider>();
        foreach (var c in colliders)
        {
            if (b.size == Vector3.zero)
                b = c.bounds;
            else
                b.Encapsulate(c.bounds);
        }
    }
    return b.center;
}

Note that this method searches through the whole hierarchy downwards. So if you have a parent object, just pass the parent:

Vector3 center = CalculateCenter(parent);