The Gizmo class allows you to register event handlers for different types of events. For example, you can register event handlers for when a gizmo is enabled, disabled, dragged etc. This is useful when your application needs to perform different types of actions in response to such events.

Pre and Post Events

All event properties are prefixed with one of the following 2 prefixes: Pre or Post. Events prefixed with Pre are fired BEFORE the gizmo updates its internal data in response to the event. Those prefixed with Post are fired AFTER the gizmo updates its internal data. It is recommended to always use the Post events.

The following sections will discuss only the Post events as these are the ones you should use in your application. It is worth mentioning however that Pre events have the same signature and have the same meaning. The only difference is the time at which they are fired.

Gizmo Enabled/Disabled

When a gizmo is enabled or disabled, it fires the following 2 events:

  • PostEnabled - fired after the gizmo has been enabled;
  • PostDisabled - fired after the gizmo has been disabled;

The event handlers must have the following signature:

void OnGizmoPostEnabledHandler(Gizmo gizmo);
void OnGizmoPostDisabledHandler(Gizmo gizmo);

The handlers must accept a single parameter which is a reference to the gizmo that fired the event.

You could use these handlers to take action when the active selection gizmo changes. For example, you could have the following 2 handlers that play different sound effects when an object selection gizmo is enabled or disabled:

private void OnSelectionGizmoEnabled(Gizmo gizmo)
{
    int gizmoId = RTObjectSelectionGizmos.Get.GetGizmoId(gizmo);
    if (gizmoId == ObjectSelectionGizmoId.MoveGizmo)
    {
        // Play sound effect for move gizmo enabled
    }
    else 
    if (gizmoId == ObjectSelectionGizmoId.RotationGizmo)
    {
        // Play sound effect for rotation gizmo enabled
    }
    /*
    else ... and so on for other gizmos
    */
}

private void OnSelectionGizmoDisabled(Gizmo gizmo)
{
    int gizmoId = RTObjectSelectionGizmos.Get.GetGizmoId(gizmo);
    if (gizmoId == ObjectSelectionGizmoId.MoveGizmo)
    {
        // Play sound effect for move gizmo disabled
    }
    else 
    if (gizmoId == ObjectSelectionGizmoId.RotationGizmo)
    {
        // Play sound effect for rotation gizmo disabled
    }
    /*
    else ... and so on for other gizmos
    */
}

Then you could register these event handlers with the object selection gizmos like so:

// This example registers the event handlers with all gizmos, but you can register 
// an event with specific gizmos if desired.
List<Gizmo> allGizmos = RTObjectSelectionGizmos.Get.GetAllGizmos();
foreach(Gizmo gizmo in allGizmos)
{
    gizmo.PostEnabled += OnSelectionGizmoEnabled;
    gizmo.PostDisabled += OnSelectionGizmoDisabled;
}

Gizmo Update End

All gizmos are managed by the RTGizmosEngine MonoBehaviour. During each frame, the gizmo engine will update the gizmos which, in a nutshell, means the following:

  1. inform the gizmos that the update step has begun;
  2. Perform update step (identify hovered handle, handle mouse events, begin drag sessio etc);
  3. inform the gizmos that the update step has ended;

Note: This list does not correctly reflect what is actually happening. But it was presented in this manner in order to keep things simple.

Suffice to say that during each frame, the gizmos are subject to an update step. The Gizmo class uses the PostUpdateEnd event to let the application know then the update step for that gizmo has finished.

The function signature for the event handler must look like this:

void OnGizmoPostUpdateEnd(Gizmo gizmo);

The handler must receieve a reference to the gizmo which fires the event.

A simple example:

private void OnGizmoPostUpdateEnd(Gizmo gizmo)
{
    int gizmoId = RTObjectSelectionGizmos.Get.GetGizmoId(gizmo);
    if (gizmoId == ObjectSelectionGizmoId.MoveGizmo)
    {
        // Write code which should be executed then the move gizmo ends its update step
    }
    /*
    else ... and so on for other gizmos
    */
}

You could register this handle in the following way:

// This example registers the event handler with all gizmos, but you can register 
// an event with specific gizmos if desired.
List<Gizmo> allGizmos = RTObjectSelectionGizmos.Get.GetAllGizmos();
foreach(Gizmo gizmo in allGizmos)
{
    gizmo.PostUpdateEnd += OnGizmoPostUpdateEnd;
}

Gizmo Hover Enter/Exit

If you need to know when a gizmo enters or exits a hover state, you can use the following events:

  • PostHoverEnter;
  • PostHoverExit;

The event handlers must have the following signature:

void OnGizmoPostHoverEnter(Gizmo gizmo, int handleId);
void OnGizmoPostHoverExit(Gizmo gizmo, int handleId);

Both handlers must accept a reference to the gizmo that fires the event and an integer which represents the id of the handle that entered or exited the hover state. Plese see Gizmo Handle Ids for a complete list of handle ids and how they map to the gizmo handles.

Here is a simple implementation af the PostHoverEnter event handler which can be used to play a sound effect when a gizmo enters a hover state:

private void OnGizmoPostHoverEnter(Gizmo gizmo, int handleId)
{
    int gizmoId = RTObjectSelectionGizmos.Get.GetGizmoId(gizmo);
    if (gizmoId == ObjectSelectionGizmoId.MoveGizmo)
    {
        /* You could filter further based on the handle id:
        switch(handleId)
        {
            case GizmoHandleId.PXSlider:

                // Play hover enter sound when the positive X axis slider is hovered

            ... and so on for other handle Ids
        }
        */
    }
    /*
    else ... and so on for other gizmos
    */
}

Same could could be written for the PostHoverExit event.

Gizmo Handle Picked

The Gizmo class fires an event when you click on one of its handles. The event is called PostHandlePicked and the handler signature must look like this:

void OnGizmoPostHandlePicked(Gizmo gizmo, int handleId);

The handler must accept a reference to the gizmo which fires the event and the id of the handle that was clicked on.

You can register the event handler like so:

// This example registers the event handler with all gizmos, but you can register 
// an event with specific gizmos if desired.
List<Gizmo> allGizmos = RTObjectSelectionGizmos.Get.GetAllGizmos();
foreach(Gizmo gizmo in allGizmos)
{
    gizmo.PostHandlePicked += OnGizmoPostHandlePicked;
}

Gizmo Drag Begin/Update/End

When you click on a gizmo handle, the gizmo will fire up a PostDragBegin event. As long as the mouse button is pressed, when the mouse is moved, the gizmo will fire a PostDragUpdate event. When you release the left mouse button, the gizmo will fire a PostDragEnd event.

The handler signatures must look like this:

void OnGizmoPostDragBegin(Gizmo gizmo, int handleId);
void OnGizmoPostDragUpdate(Gizmo gizmo, int handleId);
void OnGizmoPostDragEnd(Gizmo gizmo, int handleId);

All handlers must accept a reference to the gizmo which fired the event and the id of the handle which is involved in the drag session.

The following is an example of a PostDragUpdate handler which checks the type of drag output and performs different tasks based on the output type:

private void OnGizmoPostDragUpdate(Gizmo gizmo, int handleId)
{   
    GizmoDragChannel dragChannel = gizmo.ActiveDragChanne;
    if (dragChannel == GizmoDragChannel.Offset)
    {
        Vector3 relativeOffset = gizmo.RelativeDragOffset;
        // Do something with relative offset
    }
    else 
    if (dragChannel == GizmoDragChannel.Rotation)
    {
        Quaternion relativeRotation = gizmo.RelativeRotation;
        // Do something with relative rotation
    }
    else 
    if (dragChannel == GizmoDragChannel.Scale)
    {
        Vector3 relativeScale = gizmo.RelativeScale;
        // Do something with relative scale
    }
}

This handler checks what type of output the gizmo has produced (offset, position or scale) and then it retrieves a relative drag value which can then be used for different purposes.

Handler registration can be done like so:

// This example registers the event handlers with all gizmos, but you can register 
// an event with specific gizmos if desired.
List<Gizmo> allGizmos = RTObjectSelectionGizmos.Get.GetAllGizmos();
foreach(Gizmo gizmo in allGizmos)
{
    gizmo.PostDragBegin += OnGizmoPostDragBegin;
    gizmo.PostDragUpdate += OnGizmoPostDragUpdate;
    gizmo.PostDragEnd += OnGizmoPostDragEnd;
}

Gizmo Drag Begin Attempt

When you click on a gizmo handle, the gizmo will attempt to begin a drag session. So before a drag session begins, the gizmo will fire the PostDragBeginAttempt event. You don't need to worry about when or why a drag session might be rejected. Suffice to say, in virtually 100% of the cases, the attempt will be successful. This event is mostly used for special scenarios (e.g. all gizmos will use this event to fill the drag session data structure with the necessary data before it begins).

The handler signature must look like this:

void OnGizmoPostDragBeginAttempt(Gizmo gizmo, int handleId);

The handler must accept a reference to the gizmo which fires the event and the id of the handle which will be involved in the drag session.

Note

If your application captures this event, it should ignore the gizmo drag information. The gizmo drag information is not ready when this event is fired.

Handler registration can be done like so:

// This example registers the event handler with all gizmos, but you can register 
// an event with specific gizmos if desired.
List<Gizmo> allGizmos = RTObjectSelectionGizmos.Get.GetAllGizmos();
foreach(Gizmo gizmo in allGizmos)
{
    gizmo.PostDragBeginAttempt += OnGizmoPostDragBeginAttempt;
}

Drag Session Begin Events

Although not immediately obvious, the previous sections have covered 3 events which occur one after the other when the left mouse button is clicked:

  • PostHandlePicked;
  • PostDragBeginAttempt;
  • PostDragBegin;

So when a gizmo handle is clicked, the following events will be fired:

  1. PostHandlePicked;
  2. PostDragBeginAttempt;
  3. IF (AttemptSuccessful) FIRE PostDragBegin;