hololens凝视物体、单击双击、语音控制、蓝牙
1、用unity开发
2、在HoloLens toolkit中找到TextToSpeech添加到场景中
3、添加KeywordManager.cs到场景中
using orange;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Windows.Speech;/// <summary>
/// 语音控制类,需要在start方法中初始化。
/// 使用方法:
/// 1、在场景对象中添加KeywordManager脚本
/// 2、在需要接收语音控制的脚本中,获取到KeywordManager实例,然后注册 OnSpeeked 事件
/// </summary>
public class KeywordManager : MonoBehaviour
{public delegate void OnSpeekHandler(SpeechKeys key);private KeywordRecognizer keywordRecognizer;private List<string> keys;public event OnSpeekHandler OnSpeeked;private void Start(){//从枚举对象中获取识别命令string[] values = System.Enum.GetNames(typeof(SpeechKeys));keywordRecognizer = new KeywordRecognizer(values);keys = new List<string>();keys.AddRange(values);keywordRecognizer.OnPhraseRecognized += KeywordRecognizer_OnPhraseRecognized;keywordRecognizer.Start();}void OnDestroy(){if (keywordRecognizer != null){StopKeywordRecognizer();keywordRecognizer.OnPhraseRecognized -= KeywordRecognizer_OnPhraseRecognized;keywordRecognizer.Dispose();}}/// <summary>/// 识别完成/// </summary>/// <param name="args"></param>private void KeywordRecognizer_OnPhraseRecognized(PhraseRecognizedEventArgs args){if (keys.Contains(args.text)){//转换为枚举类型,触发事件SpeechKeys key = (SpeechKeys)System.Enum.Parse(typeof(SpeechKeys), args.text);if (OnSpeeked != null){OnSpeeked.Invoke(key);}}}/// <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();}}
}
4、添加GestureManager.cs到场景中
using orange;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.WSA.Input;public class GestureManager : MonoBehaviour
{private GestureRecognizer recognizer;public delegate void OnGestureClick();public delegate void OnGestureDoubleClick();private List<OnGestureClick> onClicks = new List<OnGestureClick>();private List<OnGestureDoubleClick> onDoubleClicks = new List<OnGestureDoubleClick>();public void AddGestureClick(OnGestureClick onClick){if (onClick == null || onClicks.Contains(onClick)) return;onClicks.Add(onClick);}public void RemoveGestureClick(OnGestureClick onClick){if (onClick != null && onClicks.Contains(onClick)){onClicks.Remove(onClick);}}public void AddGestureDoubleClick(OnGestureDoubleClick onDoubleClick){if (onDoubleClick == null || onDoubleClicks.Contains(onDoubleClick)) return;onDoubleClicks.Add(onDoubleClick);}public void RemoveGestureDoubleOnClick(OnGestureDoubleClick onDoubleClick){if (onDoubleClick != null && onDoubleClicks.Contains(onDoubleClick)){onDoubleClicks.Remove(onDoubleClick);}}void Start(){// 初始化开始// 创建手势识别对象recognizer = new GestureRecognizer();// 设置手势识别的类型recognizer.SetRecognizableGestures(GestureSettings.Tap | GestureSettings.Hold | GestureSettings.DoubleTap);// 添加手势识别的事件recognizer.TappedEvent += Recognizer_TappedEvent;recognizer.HoldStartedEvent += Recognizer_HoldStartedEvent;recognizer.HoldCompletedEvent += Recognizer_HoldCompletedEvent;recognizer.HoldCanceledEvent += Recognizer_HoldCanceledEvent;// 开启手势识别recognizer.StartCapturingGestures();Debug.Log("初始化完成~");}private void Recognizer_HoldCanceledEvent(InteractionSourceKind source, Ray headRay){}private void Recognizer_HoldCompletedEvent(InteractionSourceKind source, Ray headRay){}private void Recognizer_HoldStartedEvent(InteractionSourceKind source, Ray headRay){}private void Recognizer_TappedEvent(InteractionSourceKind source, int tapCount, Ray headRay){if (tapCount == 1){//单击for (int i = 0; i < onClicks.Count; i++){onClicks[i].Invoke();}}else if (tapCount == 2){//双击for (int i = 0; i < onDoubleClicks.Count; i++){onDoubleClicks[i].Invoke();}}}void OnDestroy(){// 销毁注册的事件recognizer.TappedEvent -= Recognizer_TappedEvent;recognizer.HoldStartedEvent -= Recognizer_HoldStartedEvent;recognizer.HoldCompletedEvent -= Recognizer_HoldCompletedEvent;recognizer.HoldCanceledEvent -= Recognizer_HoldCanceledEvent;}}
5、主程序入口
using HoloToolkit.Unity;
using HoloToolkit.Unity.InputModule;
using UnityEngine;
using UnityEngine.UI;
using ZhiHui;public class APP : MonoBehaviour
{public Transform modeles;public Material raycastMaterial;//public TextToSpeech textToSpeech;public KeywordManager keywordManager;//public GestureManager gestureManager;private GestureHandler gestureHandler;//public Canvas infoWindow;public Canvas jumpWindow;private InfoWindow mInfoWindow;private JumpWindow mJumpWondow;//private KeywordHandler keywordHandler;void Start(){//UImInfoWindow = new InfoWindow(infoWindow);mJumpWondow = new JumpWindow(jumpWindow);//语音识别SpeechHandler.textToSpeech = textToSpeech;//设置视线检测RaycastHandler.raycastMaterial = raycastMaterial;//语音控制keywordHandler = new KeywordHandler(keywordManager);keywordHandler.infoWindow = mInfoWindow;keywordHandler.jumpWindow = mJumpWondow;//手势控制gestureHandler = new GestureHandler(gestureManager);gestureHandler.infoWindow = mInfoWindow;gestureHandler.jumpWindow = mJumpWondow;gestureHandler.Init();}void Update(){RaycastHandler.OnRaycast();}private void OnDestroy(){keywordHandler.Destroy();gestureHandler.Destroy();mInfoWindow.Destroy();mJumpWondow.Destroy();}}
6、RaycastHandler.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;namespace ZhiHui
{class RaycastHandler{public static GameObject raycastObject;private static GameObject raycastObjectTmp;public static Material raycastMaterial;private static Material raycastMaterialTmp;/// <summary>/// 射线检测委托/// </summary>/// <param name="hit"></param>public delegate void RaycastCall(RaycastHit hit);private static List<RaycastCall> racastCalls = new List<RaycastCall>();/// <summary>/// 添加回调/// </summary>/// <param name="racastCall"></param>public static void AddRaycastCall(RaycastCall racastCall){if (racastCall == null || racastCalls.Contains(racastCall)) return;racastCalls.Add(racastCall);}/// <summary>/// 移除回调/// </summary>/// <param name="racastCall"></param>public static void RemoveRaycastCall(RaycastCall racastCall){if (racastCall != null && racastCalls.Contains(racastCall)){racastCalls.Remove(racastCall);}}/// <summary>/// 选中物体/// </summary>/// <param name="objName"></param>public static void SelectObjectByName(string objName){SetHightlightBack();SetHightlight(GameObject.Find(objName));}/// <summary>/// 恢复材质/// </summary>private static void SetHightlightBack(){if (raycastObjectTmp != null && raycastMaterialTmp != null){Renderer r = raycastObjectTmp.GetComponent<Renderer>();if (r){r.material = raycastMaterialTmp;}}}/// <summary>/// 改变材质/// </summary>private static void SetHightlight(GameObject obj){if (obj != null && raycastMaterial != null){Renderer r = obj.GetComponent<Renderer>();if (r){raycastMaterialTmp = r.material;r.material = raycastMaterial;}}raycastObjectTmp = obj;}/// <summary>/// 射线检测/// </summary>public static void OnRaycast(){//恢复材质SetHightlightBack();//RaycastHit hit;if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit)){raycastObject = hit.transform.gameObject;//改变材质SetHightlight(raycastObject);}else{raycastMaterialTmp = null;raycastObjectTmp = null;}//回调if (racastCalls != null){for (int i = 0; i < racastCalls.Count; i++){racastCalls[i].Invoke(hit);}}}/// <summary>/// 获取物体LookAt后的旋转值/// </summary>/// <param name="originalObj"></param>/// <param name="targetPoint"></param>/// <returns></returns>public static Quaternion GetLookAtEuler(Vector3 originPoint, Vector3 targetPoint){//计算物体在朝向某个向量后的正前方Vector3 forwardDir = targetPoint - originPoint;//计算朝向这个正前方时的物体四元数值Quaternion lookAtRot = Quaternion.LookRotation(forwardDir);//把四元数值转换成角度//Vector3 resultEuler = lookAtRot.eulerAngles;return lookAtRot;}/// <summary>/// 获取距离/// </summary>/// <returns></returns>public static float GetDistanceBetween(Vector3 v1, Vector3 v2){float x = Mathf.Pow((v2.x - v1.x), 2);float y = Mathf.Pow((v2.y - v1.y), 2);float z = Mathf.Pow((v2.z - v1.z), 2);return Mathf.Sqrt(x + y + z);}}
}
7、SpeechHandler.cs
using HoloToolkit.Unity;
using HoloToolkit.Unity.InputModule;namespace ZhiHui
{class SpeechHandler{public static TextToSpeech textToSpeech;/// <summary>/// 文字转语音/// </summary>/// <param name="txt"></param>public static void Speak(string txt){if (textToSpeech == null) return;if (textToSpeech.isActiveAndEnabled){if (!textToSpeech.IsSpeaking()){textToSpeech.StartSpeaking(txt);}}}/// <summary>/// 文字转语音(要打断当前说话吗)/// </summary>/// <param name="txt"></param>/// <param name="breaking"></param>public static void Speak(string txt, bool breaking){if (textToSpeech == null) return;if (textToSpeech.isActiveAndEnabled){if (textToSpeech.IsSpeaking()){if (breaking){StopSpeaking();textToSpeech.StartSpeaking(txt);}}else{textToSpeech.StartSpeaking(txt);}}}/// <summary>/// 停止说话/// </summary>public static void StopSpeaking(){if (textToSpeech == null) return;textToSpeech.StopSpeaking();}}
}
8、蓝牙扫描
using System;
using UnityEngine;
using UnityEngine.UI;
#if NETFX_CORE
using Windows.Devices.Bluetooth;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Enumeration;
using Windows.Foundation;
using Windows.System;
using Windows.UI.Popups;
#endifpublic class e2_bluetooth : MonoBehaviour
{public Text showText;void Start(){
#if NETFX_COREScanDevices();
#endif}void Update(){}
#if NETFX_CORE/// <summary>/// 扫描所有BLE设备/// </summary>async void ScanDevices(){try{DeviceInformationCollection bleDevices = await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelector());if (bleDevices.Count == 0){await new MessageDialog("没有找到蓝牙设备,请确认是否已配对Hololens!").ShowAsync();return;}else{for (int i = 0; i < bleDevices.Count; i++){showText.text += bleDevices[i].Name + "\n";}}}catch (Exception ex){await new MessageDialog("扫描失败: " + ex.Message).ShowAsync();}}
#endif}
9、蓝牙接收数据
#if NETFX_CORE
using System;
using System.Collections.Generic;
using System.Linq;using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Devices.Bluetooth.Advertisement;using System.Text;
using UnityEngine;
using UnityEngine.UI;namespace ZhiHui
{class BluetoothReceiver{BluetoothLEAdvertisementWatcher watcher;EventProcessor eventProcessor;public ushort BEACON_ID = 1775;public delegate void OnSucceedCallBack(GPSDataPacket gpsDataPacket);private OnSucceedCallBack onSucceedCallBack;public BluetoothReceiver(EventProcessor processor){eventProcessor = processor;}public void SetOnSucceedCallBack(OnSucceedCallBack call){onSucceedCallBack = call;}public void Start(){if (watcher != null){watcher.Stop();}watcher = new BluetoothLEAdvertisementWatcher();var manufacturerData = new BluetoothLEManufacturerData{CompanyId = BEACON_ID};watcher.AdvertisementFilter.Advertisement.ManufacturerData.Add(manufacturerData);watcher.Received += Watcher_Received;watcher.Start();}private async void Watcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args){ushort identifier = args.Advertisement.ManufacturerData.First().CompanyId;byte[] data = args.Advertisement.ManufacturerData.First().Data.ToArray();eventProcessor.QueueEvent(() =>{//Unity UI ingestion hereGPSDataPacket gpsDataPacket = new GPSDataPacket(data);if (gpsDataPacket != null){if (gpsDataPacket.Latitude == 0|| gpsDataPacket.Longitude == 0){return;}if (onSucceedCallBack != null){onSucceedCallBack.Invoke(gpsDataPacket);}}});}}
}
#endif
hololens凝视物体、单击双击、语音控制、蓝牙相关推荐
- Unity触摸屏幕 拖拽物体 旋转物体 放大缩小物体 单击 双击 长按
Unity触摸屏幕 拖拽物体 旋转物体 放大缩小物体 单击 双击 长按 拖拽物体 using System.Collections; using System.Collections.Generic; ...
- 【蓝牙Mesh笔记 ①】ESP32-C3 模组上实现天猫精灵蓝牙 BLE Mesh AliGenie 接入,无需WiFi 连接也可以实现天猫精灵语音控制。
本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 系列一:ESP32系列模组基础学习系列笔记 1. 爬坑学习新旅程,虚 ...
- stm32的语音识别_基于stm32循迹避障语音控制金属探测蓝牙小车设计(原理图+pcb+源码+参考文档)...
功能描述及设计原理: 小车具有检测里程功能,在金属探测模式,槽型光耦会检测小车车轮的圈数,以此来计算小车行走的里程,并可以通过OLED屏幕显示出来.还可以显示小车的工作模式以及小车距离前方障碍物的距离 ...
- 泰凌微ble mesh蓝牙模组天猫精灵学习之旅 ⑤ 阿里天猫精灵官方Genie BT mesh Stack框架:编译天猫精灵例程,实现语音控制!
本<泰凌微ble mesh蓝牙模组天猫精灵学习之旅>系列博客学习由半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 1.小白也痴迷,如 ...
- 一种基于蓝牙和语音控制的智能家居系统【100010378】
2018年大学生电子设计竞赛设计报告 一种基于蓝牙和语音控制的智能家居系统 摘要:本项目使用 STM32F407 作为主控芯片,通过蓝牙和语音控制实现安全.便宜的智能家居系统.实现了手机实现家电控制: ...
- 5.39 综合案例2.0 - STM32蓝牙遥控小车2(语音控制)
综合案例2.0 - 蓝牙遥控小车1- 语音控制 成品展示 案例说明 器件说明 小车连线 小车源码 语音模块遥控 语音遥控连线 模块使用说明 1.MLT-BT05 4.0 蓝牙模块 2.ASRPRO-2 ...
- 泰凌微ble mesh蓝牙模组天猫精灵学习之旅③简单入门安信可TB-02开发开发板轻松接入天猫精灵,语音控制冷暖灯so easy!
本<泰凌微ble mesh蓝牙模组天猫精灵学习之旅>系列博客学习由半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 1.小白也痴迷,如 ...
- 掌控板教程 | 搞定 Siri 语音控制,只要半小时!
话不多说,先上效果演示视频: 本教程适用于掌控板及其他 ESP32 开发板. # 前言 # 前段时间,我在公众号上面发了一篇文章:掌控板 V1.1 语音识别初体验 在这篇文章中,我使用了还处于测试阶段 ...
- win7关闭计算机控制,大吼:鹅要关机!Win7下语音控制电脑攻略
Win7之家( www.win7china.com):大吼:鹅要关机!Win7下语音控制电脑攻略 记得若干年前非常真实的一幕,一位兄弟在宿舍津津有味玩着游戏,一舍友突然学他的方言口音大吼一声:鹅要关机 ...
最新文章
- ubuntu下设置开机自启动项
- MQTT数据处理之从tcp连接获取数据过程
- teacher want middle point result rather all drafts
- python123可以复制粘贴吗_使用win32com和python复制和粘贴隔离
- Java重载和重写6_深入理解Java中的重写和重载
- Office XP 试用感受
- 新计算机是飞行模式怎么开,win10自己打开飞行模式,怎么处理
- 等保2.0三级常用的设备
- Sci-Hub创始人收到苹果的通知:2年前就把她的账户数据给了FBI
- python读取.data文件总结
- WebPagetest H5性能测试工具入门详解
- GlidedSky爬虫-验证码1
- matlab 矩阵3d显示,Matlab 3D视图矩阵
- 继续注册前请先阅读终极QQ数字点卡公司在线销售协议 一、新疆维吾尔自治区阿克苏地区终极QQ网络电子商务有限公司使用自己建设的代理商专用电子商务平台系统,通过国际互联网络为用户提供网络游戏分销服务。同
- html css3加速,10个加速CSS开发的框架
- 国潮文化引领手办市场新风向 b站会员购成消费首选平台
- IND-gyc-第一周
- ATMEGA16 自适应电压表
- android animate xml,Android Animate旋轉
- 浅试Hyperledger Fabric go 小项目
热门文章
- Python里面的编码问题真的让人快疯了.. Python乱码 b'\x1f\x8b\x08\x00\x00\x00\x00\x00\...'
- 通达信日线数据用转换为excel、csv和feather格式
- 如何系统的学习linux?
- android emulator 安装 google play
- 信号完整性(SI)电源完整性(PI)学习笔记(二十八)S参数在信号完整性中的应用(三)
- MATLAB有限元二维编程(三角单元)
- 【微信小程序】史上最全的《Java面试题及解析》,理论+实战双管齐下!
- 三招教你如何搞定将qlv格式的腾讯视频转换为mp4格式
- IDL---批量波段合成(只要点击运行,自动化处理,解放生产力)
- java Web api接入讯飞aiui(1)