周记目录
本周任务
- 整合 3D 拖拽代码
- 将实验操作平台调整为半透明
- 限制操作空间
- 建立实验台
整合代码
上周将3D拖拽代码直接写到了 AugmentedImageVisualizer 中,这周改一下结构。
首先在场景下的 EventSystem 中新建一个脚本,命名为 ObjDrag ,作为物体拖动事件的脚本。代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjDrag : MonoBehaviour
{
private Camera cam;//发射射线的摄像机
private GameObject go;//射线碰撞的物体
// Start is called before the first frame update
void Start()
{
cam = Camera.main;
Debug.Log("Start");
}
// Update is called once per frame
void FixedUpdate()
{
if (Input.GetMouseButton(0)) //监测点击事件 鼠标与手机屏幕都可
{
Debug.Log("ButtonDown");
//以摄像头为起点的第一条射线
Ray ray = cam.ScreenPointToRay(Input.touches[0].position);
RaycastHit hitInfo;
//制作 LayerMask ,只有 object 的 Layer ,用于下面射线判定
LayerMask mask1 = 1 << LayerMask.NameToLayer("object");
//如果射线在2M范围内碰到 mask1 的物体,进入此分支
if (Physics.Raycast(ray, out hitInfo, 2, mask1.value))
{
Debug.Log("Object 1 " + hitInfo.collider.gameObject.name + " " + hitInfo.collider.gameObject.layer);
go = hitInfo.collider.gameObject;
RaycastHit hitInfoPlane;
//制作 LayerMask ,只有 plane 的 Layer ,用于下面射线判定
LayerMask mask2 = 1 << (LayerMask.NameToLayer("plane"));
//第二个射线,如果射线在2M范围内碰到 mask2 的物体,进入此分支
if (Physics.Raycast(ray, out hitInfoPlane, 2, mask2.value))
{
Debug.Log("Plane " + hitInfoPlane.collider.gameObject.name + " " + hitInfoPlane.collider.gameObject.layer);
//移动物体
go.transform.position = hitInfoPlane.point;
}
}
}
}
}
核心代码和上周的差不多,接着还需要更改 AugmentedImageVisualizer 中的代码。先删除 拖拽部分代码,接着还需要将前半部分的固定到初始位置代码更改下,否则可能会造成无法拖动。上周是因为拖动部分代码在这一段代码的后半部分,所以前后两次更改位置。现在分开了,有可能将相框角固定在初始位置。
所以我们通过设置 isLoad 变量来判断是不是第一次监测到识别图。改动后代码如下:
//-----------------------------------------------------------------------
// <copyright file="AugmentedImageVisualizer.cs" company="Google">
//
// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------
namespace GoogleARCore.Examples.AugmentedImage
{
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using GoogleARCore;
using GoogleARCoreInternal;
using UnityEngine;
/// <summary>
/// Uses 4 frame corner objects to visualize an AugmentedImage.
/// </summary>
public class AugmentedImageVisualizer : MonoBehaviour
{
/// <summary>
/// The AugmentedImage to visualize.
/// </summary>
public AugmentedImage Image;
/// <summary>
/// A model for the lower left corner of the frame to place when an image is detected.
/// </summary>
public GameObject FrameLowerLeft;
/// <summary>
/// A model for the lower right corner of the frame to place when an image is detected.
/// </summary>
public GameObject FrameLowerRight;
/// <summary>
/// A model for the upper left corner of the frame to place when an image is detected.
/// </summary>
public GameObject FrameUpperLeft;
/// <summary>
/// A model for the upper right corner of the frame to place when an image is detected.
/// </summary>
public GameObject FrameUpperRight;
/// <summary>
/// The Unity Update method.
/// </summary>
///
private Boolean isLoad=false;
private void Start()
{
}
public void Update()
{
if (Image == null || Image.TrackingState != TrackingState.Tracking)
{
//如果没有找到需要识别的图片,则把四个相框角都隐藏掉
FrameLowerLeft.SetActive(false);
FrameLowerRight.SetActive(false);
FrameUpperLeft.SetActive(false);
FrameUpperRight.SetActive(false);
isLoad = false;
return;
}
else if(isLoad==false)
{
//找到识别图,把四个相框的位置固定到应该显示的位置
//注意用的 localPosition ,是相对于 AugmentedImageVisualizer 的局部位置
float halfWidth = Image.ExtentX / 2;
float halfHeight = Image.ExtentZ / 2;
FrameLowerLeft.transform.localPosition =
(halfWidth * Vector3.left) + (halfHeight * Vector3.back);
FrameLowerRight.transform.localPosition =
(halfWidth * Vector3.right) + (halfHeight * Vector3.back);
FrameUpperLeft.transform.localPosition =
(halfWidth * Vector3.left) + (halfHeight * Vector3.forward);
FrameUpperRight.transform.localPosition =
(halfWidth * Vector3.right) + (halfHeight * Vector3.forward);
FrameLowerLeft.SetActive(true);
FrameLowerRight.SetActive(true);
FrameUpperLeft.SetActive(true);
FrameUpperRight.SetActive(true);
isLoad = true;
}
}
}
}
操作平面与玻璃仪器双面半透明贴图
操作平面目前还是只有一面有碰撞,所以直接做成正反两个平面, 对着相反的方向即可