The transform pivot allows you to specify a point of origing for the transform. The following transform pivots are available:

  • ObjectGroupCenter - when multiple objects are selected, the center of the object collection is used as a pivot. When a single object is selected, the center of the object's bounds is used. When this pivot is active, the gizmo will sit at the center of the object collection;
  • ObjectMeshPivot - this is the pivot as was defined inside the modeling software and is the same as the position of the game object (i.e. gameObject.transform.position). When this pivot is active, the gizmo will sit at the position of one of the selected objects;
  • ObjectCenterPivot - this is the center of an object's bounding volume. The gizmo will sit at the center of one of the object's volume center;
  • CustomWorldPivot - a world position specified by you via a function call. When this pivot is active, the gizmo will sit at this position in the 3D world;
  • CustomObjectLocalPivot - a pivot which is defined in the local space of an object. When this pivot is active, the gizmo position will be set to the postion of the local pivot transformed in world space.

In order to change the transform pivot, you can call the following function:

// Change the pivot to mesh pivot
RTObjectSelectionGizmos.Get.SetTransformPivot(GizmoObjectTransformPivot.ObjectMeshPivot);

This function call will affect the following gizmos:

  • MoveGizmo;
  • RotationGizmo;
  • ScaleGizmo;
  • UniversalGizmo;

In order to change the transform pivot for a specific gizmo, you need to write the followin code:

// Change the rotation gizmo pivot to mesh pivot
var gizmo = RTObjectSelectionGizmos.Get.GetGizmoById(ObjectSelectionGizmoId.RotationGizmo);
gizmo.ObjectTransformGizmo.SetTransformPivot(GizmoObjectTransformPivot.ObjectMeshPivot);

Note

The CustomWorldPivot and CustomObjectLocalPivot pivots are mostly useful when dealing with rotation or scale. They are less useful when working with the move gizmo for example. In fact, using the CustomWorldPivot in conjunction with the move gizmo is actually quite confusing. This is because after you drag the gizmo to move the objects around, the gizmo will then have to go back to its resting place which is the custom world pivot position. This means that at some point the gizmo will sit really far away from the objects you are transforming.

So it is recommended to use these 2 pivots with the rotation and scale gizmos as this is the main reason why they were implemented in the first place.

The Custom World Pivot

This pivot is useful when you need to rotate or scale objects from a fixed point in space. For example, let's assume that the user is trying to build a space scene in which a bunch of alien motherships are approaching Earth. In this case you could provide an interface for the user to set the rotation pivot to the world position of the Earth object. Then they can easily rotate the motherships around the Earth sphere object.

Here is an example of how this could be done from code:

var rotationGizmo = RTObjectSelectionGizmo.Get.GetGizmoById(ObjectSelectionGizmo.RotationGizmo);
rotationGizmo.ObjectTransformGizmo.SetTransformPivot(GizmoObjectTransformPivot.CustomWorldPivot);
rotationGizmo.ObjectTransformGizmo.SetCustomWorldPivot(earthObject.transform.position);

The Custom Object Local Pivot

Use this pivot when you need to rotate or scale objects from a point defined in an object's local space. This might seem confusing in the begining, but it is actually really easy if you think about it and quite useful. For example, let's assume you have a door object in the scene, but the door mesh has been created in the modeling software such that its pivot sits in the center of the mesh. You want to be able to rotate the door in such a way that it rotates around the point where the door is connected to a wall to make it look like it is actually opening and closing as doors do in real life.

You could use the CustomWorldPivot for this, but this means that every time the door object is moved to a new spot, the custom world pivot position needs to be recalculated. And this is where the local pivot comes in handy. Because this pivot is a position expressed in the local space of an object, the pivot will follow wherever the object goes. More than that, it will also take the rotation and scale of the obejct into account so regardless of how the object is transformed, the pivot will still be where you expect it to be.

Here is an example code that can be used to change the transform pivot for the rotation gizmo:

// First we need to retrieve the desired pivot in world space. This example will assume that the door object as been
// created in such a way that the desired pivot sits on the door's left side. We first call CalcHierarchyWorldOOBB
// to calculate the door's oriented bounding volume (a box with center, size and rotation) and then we calculate the
// center of the OOBB's left face by calling CalcBoxFaceCenter.
// Note: This is just an example. You might have other means for calculating the pivot.
OOBB doorOOBB = ObjectBounds.CalcHierarchyWorldOOBB(doorObject, ObjectBounds.DefaultQConfig);
Vector3 pivotFaceCenter = BoxMath.CalcBoxFaceCenter(doorOOBB.Center, doorOOBB.Size, doorOOBB.Rotation, BoxFace.Left);

// Retrieve the rotation gizmo and set its trasnform pivot to CustomObjectLocalPivot. Also,
// we need to call SetObjectCustomLocalPivot to map the door object to the pivot. 
// Note: The pivot we calculated earlier is in world space, but the function requires a pivot expressed in object local
//       space. So we need to call InverseTransformPoint before feeding it to the function.
var rotationGizmo = RTObjectSelectionGizmos.Get.GetGizmoById(ObjectSelectionGizmoId.RotationGizmo);
rotationGizmo.ObjectTransformGizmo.SetTransformPivot(GizmoObjectTransformPivot.CustomObjectLocalPivot);
rotationGizmo.ObjectTransformGizmo.SetObjectCustomLocalPivot(doorObject, doorObject.transform.InverseTransformPoint(pivotFaceCenter));