环境:unity2017.4.11,插件版本:zCore-5.0.0.unitypackage,
将插件导入统一后,将zSpace /资源/ zCore拖到场景中,就可以进行开发了。
一:将主摄像机拖入到zCore中绑定,然后双击zCore过去会看到,几个框框,其中有个视图的框,将模型放到框里,在zSpace机器上才能正常显示。
二:摄像机上不能有滤镜,注意摄像机的渲染,这里如果有警告,消除警告,否则场景里模型会有黑影
三:在Playersetting里,将other Setting下的Color Space 改为Gamma,否则不会有谍影效果
将XR Settings里的Virtual Reality Supported勾上,并选择Stereo Display(non head-mounted),删除其他选项
四:有三个事件,触控笔移动(会一直触发),按键被按下(中间键是0,左键是2,右键是1),按键被释放
_zCore.TargetMove + = HandleMove;
_zCore.TargetButtonPress + = HandleButtonPress;
_zCore.TargetButtonRelease + = HandleButtonRelease;
用触控笔发射线来进行与物体交互,对于UI,可以启用鼠标来点击,或者去重写UI事件,让射线检测到也可以点击(可以参考VRTK插件)或者用3D模型来做UI
贴个脚本(由于时间紧网上找的脚本然后修改就用了,所以有点乱)
使用com.ootii.Messages;
使用系统;
使用System.Collections;
使用System.Collections.Generic;
使用UnityEngine;
使用zSpace.Core;
公共类RayGrapGameObject:MonoBehaviour {
private GameObject _stylusBeamObject = null;
public LineRenderer _stylusBeamRenderer = null;
// private StylusState RayGrapGameObject.Ra_stylusState = StylusState.Idle;
private StylusState _stylusState = StylusState.Idle;
//用于初始化(初始化)
private ZCore _zCore = null;
private bool _wasButtonPressed = false;
private static readonly float DEFAULT_STYLUS_BEAM_WIDTH = 0.002f;
private static readonly float DEFAULT_STYLUS_BEAM_LENGTH = 2f;
private float _stylusBeamLength = DEFAULT_STYLUS_BEAM_LENGTH;
private GameObject _grabObject = null;
private Vector3 _initialGrabOffset = Vector3.zero;
private Quaternion _initialGrabRotation = Quaternion.identity;
private float _initialGrabDistance = 0.0f;
private Transform mainCameraTrans;
//4.299965 - 0.891 //4.299965 - 2.044
private float D_Vakue = 3.408965f; //相机与TVM物体的高度的差值;
private float D_Vakue_wolin = 2.255965f; //相机与wolin物体的高度的差值;
private bool isCanMove = true; //是否可以移动镜头
public Transform volin_1;
公共变革索芳;
公共改造玄转;
公共BoxCollider TVMCollider;
公共转型TVM;
private void Awake(){
//Debuger.EnableOnScreen (true);
_zCore = GameObject.FindObjectOfType
if(_zCore == null){
Debug.LogError(“无法找到参考”);
this.enabled = false;
返回;
}
_zCore.TargetMove + = HandleMove;
_zCore.TargetButtonPress + = HandleButtonPress;
_zCore.TargetButtonRelease + = HandleButtonRelease;
mainCameraTrans = Camera.main.transform;
MessageDispatcher.AddListener(“ON_SEND_SETUP_0_MSG”,OnRecv);
MessageDispatcher.AddListener(“ON_SEND_SETUP_2_MSG”,OnRecv2);
MessageDispatcher.AddListener(“ON_SEND_SETUP_6_MSG”,OnRecv3);
MessageDispatcher.AddListener(JT_NANNING_MessageInfo.ON_SEND_BACKYUANPAN_MSG.ToString(),OnBack);
MessageDispatcher.AddListener(JT_NANNING_MessageInfo.CLICKOPERAOBJ.ToString(),OnRecvClickObj);
}
// x垂直屏幕,y屏幕的高,z屏幕的宽
私有空HandleButtonRelease(ZCore sender,ZCore.TrackerButtonEventInfo info){
//Debuger.LogError(“RateHandle_Release ===>”+ info.ButtonId);
//Debuger.LogError(“WorldPose_Release ===>”+ info.WorldPose.Position);
}
private void HandleButtonPress(ZCore sender,ZCore.TrackerButtonEventInfo info){
//Debuger.LogError ("TargetHandle_Pres ===>“+ info.ButtonId);
//Debuger.LogError(“WorldPose_Pres ===>”+ info.WorldPose.Position);
}
private void HandleMove(ZCore sender,ZCore.TrackerEventInfo info){
//Debuger.LogError(“WorldPose_Move ===>”+ info.WorldPose.Position);
}
private void OnDestroy(){
MessageDispatcher.RemoveListener(“ON_SEND_SETUP_0_MSG”,OnRecv);
MessageDispatcher.RemoveListener(“ON_SEND_SETUP_2_MSG”,OnRecv2);
MessageDispatcher.RemoveListener(“ON_SEND_SETUP_6_MSG”,OnRecv3);
MessageDispatcher.RemoveListener(JT_NANNING_MessageInfo.ON_SEND_BACKYUANPAN_MSG.ToString(),OnBack);
MessageDispatcher.RemoveListener(JT_NANNING_MessageInfo.CLICKOPERAOBJ.ToString(),OnRecvClickObj);
}
private void OnRecv(IMessage rMessage){
isRayObj = false;
isCanMove = false;
TVMCollider.enabled = false;
Xuanzhuan.gameObject.SetActive(假);
Suofang.gameObject.SetActive(假);
}
private void OnRecvClickObj(IMessage rMessage){
string name = rMessage.Data.ToString();
switch(name){
case“Suofang”:
isMoveOrChangeSize = false;
Suofang.GetChild(0).gameObject.SetActive(真);
Xuanzhuan.GetChild(0).gameObject.SetActive(假);
打破;
案例“
玄转”:isMoveOrChangeSize = true;
Suofang.GetChild(0).gameObject.SetActive(假);
Xuanzhuan.GetChild(0).gameObject.SetActive(真);
打破;
默认值:
break;
}
}
private void OnRecv2(IMessage rMessage){
//Debuger.Log(“change _zCore.ViewerScale = 1”);
mainCameraTrans.localPosition = new Vector3(-0.07f,1.907f,0.1549999f);
//mainCameraTrans.localEulerAngles = new Vector3(57f,68.31328f,0f);
_zCore.ViewerScale = 1.3f;
}
private void OnRecv3(IMessage rMessage){
mainCameraTrans.localPosition = new Vector3(-2.29769f,4.407f,-0.033f);
_zCore.ViewerScale = 10;
}
void void OnBack(IMessage rMessage){
isCanMove = true;
TVMCollider.enabled = true;
mainCameraTrans.localPosition = new Vector3(-2.29769f,4.299965f,-0.033f);
mainCameraTrans.localEulerAngles = new Vector3(55.9396f,90f,0);
_zCore.ViewerScale = 10;
//mainCameraTrans.localEulerAngles = new Vector3(55.9396f,90f,0f);
Xuanzhuan.gameObject.SetActive(真);
Suofang.gameObject.SetActive(真);
Suofang.localPosition = new Vector3(0f,1.999f,-1.53f);
Xuanzhuan.localPosition = new Vector3(0f,2.044f,-1.772f);
//Debuger.Log("Sender =====>“+ rMessage.Sender);
}
void Start(){
//创建触控笔对象
// _ stylusBeamObject = new GameObject(“StylusBeam”);
// _ stylusBeamRenderer = _stylusBeamObject.AddComponent
//_stylusBeamRenderer.material = new Material(Shader.Find(“Transparent / Refractive”));
_stylusBeamRenderer.startColor = Color.green;
_stylusBeamRenderer.endColor = Color.yellow;
}
RaycastHit hit;
bool limit = false;
bool limit1 = false;
ZCore.Pose姿势;
bool isButtonPressed;
bool isButtonPressed1;
bool isButtonPressed2;
bool isButton1Pressed = false;
Vector3 pos;
Vector3 pos1;
///
///是移动还是放大缩小
/// true-移动
/// false-改变大小
/// summary>
bool isMoveOrChangeSize = true;
Vector3 downPos;
Vector3 nowPos;
bool isRayObj = false;
void Update(){
//获取触控笔按钮状态信息
pose = _zCore.GetTargetPose(ZCore.TargetType.Primary,ZCore.CoordinateSpace.World);
isButtonPressed = _zCore.IsTargetButtonPressed(ZCore.TargetType.Primary,0); //中间键
isButtonPressed2 = _zCore.IsTargetButtonPressed(ZCore.TargetType.Primary,1); //右键
isButtonPressed1 = _zCore.IsTargetButtonPressed(ZCore.TargetType.Primary,2 ); //左键
if(isButtonPressed2){
if(Physics.Raycast(pose.Position,pose.Direction,out hit)){ //Debuger.Log (
Hit.transform.name);
//移动镜头
if(hit.transform.name ==“TVMCollider”&& isCanMove){
JT_InitScenes.instance.beginGetServerDataList( “TVM”);
}
}
}
if(isButtonPressed){
if(Physics.Raycast(pose.Position,pose.Direction,out hit)){
//Debuger.Log (Hit.transform.name);
if(hit.transform.name ==“TVMCollider”&& isCanMove){
isRayObj = true;
}
}
if(isRayObj){
nowPos = pose.Position;
if(isMoveOrChangeSize){
// TVM
float z = nowPos.z - downPos.z;
//Debuger.LogError("z=====>"+z);
if(z <0.05f && z> -0.05f){
return;
}
Vector3 roaValue = new Vector3(0f,2f,0f);
roaValue = z> 0.05f?roaValue:roaValue * -1;
TVM.localEulerAngles = TVM.localEulerAngles + roaValue;
downPos = nowPos;
}
else {
float x = nowPos.x - downPos.x;
//Debuger.LogError("x =====>
if(x <0.05f && x> -0.05f){
return;
}
Vector3 changeSize = new Vector3(0.02f,0.02f,0.02f);
changeSize = x> 0.05f?changeSize:changeSize * -1;
TVM.parent.localScale = TVM.parent.localScale - changeSize;
if(TVM.parent.localScale.x <= 0.8f){
TVM.parent.localScale = new Vector3(0.8f,0.8f,0.8f);
}
if(TVM.parent.localScale.x> = 1.6f){
TVM.parent.localScale = new Vector3(1.6f,1.6f,1.6f);
}
// downPos = nowPos;
}
}
}
如果(!isButtonPressed &&限制){
限制= TRUE;
downPos = pose.Position;
//Debuger.LogError ("downPos ===>“+ downPos);
if(Physics.Raycast(pose.Position,pose.Direction,out hit)){
MessageDispatcher.SendMessage(this,JT_NANNING_MessageInfo.CLICKOPERAOBJ.ToString(),hit.transform.name,EnumMessageDelay.IMMEDIATE);
}
}
if(isButtonPressed1 &&!limit1){
limit1 = true;
if(Physics.Raycast(pose.Position,pose.Direction,out hit)){
//Debuger.Log (Hit.transform.name);
//移动镜头
if(hit.transform.name ==“TVMCollider”&& isCanMove){
// D_Vakue
pos = mainCameraTrans.localPosition;
float height = hit.point.y + D_Vakue;
mainCameraTrans.localPosition = new Vector3(pos.x,height,pos.z);
pos1 = volin_1.localPosition;
float height1 = pos1.y + height - pos.y;
volin_1.localPosition = new Vector3(pos1.x,height1,pos1.z);
pos1 = Suofang.localPosition;
height1 = pos1.y + height - pos.y;
Suofang.localPosition = new Vector3(pos1.x,height1,pos1.z);
pos1 = Xuanzhuan.localPosition;
height1 = pos1.y + height - pos.y;
Xuanzhuan.localPosition = new Vector3(pos1.x,height1,pos1.z);
}
}
}
if(Physics.Raycast(pose.Position,pose.Direction,out hit)){
UpdateStylusBeam1(pose.Position,hit.point);
}
else {
//更新光线
this.UpdateStylusBeam(pose.Position,pose.Direction);
}
limit = isButtonPressed;
limit1 = isButtonPressed1;
}
private void UpdateStylusBeam1(Vector3 startPosition,Vector3 endPos){
if(_stylusBeamRenderer!= null){
float stylusBeamWidth = DEFAULT_STYLUS_BEAM_WIDTH;
float stylusBeamLength = _stylusBeamLength;
#if UNITY_5_4
_stylusBeamRenderer.SetWidth(stylusBeamWidth,stylusBeamWidth);
#else
_stylusBeamRenderer.startWidth = stylusBeamWidth;
_stylusBeamRenderer.endWidth = stylusBeamWidth;
#endif
_stylusBeamRenderer.SetPosition(0,startPosition);
_stylusBeamRenderer.SetPosition(1,endPos);
}
}
private void UpdateStylusBeam(Vector3 stylusPosition,Vector3 stylusDirection){
if(_stylusBeamRenderer!= null){
// float stylusBeamWidth = DEFAULT_STYLUS_BEAM_WIDTH * _zCore.ViewerScale;
// float stylusBeamLength = _stylusBeamLength * _zCore.ViewerScale;
float stylusBeamWidth = DEFAULT_STYLUS_BEAM_WIDTH;
float stylusBeamLength = _stylusBeamLength;
#if UNITY_5_4
_stylusBeamRenderer.SetWidth(stylusBeamWidth,stylusBeamWidth);
#else
_stylusBeamRenderer.startWidth = stylusBeamWidth;
_stylusBeamRenderer.endWidth = stylusBeamWidth;
#endif
_stylusBeamRenderer.SetPosition(0,stylusPosition);
_stylusBeamRenderer.SetPosition(1,stylusPosition +(stylusDirection * stylusBeamLength));
}
}
私人无效UpdateGrab(的Vector3 inputPosition,四元数inputRotation){
的Vector3 inputEndPosition = inputPosition +(inputRotation *(Vector3.forward * _initialGrabDistance));
//更新物体的角度
四元数objectRotation = inputRotation * _initialGrabRotation;
_grabObject.transform.rotation = objectRotation;
//更新抓取位置
Vector3 objectPosition = inputEndPosition +(objectRotation * _initialGrabOffset);
_grabObject.transform.position = objectPosition;
}
private void BeginGrab(GameObject hitObject,float hitDistance,Vector3 inputPosition,Quaternion inputRotation){
Vector3 inputEndPosition = inputPosition +(inputRotation *(Vector3.forward * hitDistance));
//储存初始抓取状态
_grabObject = hitObject;
_initialGrabOffset = Quaternion.Inverse(hitObject.transform.rotation)*(hitObject.transform.position - inputEndPosition);
_initialGrabRotation = Quaternion.Inverse(inputRotation)* hitObject.transform.rotation;
_initialGrabDistance = hitDistance;
}
private enum StylusState {
Idle = 0,
Grab = 1,
}
}