• 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、添加ManipulationTranslate脚本,计算相对位移,然后进行更新物体的新的位置。

    using UnityEngine;  
    using System.Collections;  
    using HoloToolkit.Unity;  
      
    public class ManipulationTranslate: MonoBehaviour {  
      
        private Vector3 manipulationPreviousPosition;  
      
        // Use this for initialization  
        void Start () {  
          
        }  
          
        // Update is called once per frame  
        void Update () {  
              
        }  
      
        void PerformManipulationStart(Vector3 position)  
        {  
            //设置初始位置  
            manipulationPreviousPosition = position;  
        }  
      
        void PerformManipulationUpdate(Vector3 position)  
        {  
            if (GestureManager.Instance.IsManipulating)  
            {  
                //计算相对位移,然后更新物体的位置     
                Vector3 moveVector = Vector3.zero;  
                moveVector = position - manipulationPreviousPosition;  
                manipulationPreviousPosition = position;  
                transform.position += 2f * moveVector;  
            }  
        }  

    4、运行测试

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

  • 相关阅读:
    密码数学大作业
    《数据结构》教材测评
    机器学习概述
    SQL基础-流程控制结构
    SQL基础-变量 存储过程和函数
    SQL基础-视图
    SQL基础-TCL 事务控制语言
    SQL基础-DDL 数据定义语言
    SQL基础-DML 数据操作语言
    SQL基础 -DQL 数据查询语言(下)
  • 原文地址:https://www.cnblogs.com/unity3ds/p/6039475.html
Copyright © 2020-2023  润新知