{}!Google Tag Manager end}} PolySpatial 输入 | PolySpatial visionOS | 1.0.3
docs.unity3d.com
    显示 / 隐藏目录

    PolySpatial 输入

    PolySpatial软件包添加了一个新的输入设备“SpatialPointerDevice”,开发人员可以将其与输入系统动作图和API一起使用。

    您可以利用Enhanced Touch API轮询触摸阶段。

    Note
    • 轮询状态时,SpatialPointerState阶段将永远无法有效使用。相反,请使用EnhancedTouch API 获取活动触摸并查询阶段。 *当基于“Kind.DirectPinch”的Spatial Pointer Kind枚举过滤输入时,建议在开始触摸阶段不要检查此项。这是因为通常会在检测到直接捏合之前调用“Kind.Touch”,并在稍后的触摸阶段设置直接捏合。

    空间指针设备数据

    SpatialPointerDevice反映了SwiftUI的SpatialEventCollection数据,是在visionOS上与内容交互的主要方式。输入数据的限制取决于应用程序的模式(有界与无界)以及您请求数据的时间。有些数据仅对执行输入的第一帧有效。

    用户看着对象并用食指和拇指执行捏合手势来记录输入。这种类型的输入将注册为“Indirect Pinch”。还可以通过直接戳(“Touch”)或直接捏(“Direct Pinch”)对象来执行输入。

    • 最多可同时注册两个输入。
    • 用户正在查看的对象上必须有碰撞体才能捕获输入。
    • “inputDevicePosition”和“inputDeviceRotation”属性描述了控制交互的输入设备的姿势。通常,这是基于用户的捏合(手指和拇指之间的点)。
    • 默认情况下,交互光线基于用户的眼睛凝视。

    “SpatialPointerDevice”提供以下属性:

    • “.interactionPosition”:交互在世界空间中的位置。该值将在保持输入的同时更新,并且始终在碰撞体上启动。
    • “.deltaInteractionPosition”:起始交互位置和当前交互位置之间的差值。
    • “.startInteractionPosition”:交互的起始位置。这将始终位于碰撞体上,并且仅在输入发生时才会设置。
    • “.startInteractionRayOrigin”:基于用户眼睛凝视的光线原点。仅当应用程序处于无界模式时才可用,并且仅在发生输入时才可用。
    • “.startInteractionRayDirection”:基于用户眼睛凝视的光线方向。仅当应用程序处于无界模式时才可用,并且仅在发生输入时才可用。
    • “.inputDevicePosition”:用户捏合的位置(在用户的拇指和食指之间)。当输入保持不变时,该值将被更新。
    • “.inputDeviceRotation”:用户捏合的旋转(在用户的拇指和食指之间)。当输入保持不变时,该值将被更新。
    • “.kind”:交互类型,触摸(戳),间接捏合,直接捏合,指针,手写笔。
    • “.targetId”:正在交互的对象的实例ID。
    • “.phase”:当前交互的空间指针触摸阶段。
    • “.modifierKeys”:交互发生时处于活动状态的任何修饰键。
    • “.targetObject”:对交互目标的GameObject的直接引用。

    在动作图中使用空间指针

    “Spatial Pointer Device”列在输入操作映射的“Other”部分中。有一个用于检测主要交互的“Primary Spatial Pointer”,以及分别用于第一和第二交互的“Spatial Pointer #0”和“Spatial Pointer #1”。

    在直接代码中使用空间指针

    根据活动触摸输入显示“SpatialPointerState”数据的脚本。

    using Unity.PolySpatial.InputDevices;
    using UnityEngine;
    using UnityEngine.InputSystem.EnhancedTouch;
    using UnityEngine.InputSystem.LowLevel;
    using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;
    
    public class InputScript : MonoBehaviour
    {
        void OnEnable()
        {
            EnhancedTouchSupport.Enable();
        }
    
        void Update()
        {
            var activeTouches = Touch.activeTouches;
    
            // You can determine the number of active inputs by checking the count of activeTouches
            if (activeTouches.Count > 0)
            {
                // For getting access to PolySpatial (visionOS) specific data you can pass an active touch into the EnhancedSpatialPointerSupport()
                SpatialPointerState primaryTouchData = EnhancedSpatialPointerSupport.GetPointerState(activeTouches[0]);
    
                SpatialPointerKind interactionKind = primaryTouchData.Kind;
                GameObject objectBeingInteractedWith = primaryTouchData.targetObject;
                Vector3 interactionPosition = primaryTouchData.interactionPosition;
            }
        }
    }
    

    根据类型限制交互

    您可以检查空间指针设备数据以限制允许的交互类型。以下示例仅执行间接捏和戳交互的输入逻辑:

    var activeTouches = Touch.activeTouches;
    
    if (activeTouches.Count > 0)
    {
        SpatialPointerState primaryTouchData = EnhancedSpatialPointerSupport.GetPointerState(activeTouches[0]);
    
        if (primaryTouchData.Kind == SpatialPointerKind.IndirectPinch || primaryTouchData.Kind == SpatialPointerKind.Touch)
        {
            // do input logic here
        }
    }
    

    选择、移动和旋转对象

    您可以基于交互位置和设备旋转更新对象的位置和旋转。以下示例显示如何根据触摸阶段选择对象、平移和旋转对象以及取消选择对象:

    using UnityEngine;
    using Unity.PolySpatial.InputDevices;
    using UnityEngine.InputSystem.LowLevel;
    using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;
    using TouchPhase = UnityEngine.InputSystem.TouchPhase;
    
    
    public class InputScript : MonoBehaviour
    {
        GameObject m_SelectedObject;
    
        void Update()
        {
            var activeTouches = Touch.activeTouches;
    
            if (activeTouches.Count > 0)
            {
                SpatialPointerState primaryTouchData = EnhancedSpatialPointerSupport.GetPointerState(activeTouches[0]);
    
                if (activeTouches[0].phase == TouchPhase.Began)
                {
                    // if the targetObject is not null, set it to the selected object
                    m_SelectedObject = primaryTouchData.targetObject != null ? primaryTouchData.targetObject : null;
                }
    
                if (activeTouches[0].phase == TouchPhase.Moved)
                {
                    if (m_SelectedObject != null)
                    {
                        m_SelectedObject.transform.SetPositionAndRotation(primaryTouchData.interactionPosition, primaryTouchData.deviceRotation);
                    }
                }
    
                if(activeTouches[0].phase == TouchPhase.Ended || activeTouches[0].phase == TouchPhase.Canceled)
                {
                    m_SelectedObject = null;
                }
            }
        }
    }
    
    返回到顶部
    Copyright © 2024 Unity Technologies —
    • Your Privacy Choices (Cookie Settings)