// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. using UnityEngine; using HoloToolkit.Unity.InputModule; using HoloToolkit.Unity; namespace HoloToolkit.Unity.Buttons { /// <summary> /// This class will automatically link buttons to speech keywords /// (Currently disabled) /// </summary> [RequireComponent (typeof(CompoundButton))] public class CompoundButtonSpeech : MonoBehaviour, ISpeechHandler { public enum KeywordSourceEnum { None, LocalOverride, ButtonText, } /// <summary> /// Source of the keyword to be used /// By default the text in a CompoundButtonText component will be used /// </summary> [HideInMRTKInspector] public KeywordSourceEnum KeywordSource = KeywordSourceEnum.ButtonText; /// <summary> /// Keyword used when KeywordSource is set to LocalOverride /// </summary> [HideInMRTKInspector] public string Keyword = string.Empty; /// <summary> /// Variable to keep track of previous button text in case the button text changes after registration. /// </summary> private string prevButtonText; /// <summary> /// The final keyword that is registered with the Keyword Manager /// </summary> private string keyWord; /// <summary> /// Have internal member reference to button /// </summary> private CompoundButton m_button; /// <summary> /// Have internal member reference to button /// </summary> private CompoundButtonText m_button_text; public void Start () { // Disable if no microphone devices are found if (Microphone.devices.Length == 0) { enabled = false; return; } if (KeywordSource == KeywordSourceEnum.None) return; keyWord = string.Empty; // Assign internal cached components m_button = GetComponent<CompoundButton>(); m_button_text = GetComponent<CompoundButtonText>(); switch (KeywordSource) { case KeywordSourceEnum.ButtonText: default: keyWord = prevButtonText = m_button_text.Text; break; case KeywordSourceEnum.LocalOverride: keyWord = Keyword; break; } } public void Update() { // Check if Button text has changed. If so, remove previous keyword and add new button text if (KeywordSource == KeywordSourceEnum.ButtonText && prevButtonText != null && m_button_text.Text != prevButtonText) { prevButtonText = m_button_text.Text; } } private void OnDestroy() { if (string.IsNullOrEmpty(this.keyWord)) return; } /// <summary> /// On Speech keyword recognizer handle speech event /// </summary> /// <param name="eventData"></param> public void OnSpeechKeywordRecognized(SpeechEventData eventData) { if (!gameObject.activeSelf || !enabled) return; if(eventData.RecognizedText.Equals(keyWord)) { // Send a pressed message to the button through the InputManager m_button.TriggerClicked(); } } #if UNITY_EDITOR [UnityEditor.CustomEditor(typeof(CompoundButtonSpeech))] public class CustomEditor : MRTKEditor { protected override void DrawCustomFooter() { CompoundButtonSpeech speechButton = (CompoundButtonSpeech)target; bool microphoneEnabled = UnityEditor.PlayerSettings.WSA.GetCapability(UnityEditor.PlayerSettings.WSACapability.Microphone); if (!microphoneEnabled) { DrawWarning("Microphone capability not present. Speech recognition will be disabled."); return; } UnityEditor.EditorGUILayout.LabelField("Keyword source", UnityEditor.EditorStyles.miniBoldLabel); speechButton.KeywordSource = (CompoundButtonSpeech.KeywordSourceEnum)UnityEditor.EditorGUILayout.EnumPopup(speechButton.KeywordSource); CompoundButtonText text = speechButton.GetComponent<CompoundButtonText>(); switch (speechButton.KeywordSource) { case CompoundButtonSpeech.KeywordSourceEnum.ButtonText: default: if (text == null) { DrawError("No CompoundButtonText component found."); } else if (string.IsNullOrEmpty(text.Text)) { DrawWarning("No keyword found in button text."); } else { UnityEditor.EditorGUILayout.LabelField("Keyword: " + text.Text); } break; case CompoundButtonSpeech.KeywordSourceEnum.LocalOverride: speechButton.Keyword = UnityEditor.EditorGUILayout.TextField(speechButton.Keyword); break; case CompoundButtonSpeech.KeywordSourceEnum.None: UnityEditor.EditorGUILayout.LabelField("(Speech control disabled)", UnityEditor.EditorStyles.miniBoldLabel); break; } } private void EnableMicrophone() { UnityEditor.PlayerSettings.WSA.SetCapability(UnityEditor.PlayerSettings.WSACapability.Microphone, true); } private void AddText() { CompoundButtonSpeech speechButton = (CompoundButtonSpeech)target; speechButton.gameObject.AddComponent<CompoundButtonText>(); } } #endif } }