当前位置:网站首页>ARFoundation从零开始9-AR锚点(AR Anchor)
ARFoundation从零开始9-AR锚点(AR Anchor)
2022-07-29 05:07:00 【suelee_hm】
项目代码:https://github.com/sueleeyu/ar-localanchor
使用锚点,可以让虚拟对象看起来仿佛留在 AR 场景中。锚点可确保对象在空间中看起来保持不变,并保持在现实世界中的虚拟对象的视觉效果。
锚点的工作原理[1]:
与锚点相关的两个概念是:世界空间和姿态。
世界空间:是指相机和对象所在位置的坐标空间;相机和对象在现实世界空间中的位置会逐帧更新
姿势:表示对象在世界空间中的位置和方向,在 iOS 中也称为“转换”
创建锚点时,您可以使用一个姿势来描述相对于当前帧的世界空间估计的位置和方向。
您向此锚点附加了一个或多个对象。锚点和连接到它的对象看起来会停留在它们在真实世界中的位置。由于锚点姿势在每个帧中适应世界空间更新,因此锚点也会相应地更新对象姿态。
您可以将多个对象附加到同一个锚点,以确保即使在锚点的姿态调整的情况下,这些对象仍能保持它们的相对位置和方向。
锚点的类型:
1.本地锚点:随应用一起存储在本地,并且仅对应用实例有效。用户必须实际位于其放置锚点的位置
2.云锚点:存储在 Google Cloud 中,并可在应用实例之间共享。用户必须实际位于其放置锚点的位置
3. 地理空间锚点:基于大地纬度、经度和海拔,加上 Google 的视觉定位系统 (VPS) 数据,可在世界上几乎任何地方提供精确的位置;这些锚点可能会在应用实例之间共享。只要应用已连接到互联网并且可以使用 VPS,用户就可以从远程位置放置锚点。
下面开始添加本地锚点。
一、添加组件
1.添加AR Anchor Manager和AR Raycast Manager。点击左侧Hierarchy-AR Session Origin,点击右侧Inspector的Add Component按钮,分别搜索添加AR Plane Manager、AR Anchor Manager和AR Raycast Manager:
2.新建AR Default Plane:
拖到当前工程的Prefabs下,同时删除Hierarchy下新建的AR Default Plane:
Hierarchy下选择AR Session Origin,右侧找到AR Plane Manager,将Prefabs下创建的AR Default Plane预制件拖动到AR Plane Manager的Plane Prefab栏:
3.添加Button组件,选择该组件,右侧Inspector内增加onclick事件,实现清除锚点功能:
二、unity知识点
在可跟踪对象(比如平面)或 ARCore 会话环境中创建锚点,例如:
1.为场景中已有对象添加锚点
gameObject.AddComponent<ARAnchor>();
或在Inspector中添加:
2.动态实例化预制件并添加锚点
void AnchorContent(Vector3 position, GameObject prefab)
{
// Create an instance of the prefab
var instance = Instantiate(prefab, position, Quaternion.identity);
// Add an ARAnchor component if it doesn't have one already.
if (instance.GetComponent<ARAnchor>() == null)
{
instance.AddComponent<ARAnchor>();
}
}
3.添加附着在平面上的锚点
public ARAnchor AttachAnchor(ARPlane plane, Pose pose);
如果想移除锚点,就销毁游戏对象的ARAnchor组件(或游戏对象自身):
//m_AnchorManager.RemoveAnchor(anchor);已弃用
Destroy(anchor.gameObject);
三、添加代码
新建AnchorCreator.cs脚本:
拖动AnchorCreator.js挂载到AR Session Origin上:
1.定义预制件,将准备好的锚点预制件拖到cs脚本的Prefab栏:
[SerializeField]
GameObject m_Prefab;//要放置的预制件
public GameObject prefab
{
get => m_Prefab;
set => m_Prefab = value;
}
2.update方法中根据类型检测射线碰撞
// Raycast against planes and feature points射线的检测类型包括平面和
const TrackableType trackableTypes =
TrackableType.FeaturePoint |
TrackableType.PlaneWithinPolygon;
// Perform the raycast
if (m_RaycastManager.Raycast(touch.position, s_Hits, trackableTypes))
{
…//do createAnchor
}
如果是平面,依附平面添加锚点:
if (hit.trackable is ARPlane plane)
{
var planeManager = GetComponent<ARPlaneManager>();
if (planeManager)
{
Logger.Log("Creating anchor attachment.");
var oldPrefab = m_AnchorManager.anchorPrefab;
m_AnchorManager.anchorPrefab = prefab;//替换AnchorManager原有锚点预制件
anchor = m_AnchorManager.AttachAnchor(plane, hit.pose);//将锚点锚定到平面,当前hit.pose创建锚点
m_AnchorManager.anchorPrefab = oldPrefab;//还原AnchorManager原有锚点预制件
SetAnchorText(anchor, $"Attached to plane {plane.trackableId}");
return anchor;
}
}
否则,根据碰撞的特征点或其他可追踪对象实例化游戏对象添加锚点:
// Note: the anchor can be anywhere in the scene hierarchy
var gameObject = Instantiate(prefab, hit.pose.position, hit.pose.rotation);//使用预制件和当前pose创建对象
// Make sure the new GameObject has an ARAnchor component
anchor = gameObject.GetComponent<ARAnchor>();
3.清除锚点
publicvoid RemoveAllAnchors()
{
Logger.Log($"Removing all anchors ({m_Anchors.Count})");
foreach (var anchor in m_Anchors)
{
Destroy(anchor.gameObject);//m_AnchorManager.RemoveAnchor(anchor);已弃用
}
m_Anchors.Clear();
}
4.AnchorCreator.cs:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
namespace FrameworkDesign.Example
{
[RequireComponent(typeof(ARAnchorManager))]
[RequireComponent(typeof(ARRaycastManager))]
publicclassAnchorCreator : MonoBehaviour
{
[SerializeField]
GameObject m_Prefab;//要放置的预制件
public GameObject prefab
{
get => m_Prefab;
set => m_Prefab = value;
}
static List<ARRaycastHit> s_Hits = new List<ARRaycastHit>();
List<ARAnchor> m_Anchors = new List<ARAnchor>();
ARRaycastManager m_RaycastManager;
ARAnchorManager m_AnchorManager;
voidAwake()
{
m_RaycastManager = GetComponent<ARRaycastManager>();
m_AnchorManager = GetComponent<ARAnchorManager>();
}
void SetAnchorText(ARAnchor anchor, string text)
{
var canvasTextManager = anchor.GetComponent<CanvasTextManager>();
if (canvasTextManager)
{
canvasTextManager.text = text;
}
}
ARAnchor CreateAnchor(in ARRaycastHit hit)
{
ARAnchor anchor = null;
// If we hit a plane, try to "attach" the anchor to the plane
if (hit.trackable is ARPlane plane)
{
var planeManager = GetComponent<ARPlaneManager>();
if (planeManager)
{
Logger.Log("Creating anchor attachment.");
var oldPrefab = m_AnchorManager.anchorPrefab;
m_AnchorManager.anchorPrefab = prefab;//替换AnchorManager原有锚点预制件
anchor = m_AnchorManager.AttachAnchor(plane, hit.pose);//将锚点锚定到平面,当前hit.pose创建锚点
m_AnchorManager.anchorPrefab = oldPrefab;//还原AnchorManager原有锚点预制件
SetAnchorText(anchor, $"Attached to plane {plane.trackableId}");
return anchor;
}
}
// Otherwise, just create a regular anchor at the hit pose
Logger.Log("Creating regular anchor.");
// Note: the anchor can be anywhere in the scene hierarchy
var gameObject = Instantiate(prefab, hit.pose.position, hit.pose.rotation);//使用预制件和当前pose创建对象
// Make sure the new GameObject has an ARAnchor component
anchor = gameObject.GetComponent<ARAnchor>();
if (anchor == null)
{
anchor = gameObject.AddComponent<ARAnchor>();//为当前对象添加锚点
}
SetAnchorText(anchor, $"Anchor (from {hit.hitType})");
return anchor;
}
publicvoid RemoveAllAnchors()
{
Logger.Log($"Removing all anchors ({m_Anchors.Count})");
foreach (var anchor in m_Anchors)
{
Destroy(anchor.gameObject);//m_AnchorManager.RemoveAnchor(anchor);已弃用
}
m_Anchors.Clear();
}
voidUpdate()
{
if (Input.touchCount == 0)
return;
var touch = Input.GetTouch(0);
if (touch.phase != TouchPhase.Began)
return;
// Raycast against planes and feature points射线的检测类型包括平面和
const TrackableType trackableTypes =
TrackableType.FeaturePoint |
TrackableType.PlaneWithinPolygon;
// Perform the raycast
if (m_RaycastManager.Raycast(touch.position, s_Hits, trackableTypes))
{
// Raycast hits are sorted by distance, so the first one will be the closest hit.
var hit = s_Hits[0];
// Create a new anchor
var anchor = CreateAnchor(hit);
if (anchor)
{
// Remember the anchor so we can remove it later.
m_Anchors.Add(anchor);//锚定以Component的形式对应于GameObject
}
else
{
Logger.Log("Error creating anchor");
}
}
}
}
}
三、android打包运行
如未配置,参看《ARFoundation从零开始3》:
ARFoundation从零开始3-创建ARFoundation项目_suelee_hm的博客-CSDN博客
1.安装运行
四、常见问题
五、参考文献
1. ARCore文档:
使用锚点 | ARCore | Google Developers
2.ARFoundation示例:
3.本项目示例源代码:
边栏推荐
- Jackson parsing JSON detailed tutorial
- TMUX essays
- JS (foreach) return cannot end the function solution
- [wechat applet] swiper slides the page, and the left and right sides of the slider show part of the front and back, showing part of the front and back
- JS daily question (12)
- Word如何查看文档修改痕迹?Word查看文档修改痕迹的方法
- Introduction of JDBC preparestatement+ database connection pool
- WPS如何进行快速截屏?WPS快速截屏的方法
- 2021-10-11
- excel怎么设置行高和列宽?excel设置行高和列宽的方法
猜你喜欢
WPS insert hyperlink cannot be opened. What should I do if I prompt "unable to open the specified file"!
向往的开源之多YOUNG新生 | 从开源到就业的避坑指南来啦!
Sparksql inserts or updates in batches and saves data to MySQL
Stack and queue and priority queue (large heap and small heap) simulation implementation and explanation of imitation function
excel怎么设置行高和列宽?excel设置行高和列宽的方法
玩家访问网站自动弹窗加QQ群方法以及详细代码
如何让照片中的人物笑起来?HMS Core视频编辑服务一键微笑功能,让人物笑容更自然
MySQL定时调用预置函数完成数据更新
时间序列分析的表示学习时代来了?
office2010每次打开都要配置进度怎么解决?
随机推荐
Reply from the Secretary of jindawei: the company is optimistic about the market prospect of NMN products and has launched a series of products
P2181 diagonal
【微信小程序--解决display:flex最后一行对齐问题。(不连续排列会分到两边)】
Exception - ...MaxUploadSizeExceededException: Maximum upload size exceeded; nested exception is ...
DataSourceClosedException: dataSource already closed at Mon Oct 25 16:55:48 CST 2021
Unity Metaverse(三)、Protobuf & Socket 实现多人在线
使用Jstack、Jconsole和jvisualvm进行死锁分析
【config】配置数组参数
基于注解的三层项目的改造及添加包扫描的方式
Rolabelimg to data format data
ODOO开发教程之图表
Google gtest事件机制
Young freshmen yearn for more open source | here comes the escape guide from open source to employment!
传奇开区网站如何添加流量统计代码
How to solve the problem of configuring the progress every time Office2010 is opened?
What servers are needed to build mobile app
Pivot table of odoo development tutorial
Raspberry pie 4B + Intel neural computing stick (stick2) +yolov5 feasibility study report
excel怎么设置行高和列宽?excel设置行高和列宽的方法
Big silent event Google browser has no title