• Hololens开发笔记之Gesture手势识别(Manipulation手势控制物体旋转)


    Manipulation gesture:保持点击手势,在3D世界中绝对运动

    当你想要全息图像1:1响应用户手部移动时,操纵手势能被用于移动、缩放或旋转全息图像。如此的一个用处是使得用户可以在世界中绘制图像或作画。使用所有的手势时,操纵手势的初始目标应该通过凝视来选中。一旦点击手势开始,通过手部移动的任何对对象的操作都能够被处理,在用户操作全息图像时,从而使得用户得以自由地四处张望。

    1、修改HandsManager.cs,添加InteractionManager.SourcePressed,InteractionManager.SourceReleased处理函数,用于识别物体被点击和被释放的事件

    HandsManager.cs完整代码如下:

    // Copyright (c) Microsoft Corporation. All rights reserved.  
    // Licensed under the MIT License. See LICENSE in the project root for license information.  
      
    using System.Collections.Generic;  
    using UnityEngine;  
    using UnityEngine.VR.WSA.Input;  
      
    namespace HoloToolkit.Unity  
    {  
        /// <summary>  
        /// HandsManager determines if the hand is currently detected or not.  
        /// </summary>  
        public partial class HandsManager : Singleton<HandsManager>  
        {  
            /// <summary>  
            /// HandDetected tracks the hand detected state.  
            /// Returns true if the list of tracked hands is not empty.  
            /// </summary>  
            public bool HandDetected  
            {  
                get { return trackedHands.Count > 0; }  
            }  
      
            private HashSet<uint> trackedHands = new HashSet<uint>();  
      
            public GameObject FocusedGameObject { get; private set; }  
      
            void Awake()  
            {  
                //识别到来源  
                InteractionManager.SourceDetected += InteractionManager_SourceDetected;  
                //来源丢失  
                InteractionManager.SourceLost += InteractionManager_SourceLost;  
                //来源被按下  
                InteractionManager.SourcePressed += InteractionManager_SourcePressed;  
                //被释放  
                InteractionManager.SourceReleased += InteractionManager_SourceReleased;  
                FocusedGameObject = null;  
            }  
      
            private void InteractionManager_SourceDetected(InteractionSourceState state)  
            {  
                // Check to see that the source is a hand.  
                if (state.source.kind != InteractionSourceKind.Hand)  
                {  
                    return;  
                }  
      
                trackedHands.Add(state.source.id);  
            }  
      
            private void InteractionManager_SourceLost(InteractionSourceState state)  
            {  
                // Check to see that the source is a hand.  
                if (state.source.kind != InteractionSourceKind.Hand)  
                {  
                    return;  
                }  
      
                if (trackedHands.Contains(state.source.id))  
                {  
                    trackedHands.Remove(state.source.id);  
                }  
                FocusedGameObject = null;  
            }  
      
            //手势释放时,将被关注的物体置空  
            private void InteractionManager_SourceReleased(InteractionSourceState state)  
            {  
                FocusedGameObject = null;  
            }  
      
            //识别到手指按下时,将凝视射线关注的物体置为当前手势操作的对象  
            private void InteractionManager_SourcePressed(InteractionSourceState state)  
            {  
                if (GazeManager.Instance.FocusedObject != null)  
                {  
                    FocusedGameObject = GazeManager.Instance.FocusedObject;  
                }  
            }  
      
            void OnDestroy()  
            {  
                InteractionManager.SourceDetected -= InteractionManager_SourceDetected;  
                InteractionManager.SourceLost -= InteractionManager_SourceLost;  
                InteractionManager.SourceReleased -= InteractionManager_SourceReleased;  
                InteractionManager.SourcePressed -= InteractionManager_SourcePressed;  
            }  
        }  
    }  

    2、修改GestureManager.cs,订阅Manipulation gesture事件

    // Copyright (c) Microsoft Corporation. All rights reserved.  
    // Licensed under the MIT License. See LICENSE in the project root for license information.  
      
    using System;  
    using UnityEngine;  
    using UnityEngine.VR.WSA.Input;  
      
    namespace HoloToolkit.Unity  
    {  
        /// <summary>  
        /// GestureManager creates a gesture recognizer and signs up for a tap gesture.  
        /// When a tap gesture is detected, GestureManager uses GazeManager to find the game object.  
        /// GestureManager then sends a message to that game object.  
        /// </summary>  
        [RequireComponent(typeof(GazeManager))]  
        public partial class GestureManager : Singleton<GestureManager>  
        {  
            /// <summary>  
            /// Key to press in the editor to select the currently gazed hologram  
            /// </summary>  
            public KeyCode EditorSelectKey = KeyCode.Space;  
      
            /// <summary>  
            /// To select even when a hologram is not being gazed at,  
            /// set the override focused object.  
            /// If its null, then the gazed at object will be selected.  
            /// </summary>  
            public GameObject OverrideFocusedObject  
            {  
                get; set;  
            }  
      
            public bool IsManipulating { get; private set; }  
            public Vector3 ManipulationPosition { get; private set; }  
      
            /// <summary>  
            /// Gets the currently focused object, or null if none.  
            /// </summary>  
            public GameObject FocusedObject  
            {  
                get { return focusedObject; }  
            }  
      
            private GestureRecognizer gestureRecognizer;  
            private GameObject focusedObject;  
      
            void Start()  
            {  
                // Create a new GestureRecognizer. Sign up for tapped events.  
                gestureRecognizer = new GestureRecognizer();  
                gestureRecognizer.SetRecognizableGestures(GestureSettings.Tap  
                    | GestureSettings.DoubleTap  
                    | GestureSettings.ManipulationTranslate);  
      
                gestureRecognizer.TappedEvent += GestureRecognizer_TappedEvent;  
                //订阅Manipulation gesture事件  
                gestureRecognizer.ManipulationStartedEvent += GestureRecognizer_ManipulationStartedEvent;  
                gestureRecognizer.ManipulationUpdatedEvent += GestureRecognizer_ManipulationUpdatedEvent;  
                gestureRecognizer.ManipulationCompletedEvent += GestureRecognizer_ManipulationCompletedEvent;  
                gestureRecognizer.ManipulationCanceledEvent += GestureRecognizer_ManipulationCanceledEvent;  
      
                // Start looking for gestures.  
                gestureRecognizer.StartCapturingGestures();  
            }  
      
            private void GestureRecognizer_ManipulationStartedEvent(InteractionSourceKind source, Vector3 cumulativeDelta, Ray headRay)  
            {  
                //当被关注的对象非空时,设置初始位置  
                if (HandsManager.Instance.FocusedGameObject != null)  
                {  
                    IsManipulating = true;  
      
                    ManipulationPosition = cumulativeDelta;  
      
                    HandsManager.Instance.FocusedGameObject.SendMessageUpwards("PerformManipulationStart", cumulativeDelta);  
                }  
            }  
      
            private void GestureRecognizer_ManipulationUpdatedEvent(InteractionSourceKind source, Vector3 cumulativeDelta, Ray headRay)  
            {  
                //当被关注的对象非空时,更新新的位置  
                if (HandsManager.Instance.FocusedGameObject != null)  
                {  
                    IsManipulating = true;  
      
                    ManipulationPosition = cumulativeDelta;  
      
                    HandsManager.Instance.FocusedGameObject.SendMessageUpwards("PerformManipulationUpdate", cumulativeDelta);  
                }  
            }  
      
            private void GestureRecognizer_ManipulationCompletedEvent(InteractionSourceKind source, Vector3 cumulativeDelta, Ray headRay)  
            {  
                IsManipulating = false;  
            }  
      
            private void GestureRecognizer_ManipulationCanceledEvent(InteractionSourceKind source, Vector3 cumulativeDelta, Ray headRay)  
            {  
                IsManipulating = false;  
            }  
      
            private void OnTap()  
            {  
                if (focusedObject != null)  
                {  
                    focusedObject.SendMessage("OnTap");  
                }  
            }  
      
            private void OnDoubleTap()  
            {  
                if (focusedObject != null)  
                {  
                    focusedObject.SendMessage("OnDoubleTap");  
                }  
            }  
      
            private void GestureRecognizer_TappedEvent(InteractionSourceKind source, int tapCount, Ray headRay)  
            {  
                if (tapCount == 1)  
                {  
                    OnTap();  
                }  
                else  
                {  
                    OnDoubleTap();  
                }  
            }  
      
            void LateUpdate()  
            {  
                GameObject oldFocusedObject = focusedObject;  
      
                if (GazeManager.Instance.Hit &&  
                    OverrideFocusedObject == null &&  
                    GazeManager.Instance.HitInfo.collider != null)  
                {  
                    // If gaze hits a hologram, set the focused object to that game object.  
                    // Also if the caller has not decided to override the focused object.  
                    focusedObject = GazeManager.Instance.HitInfo.collider.gameObject;  
                }  
                else  
                {  
                    // If our gaze doesn't hit a hologram, set the focused object to null or override focused object.  
                    focusedObject = OverrideFocusedObject;  
                }  
      
                //if (focusedObject != oldFocusedObject)  
                //{  
                //    // If the currently focused object doesn't match the old focused object, cancel the current gesture.  
                //    // Start looking for new gestures.  This is to prevent applying gestures from one hologram to another.  
                //    gestureRecognizer.CancelGestures();  
                //    gestureRecognizer.StartCapturingGestures();  
                //}  
            }  
      
            void OnDestroy()  
            {  
                gestureRecognizer.StopCapturingGestures();  
                //取消订阅  
                gestureRecognizer.TappedEvent -= GestureRecognizer_TappedEvent;  
                gestureRecognizer.ManipulationStartedEvent -= GestureRecognizer_ManipulationStartedEvent;  
                gestureRecognizer.ManipulationUpdatedEvent -= GestureRecognizer_ManipulationUpdatedEvent;  
                gestureRecognizer.ManipulationCompletedEvent -= GestureRecognizer_ManipulationCompletedEvent;  
                gestureRecognizer.ManipulationCanceledEvent -= GestureRecognizer_ManipulationCanceledEvent;  
            }  
        }  
    }  

    3、添加ManipulationRotate脚本,实现对物体进行旋转。

    using UnityEngine;
    using System.Collections;
    using HoloToolkit.Unity;
    
    public class ManipulationRotate : MonoBehaviour {
    
        public float RotationSensitivity = 25.0f;
    
        private float rotationFactorX;
        
    
        // Use this for initialization  
        void PerformManipulationStart()
        {
            
        }
    
        void PerformManipulationUpdate(Vector3 position)
        {
            if (GestureManager.Instance.IsManipulating)
            {
                try
                {
                    if (GazeManager.Instance.HitInfo.collider.gameObject.tag == "Rotate")
                    {   //绕X轴进行旋转
                        rotationFactorX = GestureManager.Instance.ManipulationPosition.x * RotationSensitivity;
                        transform.Rotate(new Vector3(rotationFactorX, 0, 0));
    
                    }
                }
                catch
                {
    
                }
            }
        }
    }

    4、运行测试

    将凝视射线投射到对象上,举起右手使食指和拇指碰触在一起,然后进行左右移动,可以看到物体将绕X轴旋转。

     
  • 相关阅读:
    Eclipse相关问题
    分词工具比较(转)
    package-info.java文件详解
    如何在大量jar包中搜索特定字符
    eclipse插件在线发布发布和版本更新(web site) 转
    Peer Code Reviews Made Easy with Eclipse Plug-In
    Eclipse中Ant的配置与测试 转
    astyle 使用说明
    Eclipse远程调试出现“JDWP Transport dt_socket failed to initialize”的解决方案
    记录一个中括号的问题
  • 原文地址:https://www.cnblogs.com/unity3ds/p/6054168.html
Copyright © 2020-2023  润新知