第一步:官网下载zCore和zView插件,下载并安装Unity2018(我的是2018.4.3)
第二步:将下载的zCore6.0和zView6.0导入到Unity的工程中,导入后会生成两个文件夹
第三步:设置你的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();
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();
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();
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
目前也在学习阶段,有问题随时留言讨论学习~