如何在Unity结合Mapbox开发的AR应用中将标记点锚定到真实世界中
实现步骤
1. 前置依赖配置
- 确保你的Unity项目已经集成了对应平台的AR SDK:iOS用ARKit,Android用ARCore,或者直接用Unity的AR Foundation做跨端封装,避免分别适配两套API
- 确认Mapbox Unity SDK的配置项里,关闭虚拟地图渲染:找到Mapbox对象下的
AbstractMap组件,取消勾选Enable Rendering,不需要显示虚拟地图瓦片,只保留SDK的坐标转换能力即可 - 检查位置权限配置:iOS在Info.plist添加
NSLocationWhenInUseUsageDescription权限声明,Android在AndroidManifest添加ACCESS_FINE_LOCATION权限
2. 核心坐标映射逻辑实现
这一步是和Pokemon Go类虚拟地图AR最核心的区别:不需要把经纬度映射到虚拟地图的世界坐标,而是直接映射到AR会话的真实世界坐标系
- 启动应用后先等待两个初始化完成:AR会话初始化成功(AR Foundation的
ARSession.state变为ARSessionState.SessionTracking)、设备GPS首次定位成功(Mapbox的LocationProvider返回有效经纬度、海拔) - 记录此时的设备位置作为锚定原点经纬度,同时记录此时AR Session的世界坐标原点作为对应三维空间原点
- 用Mapbox SDK提供的
GeoCoordinate转换方法,把每个GeoJSON里的点的经纬度,换算为和锚定原点的相对偏移量(单位:米):// 示例代码片段 GeoCoordinate originGeo = new GeoCoordinate(originLat, originLon); GeoCoordinate pointGeo = new GeoCoordinate(pointLat, pointLon); float xOffset = (float)originGeo.DistanceTo(new GeoCoordinate(originGeo.Latitude, pointGeo.Longitude)) * (pointGeo.Longitude > originGeo.Longitude ? 1 : -1); float zOffset = (float)originGeo.DistanceTo(new GeoCoordinate(pointGeo.Latitude, originGeo.Longitude)) * (pointGeo.Latitude > originGeo.Latitude ? 1 : -1); // y轴偏移可以取GeoJSON里的高程值,或者默认用AR平面检测的地面高度 Vector3 arWorldPos = new Vector3(xOffset, pointElevation, zOffset);
3. GeoJSON数据解析与标记点生成
- 用Mapbox SDK内置的
GeoJsonReader工具直接读取你导出的4份GeoJSON文件,遍历所有Feature的Point类型几何数据 - 每类GeoJSON对应你要显示的不同AR预制体(比如四类标记分别对应不同的3D模型),按照上一步算出的
arWorldPos位置实例化预制体 - 如果需要动态加载只显示用户周围一定范围内的点,可以加距离过滤:只生成和当前设备位置距离小于你设置的阈值(比如500米)的标记点
4. 动态校准优化
- GPS本身存在1-10米的误差,建议添加手动校准功能:用户可以通过单指拖动、双指旋转的交互,整体调整所有AR标记点的位置偏移,适配实际场景
- 如果你的标记点都是放置在地面上,可以结合AR Foundation的平面检测结果,自动修正标记点的y轴高度,避免模型悬浮或者陷到地面里
- 设备移动过程中每3秒重新拉取一次最新GPS位置,根据位置变化动态更新周边标记点的显示状态,超出范围的销毁,新进入范围的生成
内容的提问来源于stack exchange,提问作者Hayls99
相关产品推荐
相关产品推荐

