Hololens空间锚点+场景保持

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.WSA;
using UnityEngine.XR.WSA.Persistence;

public class MyCube : MonoBehaviour
{

    public string ObjectAnchorStoreName;
    WorldAnchorStore anchorStore;
    bool placing = false;
    public GameObject Text;
    void Start()
    {
        //获取WorldAnchorStore 对象
        WorldAnchorStore.GetAsync(AnchorStoreReady);
    }

    private void AnchorStoreReady(WorldAnchorStore store)
    {
        anchorStore = store;
        string[] ids = anchorStore.GetAllIds();
        //遍历之前保存的空间锚,载入指定id场景对象信息
        for (int index = 0; index < ids.Length; index++)
        {
            if (ids[index] == ObjectAnchorStoreName)
            {
                WorldAnchor wa = anchorStore.Load(ids[index], gameObject);
                break;
            }
        }
    }

    void OnSelect()
    {
        if (anchorStore == null)
        {
            return;
        }
        if (placing)
        {
            SpatialMapping.Instance.DrawVisualMeshes = false;
            //当再次点击全息对象时,保存空间锚信息
            WorldAnchor attachingAnchor = gameObject.AddComponent();
            if (attachingAnchor.isLocated)
            {
                bool saved = anchorStore.Save(ObjectAnchorStoreName, attachingAnchor);
            }
            else
            {
                //有时空间锚能够立刻被定位到。这时候,给对象添加空间锚后,空间锚组件的isLocated属性
                //值将会被设为true,这时OnTrackingChanged事件将不会被触发。因此,在添加空间锚组件
                //后,推荐立刻使用初始的isLocated状态去调用OnTrackingChanged事件
                attachingAnchor.OnTrackingChanged += AttachingAnchor_OnTrackingChanged;
            }
        }
        else
        {
            SpatialMapping.Instance.DrawVisualMeshes = true;
            //当全息对象已附加空间锚组件后,它不能被移动。如果你需要移动全息对象的话,那么你必须这样做:
            //1.立刻销毁空间锚组件
            //2.移动全息对象
            //3.添加一个新的空间锚到全息对象上
            WorldAnchor anchor = gameObject.GetComponent();
            if (anchor != null)
            {
                DestroyImmediate(anchor);
            }

            string[] ids = anchorStore.GetAllIds();
            for (int index = 0; index < ids.Length; index++)
            {
                if (ids[index] == ObjectAnchorStoreName)
                {
                    bool deleted = anchorStore.Delete(ids[index]);
                    break;
                }
            }
        }
        placing = !placing;
    }
    // Update is called once per frame
    void Update()
    {
        if (placing)
        {
            var headPositon = Camera.main.transform.position;
            var gazeDirection = Camera.main.transform.forward;
            RaycastHit hit;
            if (Physics.Raycast(headPositon, gazeDirection, out hit, 30f, SpatialMapping.PhysicsRaycastMask))
            {
                this.transform.position = hit.point;
                Quaternion toQuat = Camera.main.transform.localRotation;
                toQuat.x = 0;
                toQuat.z = 0;
                this.transform.rotation = toQuat;
            }
        }
    }
    private void AttachingAnchor_OnTrackingChanged(WorldAnchor self, bool located)
    {
        if (located)
        {
            bool saved = anchorStore.Save(ObjectAnchorStoreName, self);
            self.OnTrackingChanged -= AttachingAnchor_OnTrackingChanged;
        }
    }
}

这个脚本挂到物体上

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.WSA.Input;
/// 
/// 手势识别
/// 
public class GazeGestureManager : MonoBehaviour
{
    public static GazeGestureManager Instance { get; private set; }
    public GameObject FocusedObject { get; private set; }

    private GestureRecognizer recognizer;
    // Use this for initialization
    void Start()
    {
        Instance = this;
        recognizer = new GestureRecognizer();
        recognizer.Tapped += (args) =>
        {
            if (FocusedObject != null)
            {
                FocusedObject.SendMessageUpwards("OnSelect", SendMessageOptions.DontRequireReceiver);
            }
        };
        recognizer.StartCapturingGestures();
    }

    // Update is called once per frame
    void Update()
    {
        GameObject oldFocusObject = FocusedObject;
        var headPositon = Camera.main.transform.position;
        var gazeDirection = Camera.main.transform.forward;
        RaycastHit hit;
        if (Physics.Raycast(headPositon, gazeDirection, out hit))
        {
            FocusedObject = hit.collider.gameObject;
        }
        else
        {
            FocusedObject = null;
        }

        if (FocusedObject != oldFocusObject)
        {
            //取消手势 重新开始捕捉
            recognizer.CancelGestures();
            recognizer.StartCapturingGestures();
        }
    }
}

这个脚本是手势识别 使用手势广播消息 OnSelect() 方法 物体上方法回调来保存调整空间锚点

你可能感兴趣的:(unity,C#)