Unity zSpace 开发

本篇博客适合没有zSpace开发经验的朋友,从下载SDK到配置发布、UI事件、触控笔事件。。

一、项目设置

第一步:官网下载zCore和zView插件,下载并安装Unity2018(我的是2018.4.3)

第二步:将下载的zCore6.0和zView6.0导入到Unity的工程中,导入后会生成两个文件夹

 3

第三步:设置你的Unity工程

1.Edit—ProjectSettings—Player—OtherSetting—Rendering—ColorSpace改为Gamma

2.Edit—ProjectSettings—Player—OtherSetting—AutoGraphicsAPIforWindows取消勾选

3.Edit—ProjectSettings—Player—OtherSetting—GraphicsAPIsforWindows-添加OpenGLCore,其他全部删除

4.Edit—ProjectSettings—Player—OtherSetting—Configuration—ScriptingRuntimeVersion改为4.x

5.Edit—ProjectSettings—Player—XRSetting中勾选Virtual Reality Supported

6.Edit—ProjectSettings—Player—XRSetting—Virtual Reality SDKs添加Stereo Display (non head-mounted)

 7.Edit—ProjectSettings—Player—Resolution and Presentation—Run In Back ground选中(如果不用zView可以不设置此项)

第四步:查看zCore自带案例,如下

 第五步:发布测试,找到一个适合自己想要功能的场景,发布到PC后,将发布程序拷贝到zSpace设备上运行即可

第六步:如果你的软件不使用zView的话忽略此项

1.将zView预制体拖拽到场景中

2.zView组件如下:

配置zView

大多数情况下,ZView应该在你第一次测试时就能工作。然而,越来越复杂的场景更有可能遇到图形问题时,通过zView的增强现实模式。在zView的检查器字段中出现的公共属性可以用来管理这种复杂性。

Ignore Layers

你可以在zView中隐藏对象,方法是把它们放在可以忽略的层上。有一些常见的元素需要考虑zView忽略。在zView表示过程中,UI元素通常不是内容焦点,而是被隐藏的主要考虑因素。其他可能值得忽略的元素将是周边环境艺术,在AR模式下不能正确或清晰地呈现。

Mask Layer

zView在zSpace显示周围放置一个蒙版,在显示表面上有一个洞。设置到此层的对象将只通过此显示蒙版可见。这个遮罩将优先于正视差框遮罩,不管遮罩对象是负视差还是正视差。

Mask Render Queue

增强现实模式的框蒙版的渲染队列优先级。这只在启用ARModeEnableTransparency时使用,通常应该分配小于2000(不透明几何)的值,以确保它的深度将在渲染任何不透明几何之前进行渲染。

Mask Size

增强现实模式的盒子面具的尺寸,单位是米。盒子面具不同于

Show Mask

在Unity Editor的SceneView窗口中启用增强现实模式的框掩码的调试可视化。

Enable Transparency

如果未启用,则强制增强现实模式的虚拟相机渲染的所有非蒙版像素的alpha值为1。默认情况下,这是禁用的,因为大多数与不透明和透明几何相关的标准着色器要么在它们的alpha通道中有不正确的值,要么不写它们的alpha通道到帧缓冲区。

Active ZCamera

确保这个属性被分配给在任何时候都在积极使用的ZCamera。如果没有分配,ZView将在awake时调用. findobjectoftype()来自己找到它,但理想情况下它将手工分配。

 连接到zView(放到Start()中):

IntPtr connection = zView.GetCurrentActiveConnection();
if(connection == IntPtr.Zero)
{
    zView.ConnectToDefaultViewer();
}

示例:

    private void Start()
    {
#if !UNITY_EDITOR
        ZView _zView = GameObject.FindObjectOfType<ZView>();
        IntPtr connection = _zView.GetCurrentActiveConnection();
        if (connection == IntPtr.Zero)
        {
            _zView.ConnectToDefaultViewer();
        }
#endif
    }

 看到此项表示你的zSpace工程已经全部配置完成,点击发布运行起来吧~

上述在官网都可查到出处Unity3D zCore 6.0: Developer Guide (zspace.com)https://developer.zspace.com/docs/unity3d-zcore-6-guide 

二、UI系统

1.画布设置

在zSpace-Core-Prefabs中可以看到ZCanvas预制体,拖拽到场景中,ZCanvas默认渲染模式是WorldSpace,将zSpace的相机拖拽至EventCamera即可,并确保ZCanvas添加了以下组件

2.Button事件

UI事件:经过测试,button.onClick.AddListener()的UI事件可以触发,而手动绑定的无法触发

3D事件:通过引入命名空间IBeginDragHandler, IDragHandler, IEndDragHandler来实现

触控笔中键:PointerEventData.InputButton.Left

触控笔左键:PointerEventData.InputButton.Middle

触控笔右键:PointerEventData.InputButton.Right

示例:用触控笔来实现对模型的拖拽、旋转、放大、缩小功能:


//
//  Copyright (C) 2007-2020 zSpace, Inc.  All Rights Reserved.
//


using UnityEngine;
using UnityEngine.EventSystems;

using zSpace.Core.EventSystems;
using zSpace.Core.Input;

namespace zSpace.Core.Samples
{
    public class MyDraggable : ZPointerInteractable, IBeginDragHandler, IDragHandler, IEndDragHandler
    {
        
        // Public Methods
        

        public override ZPointer.DragPolicy GetDragPolicy(ZPointer pointer)
        {
            if (pointer is ZMouse)
            {
                return ZPointer.DragPolicy.LockToScreenAlignedPlane;
            }

            if (pointer is ZStylus)
            {
                return ZPointer.DragPolicy.LockHitPosition;
            }

            return base.GetDragPolicy(pointer);
        }

        public void OnBeginDrag(PointerEventData eventData)
        {
            ZPointerEventData pointerEventData = eventData as ZPointerEventData;
            if (pointerEventData == null ||
                pointerEventData.button != PointerEventData.InputButton.Left)
            {
                return;
            }

            Pose pose = pointerEventData.Pointer.EndPointWorldPose;

            // Cache the initial grab state.
            this._initialGrabOffset =
                Quaternion.Inverse(this.transform.rotation) *
                (this.transform.position - pose.position);

            this._initialGrabRotation =
                Quaternion.Inverse(pose.rotation) *
                this.transform.rotation;

            // If the grabbable object has a rigidbody component,
            // mark it as kinematic during the grab.
            var rigidbody = this.GetComponent<Rigidbody>();
            if (rigidbody != null)
            {
                this._isKinematic = rigidbody.isKinematic;
                rigidbody.isKinematic = true;
            }

            // Capture pointer events.
            pointerEventData.Pointer.CapturePointer(this.gameObject);
        }

        private float z;
        private void Start()
        {
            z = transform.localPosition.z;
        }
        public void OnDrag(PointerEventData eventData)
        {
            ZPointerEventData pointerEventData = eventData as ZPointerEventData;
            if (pointerEventData == null)
            {
                return;
            }

            if (pointerEventData.button == PointerEventData.InputButton.Left)
            {
                Pose pose = pointerEventData.Pointer.EndPointWorldPose;

                // Update the grab object's rotation.
                this.transform.rotation = pose.rotation * this._initialGrabRotation;

                // Update the grab object's position.
                this.transform.position = pose.position + (this.transform.rotation * this._initialGrabOffset);

            }
            if (pointerEventData.button == PointerEventData.InputButton.Right)
            {
                if (transform.position.z > z)
                {
                    transform.localScale = new Vector3(transform.localScale.x + 0.01f, transform.localScale.y + 0.01f, transform.localScale.z + 0.01f);
                }
                else if(transform.position.z < z)
                {
                    transform.localScale = new Vector3(transform.localScale.x - 0.01f, transform.localScale.y - 0.01f, transform.localScale.z - 0.01f);
                }
                //transform.localScale = new Vector3(transform.localScale.x + 0.01f, transform.localScale.y + 0.01f, transform.localScale.z + 0.01f);
            }
            //if (pointerEventData.button == PointerEventData.InputButton.Middle)
            //{
            //    transform.localScale = new Vector3(transform.localScale.x - 0.01f, transform.localScale.y - 0.01f, transform.localScale.z - 0.01f);
            //}
        }

        public void OnEndDrag(PointerEventData eventData)
        {
            ZPointerEventData pointerEventData = eventData as ZPointerEventData;
            if (pointerEventData == null ||
                pointerEventData.button != PointerEventData.InputButton.Left)
            {
                return;
            }

            // Release the pointer.
            pointerEventData.Pointer.CapturePointer(null);

            // If the grabbable object has a rigidbody component,
            // restore its original isKinematic state.
            var rigidbody = this.GetComponent<Rigidbody>();
            if (rigidbody != null)
            {
                rigidbody.isKinematic = this._isKinematic;
            }
        }

        
        // Private Members
        

        private Vector3 _initialGrabOffset = Vector3.zero;
        private Quaternion _initialGrabRotation = Quaternion.identity;
        private bool _isKinematic = false;
    }
}

上述皆参考ZCore自带脚本:Draggable

目前也在学习阶段,有问题随时留言讨论学习~ 

猜你喜欢

转载自blog.csdn.net/qq_42047805/article/details/124340512