How to handle UI Events in Unity for VR
Join 6000+ Students
Upgrade your programming skills to include Virtual Reality. A premium step-by-step training course to get you building real world Virtual Reality apps and website components. You’ll have access to 40+ WebVR & Unity lessons along with their source code.
Start Learning Now
So far we worked on getting the system to work with the Gear VR with which we could handle the Gaze and TouchPad Events. It even works with the Touch Controller if you so desire to use that. In this we will create a UI with multiple nested Elements. In this tutorial, we’ll see how to handle UI events in Unity.
If we need to create custom animations or behaviour for our UI Components we use Event Triggers. Event Triggers contain event types like OnPointerEnter, Exit, Click etc. A callback can be passed to these triggers which are triggered when their respective event occurs. More info on them here in Unity’s docs.
UI Events in Unity
Generally in UI Events for Unity, event bubbling occurs. This means that when you click on a UI component which has a Raycast or a Collider based event capturing, it will being traversing up the object hierarchy for a handler of that particular event starting from the innermost. This happens until a Handler handles that event. But if we use Event Triggers they stop event bubbling and will intercept all events.
This creates problems when we have nested elements like in this case. ScrollView has elements inside it which need the OnPointer, OnPointerExit and Click events. The inner elements would intercept all of the events and the scrolling of the ScrollView would not work, which is very important in VR.
Solving issues with UI Events for Unity
The solution to this is rather elegant and simple. We can use the UnityEngine.EventSystems which contains interfaces for all the Handlers for our events. The whole list can be found here. We can then implement these Handlers in our Classes and our Gameobject will only intercept the handled events and propagate the unhandled one’s up the Hierarchy for the parent objects to handle.
We can also capture an event in the child GameObject and pass the event up explicitly using the EventSystems.ExecuteHierarchy() Method.
Let’s create a ScrollView which contains Items which would change to Gray Color on Hover and Green Color on Selecting them.
- Create a ScrollView under our world space canvas. on Canvas > Create > UI > Scrollview.
- Set the Canvas Position to (0,0) and reduce its scale to very small like 0.002 on all axis so that we can see the Canvas with our OVRCamera. I set my width and height to 1920X1080.
- Now that the Canvas is visible in our Game View, Anchor the ScrollView to the Centre of the canvas and stretch on all corners.
- Lets populate the ScrollView with elements. Im creating Image components which will have behaviours attached to them.
- Create a script called OnHover.cs which we will attach to all of our Images in the scroll view.
- First we add required namespaces.In this case the EventSystems.
12345using UnityEngine;using System.Collections;using UnityEngine.EventSystems;
Then we implement the required Handlers and create the Handler functions which take PointerEventData Type as parameters. These methods will be called when that event occurs. Note that the Handler’s methods need to be present else Unity will throw an error.
1234567891011121314151617181920public class OnHover : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler {public void OnPointerEnter(PointerEventData eventData){}public void OnPointerExit(PointerEventData eventData){}public void OnPointerClick(PointerEventData eventData){}}Now we can create our Behaviour or Animations for the elements.Add the Following to use the UI class
123using UnityEngine.UI;123private Image image;To avoid NullReferences, we can add the following on top of our class. When we add this script to any component it will automatically add an Image component as well.
123[RequireComponent(typeof(Image))]We then get the Image in the Start() method.
123456void Start(){image = GetComponent<Image> ();}Creating Methods to show the Color shift on Hover and Click.
12345678910111213141516void OnHoverEnter(){image.color = Color.gray;}void OnHoverExit(){image.color = Color.white;}void OnClick(){image.color = Color.blue;}Finally we can call these methods from our handlers. This is our complete script now.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849using UnityEngine;using UnityEngine.UI;using System.Collections;using UnityEngine.EventSystems;[RequireComponent(typeof(Image))]public class OnHover : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler {private Image image;void Start(){image = GetComponent<Image> ();}public void OnPointerEnter(PointerEventData eventData){OnHoverEnter ();}public void OnPointerExit(PointerEventData eventData){OnHoverExit ();}public void OnPointerClick(PointerEventData eventData){OnClick ();}void OnHoverEnter(){image.color = Color.gray;}void OnHoverExit(){image.color = Color.white;}void OnClick(){image.color = Color.blue;}} - Save the file and let it compile in Unity. Add the script to all the images in the scrollview and set the content size properly.If you wish to use Dynamic scroll view then checkout Enhanced Scroller from the asset store as it works perfectly with VR.
- You can now build away and test it on your Gear VR. Don’t forget to add the .osig file to the project folder. This is the final output.