Hello everyone.

The Mixed Reality Forums here are no longer being used or maintained.

There are a few other places we would like to direct you to for support, both from Microsoft and from the community.

The first way we want to connect with you is our mixed reality developer program, which you can sign up for at https://aka.ms/IWantMR.

For technical questions, please use Stack Overflow, and tag your questions using either hololens or windows-mixed-reality.

If you want to join in discussions, please do so in the HoloDevelopers Slack, which you can join by going to https://aka.ms/holodevelopers, or in our Microsoft Tech Communities forums at https://techcommunity.microsoft.com/t5/mixed-reality/ct-p/MicrosoftMixedReality.

And always feel free to hit us up on Twitter @MxdRealityDev.

Voice commands don't work

OddCoreOddCore
edited December 2016 in Projects

I am trying to have a voice command to move the position of the hologram to a specific position so it looks like the user moved closer to a certain point of it. I have tried the Holograms tutorials but they don't explain the code or how to do something different to what they do.

I made sure to enable Microphone in Unity Player Settings.

My KeywordManager:

using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Windows.Speech;

namespace HoloTest
{
    /// <summary>
    /// KeywordManager allows you to specify keywords and methods in the Unity
    /// Inspector, instead of registering them explicitly in code.
    /// This also includes a setting to either automatically start the
    /// keyword recognizer or allow your code to start it.
    ///
    /// IMPORTANT: Please make sure to add the microphone capability in your app, in Unity under
    /// Edit -> Project Settings -> Player -> Settings for Windows Store -> Publishing Settings -> Capabilities
    /// or in your Visual Studio Package.appxmanifest capabilities.
    /// </summary>
    public class KeywordManager : MonoBehaviour
    {
        [System.Serializable]
        public struct KeywordAndResponse
        {
            [Tooltip("The keyword to recognize.")]
            public string Keyword;
            [Tooltip("The UnityEvent to be invoked when the keyword is recognized.")]
            public UnityEvent Response;
        }

        // This enumeration gives the manager two different ways to handle the recognizer. Both will
        // set up the recognizer and add all keywords. The first causes the recognizer to start
        // immediately. The second allows the recognizer to be manually started at a later time.
        public enum RecognizerStartBehavior { AutoStart, ManualStart };

        [Tooltip("An enumeration to set whether the recognizer should start on or off.")]
        public RecognizerStartBehavior RecognizerStart;
        [Tooltip("An array of string keywords and UnityEvents, to be set in the Inspector.")]
        public KeywordAndResponse[] KeywordsAndResponses;

        private KeywordRecognizer keywordRecognizer;
        private Dictionary<string, UnityEvent> responses;

        void Start()
        {
            if (KeywordsAndResponses.Length > 0)
            {
                // Convert the struct array into a dictionary, with the keywords and the keys and the methods as the values.
                // This helps easily link the keyword recognized to the UnityEvent to be invoked.
                responses = KeywordsAndResponses.ToDictionary(keywordAndResponse => keywordAndResponse.Keyword,
                                                              keywordAndResponse => keywordAndResponse.Response);

                keywordRecognizer = new KeywordRecognizer(responses.Keys.ToArray());
                keywordRecognizer.OnPhraseRecognized += KeywordRecognizer_OnPhraseRecognized;

                if (RecognizerStart == RecognizerStartBehavior.AutoStart)
                {
                    keywordRecognizer.Start();
                }
            }
            else
            {
                Debug.LogError("Must have at least one keyword specified in the Inspector on " + gameObject.name + ".");
            }
        }

        void OnDestroy()
        {
            if (keywordRecognizer != null)
            {
                StopKeywordRecognizer();
                keywordRecognizer.OnPhraseRecognized -= KeywordRecognizer_OnPhraseRecognized;
                keywordRecognizer.Dispose();
            }
        }

        private void KeywordRecognizer_OnPhraseRecognized(PhraseRecognizedEventArgs args)
        {
            UnityEvent keywordResponse;

            // Check to make sure the recognized keyword exists in the methods dictionary, then invoke the corresponding method.
            if (responses.TryGetValue(args.text, out keywordResponse))
            {
                keywordResponse.Invoke();
            }
        }

        /// <summary>
        /// Make sure the keyword recognizer is off, then start it.
        /// Otherwise, leave it alone because it's already in the desired state.
        /// </summary>
        public void StartKeywordRecognizer()
        {
            if (keywordRecognizer != null && !keywordRecognizer.IsRunning)
            {
                keywordRecognizer.Start();
            }
        }

        /// <summary>
        /// Make sure the keyword recognizer is on, then stop it.
        /// Otherwise, leave it alone because it's already in the desired state.
        /// </summary>
        public void StopKeywordRecognizer()
        {
            if (keywordRecognizer != null && keywordRecognizer.IsRunning)
            {
                keywordRecognizer.Stop();
            }
        }
    }
}

Answers

  • Where are you trying to move the hologram in the above script? I don't see any transform manipulation. Do you know how to work with the keyword manager? Have you been successful with it in other tasks?

  • I tried leaving a comment with the class that has the function that should be called by the voice command but for some reason it won't let me post it, so I will attach it here.

  • Can you post a screenshot of your Inspector panel for the object these scripts will be on? Assuming GoToBoosterAccess() is the method you want called for the keyword, you should just be able to set that in the Inspector.

  • My MoveAroundMap class that contains the function that should be called with the voice command:

    using UnityEngine;

    namespace HoloTest
    {
    [RequireComponent(typeof(KeywordManager))]
    public class MoveAroundMap : Singleton
    {
    [Tooltip("Drag the Communicator prefab asset.")]
    public GameObject CommunicatorPrefab;
    private GameObject communicatorGameObject;

        [Tooltip("Drag the Message Received prefab asset.")]
        public GameObject MessagePrefab;
        private GameObject messageGameObject;
    
        [Tooltip("Drag the Voice Tooltip prefab asset.")]
        public GameObject OpenCommunicatorTooltip;
        private GameObject openCommunicatorTooltipGameObject;
    
        public AudioClip DismissSound;
    
        public bool CommunicatorOpen { get; private set; }
    
        private KeywordManager keywordManager;
    
        [SerializeField]
        private GameObject map;
    
        void Awake()
        {
            CommunicatorOpen = false;
    
            openCommunicatorTooltipGameObject = Instantiate(OpenCommunicatorTooltip);
    
            openCommunicatorTooltipGameObject.transform.position = new Vector3(
                gameObject.transform.position.x + 0.1f,
                gameObject.transform.position.y + 0.05f,
                gameObject.transform.position.z - 0.05f);
    
            openCommunicatorTooltipGameObject.transform.parent = gameObject.transform;
            openCommunicatorTooltipGameObject.SetActive(false);
    
            keywordManager = GetComponent<KeywordManager>();
        }
    
        public void OpenCommunicator()
        {
            // When a voice command is heard, change the text color on the tooltip.
            // This gives feedback to the user that the voice command has been heard.
            //openCommunicatorTooltipGameObject.GetComponent<VoiceTooltip>().VoiceCommandHeard();
    
            CommunicatorOpen = true;
    
            communicatorGameObject = Instantiate(CommunicatorPrefab);
    
            communicatorGameObject.transform.position = transform.position;
            communicatorGameObject.transform.Translate(0.4f, 0.0f, 0.0f, Camera.main.transform);
        }
    
        public void GoToBoosterAccess()
        {
            map.transform.position = new Vector3( 98, map.transform.position.y, -9 );
        }
    
        public void CloseCommunicator()
        {
            CommunicatorOpen = false;
    
            GameObject soundPlayer = new GameObject("MessageSentSound");
            AudioSource soundSource = soundPlayer.AddComponent<AudioSource>();
            soundSource.clip = DismissSound;
            soundSource.Play();
    
            messageGameObject = (GameObject)Instantiate(MessagePrefab, communicatorGameObject.transform.position, MessagePrefab.transform.rotation);
    
            Destroy(communicatorGameObject);
            Destroy(messageGameObject, 1.0f);
            Destroy(soundPlayer, DismissSound.length);
        }
    
        void GazeEntered()
        {
            // If communicator is not open, show the voice command tooltip.
            if (!CommunicatorOpen)
            {
                openCommunicatorTooltipGameObject.SetActive(true);
    
                keywordManager.StartKeywordRecognizer();
            }
        }
    
        void GazeExited()
        {
            // Hide tooltip when user looks away.
            openCommunicatorTooltipGameObject.SetActive(false);
    
            keywordManager.StopKeywordRecognizer();
    
            // Reset tooltip to its original state.
            //openCommunicatorTooltipGameObject.GetComponent<VoiceTooltip>().ResetTooltip();
        }
    }
    

    }

  • Did you set that method in the Inspector? How are you registering the keyword?

Sign In or Register to comment.