- 环境配置
- 打包apk环境配置
- 安装jdk,和安卓SDK(版本要足够高)
- 打开unity 中edit目录下的 首选项,选择SDK和JDK路径
(3)Ctrl + shift + B打开 build Settings选项框,点击选择并转换为Android平台
- Vuforia配置
- Unity内置商店内,下载vuforia package
- 登录官网,并注册开发者帐号
- 从官网上获取到App license
- Import ARcamera
- 选中被拖入场景中的ARCamera,在其属性面板中点击”Open Vuforia Configuration“,在“App License Key”中,将之前申请的App license复制到输入框中
- 项目框架的具体实现
- 原项目打包
将需要打包的物体放入一个gameObject空物体下,然后将其作为一个整体拉入资源文件夹下,生成一个预制体
- AR项目具体实现
(1)将原项目预制体作为参数传入imageTarget 下的Model Swap脚本
(2)进入到官网的开发者页面,添加数据库
(3)选取用作图像识别的图片,并添加到数据库,然后得到3星级以上的图片,即可考虑下载数据库到本地,否则需要处理图像(调整对比度,锐度等)
(4)下载并导入数据库到项目中,然后点击imageTarget,选择数据库
三、UI交互(Scenes Introduction)
1.开启Scenes Introduction功能的选择框
(1)UI组件:定义于一个全局的canvas下,由Toggle勾选框组件构成
(2)源代码(实现对Target下UI组件的开关控制):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class OpenIntroduction_Canvas : MonoBehaviour {
public GameObject introductionCanvas; //介绍框
public GameObject pointCanvas; //中心点
// Use this for initialization
public void IsopenIntroduction()
{
introductionCanvas.SetActive(!introductionCanvas.activeInHierarchy);
pointCanvas.SetActive(introductionCanvas.activeInHierarchy);
}
}
- 将源代码挂于总控制gameobject下,并设置Toggle的bool返回值改变时调用该gameobject下的IsopenIntroduction 函数
2.UI介绍框及其交互
(1)UI组件:定义于一个Target局部下的canvas下,各个场景物体的介绍
- 脚本构成:共有两个脚本,分别是挂在ARcamera上的 Port_GazeController.cs 脚本和挂在可识别物体上的Port_InteractiveObj.cs脚本
- 识别用的中心圈状读取条image挂于ARcamera下,需设置两个读取条(一个作为白色背景,一个作为读取缓冲),作为读取缓冲的读取条,需要设置Image Type为Filled类型,并调整其相关参数,如下图
- 源代码
①Port_InteractiveObj.CS
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Port_InteractiveObj : MonoBehaviour {
public GameObject p;
public GameObject pointImage;
public void hovered()
{ //凝视中
}
public void activated()
{ //凝视完
p.SetActive(true);
pointImage.SetActive(false);
}
public void leave()
{ //视线移开
p.SetActive(false);
pointImage.SetActive(true);
}
}
②Port_GazeController.CS
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Port_GazeController : MonoBehaviour {
public Canvas canvasPoint; //中心点图标
public Image reticleImage; //中心点图片的填充
public float deafaultGazeDistance;
private GameObject curInteractiveObj; //当前注视的物体
private GameObject oldInteractiveObj; //上一个注视的物体
private Port_InteractiveObj objDoing; //当前注视物体的交互脚本
private Port_InteractiveObj oldobjDoing; //上一个物体的交互脚本
private float gazeDurationTime = 2.0f;
private float counttime;
private Vector3 canvasOriginalPosition;
private Vector3 canvasOriginalRotation;
private Vector3 canvasOriginalScale;
// Use this for initialization
void Start()
{
canvasOriginalPosition = new Vector3(0, 0, deafaultGazeDistance);
canvasOriginalRotation = canvasPoint.transform.eulerAngles;
canvasOriginalScale = new Vector3(0.02f, 0.02f, 0.02f);
reticleImage.fillAmount = 0;
}
// Update is called once per frame
void Update()
{
Ray ray = new Ray(transform.position, transform.forward);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100))
{
canvasPoint.transform.localScale = hit.distance * canvasOriginalScale * 0.05f;
canvasPoint.transform.position = hit.point;
canvasPoint.transform.forward = hit.normal;
if (hit.transform.gameObject != curInteractiveObj) //当我们射到了新物体(不等于之前的物体)
{
if (curInteractiveObj != null)
{ //如果当前凝视的物体不为空
oldInteractiveObj = curInteractiveObj; //当前凝视物体记录为上一个凝视的物体
oldobjDoing = oldInteractiveObj.GetComponent<Port_InteractiveObj>();
if (oldobjDoing)
{ //如果该物体上存在InteractiveObj脚本
oldobjDoing.leave(); //调用脚本内的视线离开函数
}
}
curInteractiveObj = hit.transform.gameObject; //更新当前凝视物体
objDoing = curInteractiveObj.GetComponent<Port_InteractiveObj>();
if (objDoing)
{ //如果当前凝视物体有InteractiveObj脚本,调用脚本内的凝视中函数
objDoing.hovered();
}
}
else
{
counttime += Time.deltaTime;
if (counttime < gazeDurationTime) //凝视中,开始填充图片
{
reticleImage.fillAmount = counttime / gazeDurationTime;
}
else
{
reticleImage.fillAmount = 0.0f;
counttime = 0;
objDoing.activated();
}
}
}
else
{ //如果中心点离开了,重置中心点
canvasPoint.transform.localPosition = canvasOriginalPosition;
canvasPoint.transform.localEulerAngles = Vector3.zero;
canvasPoint.transform.localScale = canvasOriginalScale;
counttime = 0;
reticleImage.fillAmount = 0;
if (curInteractiveObj != null)
{
objDoing = curInteractiveObj.GetComponent<Port_InteractiveObj>();
if (objDoing)
{
objDoing.leave();
curInteractiveObj = null;
}
}
}
}
private void OnDrawGizmos()
{
Gizmos.DrawIcon(this.transform.position, "AutoMan.png");
}
}
四、调试与打包
1.调试
(1)调整模型的大小与参数,模型的下方有对照图片,可模拟现实中扫描图片后,模型于图片的相对位置和大小
(2)调试时,可将手机设置为开发者模式,与电脑用USB连接,然后unity内Ctrl+B一键打包并安装于手机上(手机会跳出一个询问框:是否同意安装应用于手机上)
2.打包
(1)Ctrl +shift +B打开Build settings页面,点击play settings,可以更改应用名和应用图标,并且Other settings选项框中的Packagename必须要更改
(2)Ctrl +shift +B打开Build settings页面,点击下方Build,选择保存APK路径以及APK命名