The TapToPlace
script of the HoloToolkit is a great and simple way to place and anchor holograms in the real world. However, it can be problematic if the hologram is placed out of reach / view from a previous session in another room and you can not tap the hologram to place it closer to you once again.
A good solution is to create another “reset” gesture that triggers object placement even if you don’t directly tap the hologram. An easy way to achieve this is the tap-and-hold gesture, which is one of the standard events the Input Manager of the HoloToolkit can send.
To handle interaction events that don’t target a particular hologram, the current HoloToolkit uses Fallback Input Handlers. However, this functionality isn’t very well documented anywhere. This guide explains how to write a custom fallback input handler.
Handling Fallback Input Events
For the general setup: first, ensure that your Unity HoloLens project includes the InputManager
Prefab from the HoloToolkit. Next, add the standard TapToPlace
script of the HoloToolkit to the game object you want to place in the world.
Now, add the following script HoldAnywhereHandler
to your scene, for example also into the Managers game objects hierarchy where you have placed the InputManager
prefab.
using HoloToolkit.Unity.InputModule; using HoloToolkit.Unity.SpatialMapping; using UnityEngine; public class HoldAnywhereHandler : MonoBehaviour, IHoldHandler { /// <summary> /// Game object to send a fallback hold event to, using a custom "AnywhereHoldCompleted" event. /// </summary> public GameObject SendEventToObject; // Use this for initialization void Start() { Debug.Log(gameObject.name + " : Registering as fallback input handler."); // Register using the singleton input manager instance of the HoloToolkit InputManager.Instance.PushFallbackInputHandler(gameObject); } public void OnHoldCompleted(HoldEventData eventData) { Debug.Log(gameObject.name + " : Received fallback OnHoldCompleted event. " + Time.time); if (SendEventToObject != null && SendEventToObject.GetComponent<TapToPlace>() != null) { // Send custom event to the registered game object var receivingObject = SendEventToObject.GetComponent<TapToPlace>(); if (!receivingObject.IsBeingPlaced) { receivingObject.OnInputClicked(null); } //SendEventToObject.SendMessage("AnywhereHoldCompleted", null); } } public void OnHoldStarted(HoldEventData eventData) { // Implementation not needed, but method required from interface } public void OnHoldCanceled(HoldEventData eventData) { // Implementation not needed, but method required from interface } }
The script will register itself as the fallback input handler for any hold events that the user performs while not looking at a hologram. Accessing the input manager instance of the HoloToolkit works using the singleton pattern.
In this case, we are only interested in the event when the hold gesture has been completed: OnHoldCompleted
. Whenever we get this, we simulate the click event for the pre-configured target object. We do not need to send any event parameters, as the standard TapToPlace
script does not use the parameters. In order to not accidentally ending the placement, we only send the click event if the hologram is not already being placed.
Script Configuration
The only final step is to assign the target hologram that we want to place. To do this, drag the placeable game object (that has the TapToPlace
script assigned) to the configuration section of the new HoldAnyhwereHandler
script.
As a result, you can tap and hold anywhere in the world to start placement of the hologram. You don’t need to hit the object anymore with your tap gesture as required by the default TapToPlace
script of the HoloToolkit.