利用Unity实现Vuforia SmartTerrain的简易应用
SmartTerrain是可以让虚拟模型和现实世界产生互动的一种方式,这次我们用Unity2017.1.0f3,Vuforia6.2.10来实现以下智能地形的一个简单的应用。
实现目标:点击地形的某个地方,机器人可以移动过去,碰到障碍物就停止。
我们首先来设置一下这个智能地形,好让我们的应用能够使用它。
一、首先导入Vuforia的插件,配置ARCamera和ImageTarget。
这里先设置ImageTarget:将ImageTarget设置成
(勾选上EnableSmartTerrain后下面会自动出来),然后设置地形的边界(以识别图为中心,用的是虚拟世界的单位)
然后Hierarchy中就会有这些东西:
然后设置ARCamera:ARCamera下要这样设置:一定要赋值这个WorldCenter,这个WorldCenter是我们选中的这个
的上面的SurfaceBehaviour。
再点击VufuriaConfiguration,设置这个
下面那个Scene Unit in mm 个人理解应该是一个比例,场景中的单位和现实世界的以毫米为单位的比值。
下面来测试一下这个智能地形,我们先将SmartTerrain和PropTemplate的材质替换一下,换成一个有颜色的材质就好。
我这边换的是SmartTerrain:蓝色
PropTemplate:绿色
测试运行:
然后我们来看一下这些都是些啥:
可以看到我们运行后,之前的SmartTerrain_ImageTarget的子物体都不显示了,然而多出来了他的子物体的克隆物体。
选中这个克隆物体:可以看到他包括了这一大堆绿方块和蓝色的地板。
到Inspector下查看:
这个东西包含一个MeshCollider,这也是等会我们可以做射线选择的原因,还有他上面挂着的脚本是:
这个脚本我的理解是动态更新这个Mesh和MeshCollider。
这个蓝色的地板Primary Surface只会克隆一次,包括他的Tag,子物体啥的一堆都会原模原样的克隆下来。这也就是智能地形的“地板”。
再来看看这些绿方块:
这个绿方块就是地形中的障碍物,就是和识别图不在一个平面或者是现实场景中的其他三维物体。
他会动态更新他的MeshFilter和子物体的Collider,他的子物体有碰撞器,可以做物理碰撞。
所以我理解的大概流程是,识别到识别图后克隆一个Primary Surface,然后开始分析地形并动态修改地形的Mesh和Collider,然后如果现实中存在地形上的一些其他3D物体,就会克隆Prop Template来表示这些3D物体。
所以我们可以在编辑器中最原始的上面添加脚本或者给他添加子物体来达到我们所期望的效果,因为是原封不动的克隆,所以添加的脚本,效果等等都会原封不动的反映到智能地形上。
我们继续实现我们的功能。添加一个机器人模型到SmartTerrain_ImageTarget--PrimarySurface 下,让它成为地形的子物体,然后调整模型,让他的中心在他的正下方,与平面接触的地方。
在新建一个Tag和一个Layer,分别表示障碍物和平面:layer是MovePlane,Tag是 Obstacle。
接着写个脚本给机器人,代表我们单击屏幕,让他移动
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveRobot : MonoBehaviour
{
private Vector3 targtPos;
// Use this for initialization
void Start ()
{
targtPos = this.transform.position;
}
// Update is called once per frame
void Update ()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo, 100f))
{
if (hitInfo.collider.gameObject.layer == LayerMask.NameToLayer("MovePlane"))
{
targtPos = hitInfo.point;
Quaternion q = Quaternion.FromToRotation(this.transform.forward, targtPos - this.transform.position);
this.transform.forward = q * this.transform.forward;
//也可以直接用LookAt实现
}
}
}
}
void FixedUpdate()
{
this.transform.position = Vector3.MoveTowards(this.transform.position, targtPos, 0.4f);
//this.transform.LookAt(targtPos);
}
void OnCollisionEnter(Collision other) //有碰撞,则阻止移动
{
if (other.gameObject.tag == "Obstacle")
{
targtPos = this.transform.position;
}
}
}
由于平面存在MeshCollider,所以可以用射线选择点,然后让他移动。所以我们需要在机器人上加上刚体。
如果需要修改3D物体的一些属性啥的,可以在这个地方修改和添加。可以动态替换他的网格等生成一些奇奇怪怪的东西。
比如我们加一个粒子发射器,让它扫描出来以后发射粒子。
最后把材质啥的都改回去
运行测试:
基本效果是这样,绿色的线是地形的三角形组成。单击地图之外的敌方机器人是走不过去的。
基本的智能地形就是这样。
本文内容部分参考自Think加速想象力出版的《AR与VR开发实战》教程,更多学习资料也请关注www.arvrthink.com。