Abstract selection menu UI

The next feature we want to add is the ability to choose different frames and photo images for your pictures. For this, we'll develop a menu element using a modal design pattern. When a menu is activated, the user is presented with a set of choices. When a choice is selected, the choice is applied and the menu closes. It is modal because the menu remains active until the user has made his or her choice.

We will begin by writing an abstract PictureMenu class that implements the basic functionality of a menu. Then we'll use it for selecting the frames and images of the picture.

In our framework, a menu will be enabled by making it active in the Unity scene (using SetActive). When an object is activated, Unity will call OnEnable(), which we can use to begin using the menu. The abstract PictureMenu class expects the following methods in the derived classes:

  • InitMenu: Initialization code; called from Start()
  • BeginEdit: When the menu is opened; called from OnEnable()
  • ObjectClicked: When a menu item is selected; called when a clickable object event is triggered
  • DoneEdit: When a menu is done; should be called from ObjectClicked as appropriate

The menu items will have a ClickableObject component. When the object is clicked, it will invoke a OnClickableObjectclicked event, passing the game object selected, which the menu handles in its ObjectClicked function. So first let's implement that:

  1. Create a new C# script in your Scripts folder named ClickableObject and open it for editing:

 

File: ClickableObject.cs
using UnityEngine; using UnityEngine.Events; using HoloToolkit.Unity.InputModule; public class ClickableObjectEvent : UnityEvent<GameObject> { } public class ClickableObject : MonoBehaviour, IInputClickHandler { public ClickableObjectEvent OnClickableObjectClicked = new ClickableObjectEvent(); public void OnInputClicked(InputClickedEventData eventData) { OnClickableObjectClicked.Invoke(gameObject); } }

The script declares a ClickableObjectEvent as a UnityEvent. Using the toolkit InputManager, when the current object is clicked, OnInputClicked will invoke the OnClickableObjectClicked event that the menu will get.

It is important to note that any objects using the IInputClickHandler (or any InputManager events, for that matter) must have a collider for the InputManager and GazeManager to detect what object is selected. You can see now why we need to make sure any clickable menu items have a collider.

Now we can write the PictureMenu class.

  1. Create a new C# script in your Scripts folder named PictureMenu and open it for editing:
File: PictureMenu.cs
using UnityEngine; public abstract class PictureMenu : MonoBehaviour { public ClickableObject[] clickableObjects; protected PictureController picture; protected GameObject toolbar; void Start() { SubscribeClickableObjects(); InitMenu(); } void OnEnable() { Debug.Log("PictureMenu: OnEnable"); picture = GetComponentInParent<PictureController>(); picture.toolbar.SetActive(false); BeginEdit(); } public abstract void InitMenu(); public abstract void BeginEdit(); public abstract void ObjectClicked(GameObject clickedGameObject); public void DoneEdit() { Debug.Log("PictureMenu: DoneEdit"); picture.toolbar.SetActive(true); gameObject.SetActive(false); } public void SubscribeClickableObjects() { for (int i = 0; i < clickableObjects.Length; i++) { clickableObjects[i].OnClickableObjectClicked.AddListener(ObjectClicked); } } }

As already explained, the PictureMenu maintains a list of clickable menu items (ClickableObjects) and subscribes them to the ObjectClicked function. We will use this class next as we implement a frame selection menu.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset