1.简介
1.1 功能介绍
本文主要做了两个功能:
1.扫描一张二维码生成一个操作台(桌子),这张桌子比二维码尺寸大非常多(就是实际物体大小的桌子),所以需要定位 好桌子和操作台之间的位置关系。并且生成之后,桌子会永远停在空间之中了,并不会随着视角的离开而消失,只有关闭应用程序之后才会消失。
2.操作台在空间中,只可以绕自己的本事的y轴旋转,不能发生移动和其他轴偏转,并且操作台本身是需要加上动画的。并且有事件进行触发。并且,我们要在显示器 的内部添加上浏览器的功能。
1.2 使用的相关技术和软件
软件:unity 2022.3 ; vs 2022
硬件设备:hololen2 ;台式电脑(i5-12600+5500+16G+1T Nvme)
相关开发工具:MRTK2.8.3+vuforia10.15.4+webview2
2.相关软件的安装
2.1 Unity2022+VS2022的安装
直接搜索unity 下载 最后一个全英文的。进入
进入下载unity hub 同时注册自己的账号。
打开,进入install 。
右上角安装,选择自己想要的版本。
安装Universal Windows 和 Windows Build Support 最上面还有vs2022 这三个。
在win10 开始界面打开vs installer
进入选择修改安装一下内容。
至此安装已经完毕。
2.2 创建项目
在projects -> New Project.等一会
Enable Version 可以 先不选。
第一创建项目初始化时间有点长,等1-2 分钟都差不多。创建结束后这个样子
2.3 下载导入并导入开发工具
下载MRTK
Download Mixed Reality Feature Tool from Official Microsoft Download Center
下载结束后,打开
等一会初始化后,start,点击Path 选择自己新建项目的 --> Discover Features.
‘
选择
全部选择确认 ,start over 等一会项目重启,就可以。
2.4 Mixed Reality Settings
选择第一个
选择 apply
导入TMp
完成
会自动打开这个界面,如果没打开,可以Edit-> project setting打开这个界面
openxr 哪里有黄色感叹号点击Fix all
进入这里
点击+ 好添加这几个控件,同时有黄色感叹号一律点击之后fix
回到这个界面,说明已经配置好了。
2.5 Vuforia 的安装
进入网站并先注册一个行号
Home | Engine Developer Portal
点击Downloads
下载
点击并进入导入。至此,我们将所有的项目准备都完成了。
3.创建自己的项目
3.1项目开始
打开空项目,Mixed Realtiy ->Add to Scene and Config,此时项目变成了一个3D 的项目。
创建vuforia 物体
在imageTarget 打开 Image Target Behaviour 。导入创建的数据库。下面将如何制作自己的数据库
3.2 创建自己的vuforia 数据库
进入vuforia 官网首页,点击开发,登录自己账号,进入一下页面
进入target Manager-> Add DataBase
add target 设置大小比例:注意1就是实际场景中的1m
成功后点击Download DataBase. 选择untiy Editor
下载后是一个unitypackage 结尾的文件点击(保证项目是打开的),导入项目中。
同时打开相机
点击Open Vuforia Engine configure
需要添加相机的key
获取key:在官网首页获取key 是一个非常长的字符串,我这里只截取了一行,实际中换成你自己的
至此,将data绑定到上面的内容上面。注意 Physical width 非常重要,0.15 表示图片在实际场景的大小就是15厘米,实际图片大小就要和这里的设置一样。否则定位就不对了。
3.3 导入模型
将预先设计工程师设计好的模型导入里面去。设置成预制体。
在项目中场景中添加一个新的cube 并在cube 下添加一个MRTK 自带的button.
MRTK button 打开方式是:
同时修改Textmeshpro 内的“内容” 改成Scanf.用来触发扫描的开始时间
同时新建一个新的空的物体ScanfDescriptions 用来提示是否触发了扫描,加上TestMeshPro 和眼动追踪功能。
3.4 相关脚本的编写
//此脚本挂在的ImageTarget ,实时获取,实际场景中的坐标位置
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class changePosition : MonoBehaviour
{
//public GameObject cube;
private Transform pos;
// Start is called before the first frame update
void Start()
{
pos = gameObject.transform;
//Screen.SetResolution(800, 600, true);
//Debug.Log(Screen.resolutions);
}
// Update is called once per frame
void Update()
{
//Debug.Log(pos.position);
}
public Transform GivePos()
{
return pos;
}
}
此脚本挂在到Cube 上面,用于生成物体
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Microsoft.MixedReality.Toolkit.UI;
using TMPro;
using System;
public class GetPosition : MonoBehaviour
{
// Start is called before the first frame update
//private Transform pos;
[HideInInspector]
public changePosition changepos;
public bool scanf = false;
//private Caldistance caldistance;
public TextMeshPro descriptions;
public Interactable descriptionButton;
public GameObject Desks;
public bool isOn = false;
public bool isActive = true;
protected DownUpController con;
void Start()
{
changepos = FindAnyObjectByType<changePosition>();
descriptionButton.OnClick.AddListener(verScanf);
//destroyButton.OnClick.AddListener(DestroyDesks);
//caldistance = FindAnyObjectByType<Caldistance>();
}
private void verScanf()
{
scanf = !scanf;
//descriptionButton
}
void CheckisOn()
{
con = FindAnyObjectByType<DownUpController>();
if (con != null)
{
isOn = true;
}
else
{
isOn = false;
}
}
public void showDescription()
{
if (!scanf)
{
descriptions.text = "未开启检测";
}
else
{
descriptions.text = "检测中......";
}
}
//如果想使用事件调用它的情况话,那么需要设置成public
public void ShowDesks()
{
transform.position = changepos.GivePos().position;
//float distance = caldistance.showDistance();
//if (distance <= 1.2f)
if (scanf==true)
{
if (isOn==false)
{
Instantiate(Desks, new Vector3(transform.position.x, transform.position.y-0.38f, transform.position.z+0.70f), transform.rotation);
descriptions.enabled = false;
isActive = false;
transform.GetChild(0).gameObject.SetActive(isActive);
isOn = true;
}
else
{
return;
}
}
else
{
return;
}
}
public bool testTriggle = false;
void Triggle()
{
//testTriggle = !testTriggle;
if (testTriggle == true)
{
ShowDesks();
}
}
// Update is called once per frame
void Update()
{
showDescription();
CheckisOn();
Triggle();
//ShowDesks();
}
//public static implicit operator GameObject(GetPosition v)
//{
// throw new NotImplementedException();
//}
}
将相关内容挂在到代码上面。
同时将时间绑定到ImageTarget Found() 函数上面。我们不是使用将模型设置成ImageTarget 这个方法,因为这种方式定位是不准的,尤其是虚拟物体的大小远大于实际图片的大小。并且会随着视线的离开,生成的物体也会发生便宜,我们希望
3.5 运行
未开启检测
检测中
触发 (unity手动设置Test Triggle=true 模拟实际场景中看见图片触发)
4.项目打包与部署
4.1 打包
Add op Scenes 将项目加入,设置如图所示,转到Universal windows Platorms 建议可以在创建的时候就直接转换到这个平台。
PlayerSettings ->设置其他内容
以下 需要设置
都设置完成会自动保存,之后选择需要输出的文件夹打包,打包大约1分钟。
4.2 项目的部署
打开打包的文件夹,点击.sln 文件。
之后设置如下,同时使用USB连接到hololen2 ,确保hololen2 已经开机,并且进入应用界面,点击设备那个播放的按钮。先会编译,之后运行,部署,第一次会要求输入ping 码,进入hololen2 开发着选项,配对,在vs 输入那个码。就可以了。
如果大家喜欢内容的话,我会把项目开源,在下面评论。