Unity离线导览地图项目:Navmesh路径线距离计算代码求助
Unity离线导览地图:路径线距离计算实现
核心思路
离线导览的路径距离计算,本质是累加路径上所有相邻导航点的线段距离,再根据需求转换为米/千米单位。分两种常见场景处理:
场景1:基于Unity世界坐标的路径(场景按真实比例搭建)
如果你的场景是按1:1真实比例制作(Unity默认1单位=1米),直接用世界坐标计算即可;若场景有缩放,只需加一个比例系数转换。
实现代码
距离计算工具类
using UnityEngine; public class NavDistanceCalculator : MonoBehaviour { // 场景缩放系数:1 Unity单位对应真实世界的米数(默认1:1) [SerializeField] private float unitToMeterScale = 1f; /// <summary> /// 计算路径总长度(单位:米) /// </summary> /// <param name="pathPoints">路径上的连续导航点世界坐标数组</param> public float GetPathTotalMeters(Vector3[] pathPoints) { if (pathPoints == null || pathPoints.Length < 2) return 0f; float total = 0f; for (int i = 0; i < pathPoints.Length - 1; i++) { // 计算相邻两点的Unity单位距离 float segmentDist = Vector3.Distance(pathPoints[i], pathPoints[i + 1]); // 转换为真实米数并累加 total += segmentDist * unitToMeterScale; } return total; } /// <summary> /// 米转千米 /// </summary> public float MetersToKilometers(float meters) => meters / 1000f; }
使用示例(结合寻路逻辑)
// 假设你已通过A*或自定义寻路得到最短路径点数组 Vector3[] shortestPath = YourPathFindingAlgorithm(); // 替换为你的寻路方法 // 获取计算器实例 NavDistanceCalculator calc = FindObjectOfType<NavDistanceCalculator>(); // 计算并输出结果 float totalMeters = calc.GetPathTotalMeters(shortestPath); float totalKm = calc.MetersToKilometers(totalMeters); Debug.Log($"路径距离:{totalMeters:F2} 米 / {totalKm:F3} 千米");
场景2:基于经纬度的离线地图
如果你的导览数据是经纬度格式(比如从离线地图API导出的楼宇坐标),用Haversine公式计算球面距离(更贴合真实地球场景)。
经纬度距离计算补充代码
在上述工具类中添加以下方法:
/// <summary> /// 经纬度两点间球面距离计算(单位:米) /// </summary> public float HaversineDistance(float lat1, float lon1, float lat2, float lon2) { const float earthRadius = 6371000f; // 地球平均半径(米) float dLat = Mathf.Deg2Rad * (lat2 - lat1); float dLon = Mathf.Deg2Rad * (lon2 - lon1); float a = Mathf.Sin(dLat / 2) * Mathf.Sin(dLat / 2) + Mathf.Cos(Mathf.Deg2Rad * lat1) * Mathf.Cos(Mathf.Deg2Rad * lat2) * Mathf.Sin(dLon / 2) * Mathf.Sin(dLon / 2); float c = 2 * Mathf.Atan2(Mathf.Sqrt(a), Mathf.Sqrt(1 - a)); return earthRadius * c; } // 基于经纬度路径的总距离计算 public float GetPathTotalMetersFromGeoPoints((float lat, float lon)[] geoPoints) { if (geoPoints == null || geoPoints.Length < 2) return 0f; float total = 0f; for (int i = 0; i < geoPoints.Length - 1; i++) { var p1 = geoPoints[i]; var p2 = geoPoints[i + 1]; total += HaversineDistance(p1.lat, p1.lon, p2.lat, p2.lon); } return total; }
注意事项
- 若场景非真实比例,务必调整
unitToMeterScale参数,比如1 Unity单位对应2米,就设为2。 - 经纬度计算适用于大范围导览(比如整个校园),小范围场景用世界坐标更高效。
内容的提问来源于stack exchange,提问作者Christian Bautista Villanueva
相关产品推荐
相关产品推荐

