AR多点测量APP故障排查:无法连续测量需重置场景
AR测量APP无限测量功能修复方案
核心问题分析
- 原代码依赖固定长度的tapePoints数组,仅支持两个测量点,无法扩展新的测量线
currentTapePoint变量在达到2后会被强制重置为0,阻断了连续测量流程- 单个
LineRenderer只能渲染一条线段,无法同时显示多条测量结果 - 距离文本和浮动文本组件绑定单一实例,无法对应多条测量线的信息展示
具体修改方案
1. 重构数据结构,支持多组测量数据
替换原有的固定数组和单一组件定义,改用动态集合存储每组测量的元素:
// 删除原有的tapePoints、line定义,替换为以下内容 public GameObject tapePointPrefab; // 在Inspector中拖拽你的测量点预制体 public LineRenderer lineRendererPrefab; // 在Inspector中拖拽你的线段预制体 public GameObject floatingDistancePrefab; // 在Inspector中拖拽浮动文本预制体 private List<LineRenderer> allLines = new List<LineRenderer>(); private List<GameObject> allFloatingTexts = new List<GameObject>(); private int currentMeasureStage = 0; // 0: 等待选起点, 1: 等待选终点 private Vector3 currentStartPoint; private LineRenderer previewLine; // 实时预览用的临时线段
2. 修改触摸逻辑,支持连续测量
去掉currentTapePoint的数值限制,改为完成一组测量后自动开启下一组:
// 修改Update方法中的触摸处理部分 if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began) { if (placementEnabled) { Vector3 hitPos = hits[0].pose.position; if (currentMeasureStage == 0) { // 放置测量起点 currentStartPoint = hitPos; SpawnTapePoint(hitPos); currentMeasureStage = 1; } else if (currentMeasureStage == 1) { // 放置测量终点,完成当前组测量 SpawnTapePoint(hitPos); SpawnNewLine(currentStartPoint, hitPos); SpawnFloatingText(currentStartPoint, hitPos); currentMeasureStage = 0; // 重置状态,准备下一组测量 } placementEnabled = false; } }
3. 新增实例化预制体的方法
添加动态生成测量点、线段、浮动文本的方法,避免复用旧组件冲突:
private void SpawnTapePoint(Vector3 position) { GameObject point = Instantiate(tapePointPrefab, position, Quaternion.identity); point.transform.parent = transform; // 将测量点归到管理器对象下,方便统一管理 point.tag = "TapePoint"; // 给测量点加标签,方便后续批量清理 } private void SpawnNewLine(Vector3 start, Vector3 end) { LineRenderer newLine = Instantiate(lineRendererPrefab, transform.position, Quaternion.identity); newLine.transform.parent = transform; newLine.SetPosition(0, start); newLine.SetPosition(1, end); allLines.Add(newLine); } private void SpawnFloatingText(Vector3 start, Vector3 end) { GameObject textObj = Instantiate(floatingDistancePrefab, Vector3.Lerp(start, end, 0.5f), Quaternion.identity); textObj.transform.parent = transform; TMP_Text textComp = textObj.GetComponent<TMP_Text>(); float distance = Vector3.Distance(start, end); float convertedDistance = ConvertDistance(distance); textComp.text = convertedDistance.ToString("#.##") + currentUnit; // 让文本始终朝向相机 textObj.transform.rotation = Quaternion.LookRotation(Camera.main.transform.forward, Camera.main.transform.up); allFloatingTexts.Add(textObj); } // 抽离单位转换逻辑,提升复用性 private float ConvertDistance(float rawDistance) { switch (currentUnit) { case Unit.m: return rawDistance; case Unit.cm: return rawDistance * 100; case Unit.i: return rawDistance / 0.0254f; case Unit.f: return rawDistance * 3.2808f; default: return rawDistance; } }
4. 实现实时测量预览
在选择起点后,实时显示未完成的测量线和距离:
// 在Update方法中添加实时预览逻辑 if (currentMeasureStage == 1 && hits.Count > 0) { // 创建或更新预览线 if (previewLine == null) { previewLine = Instantiate(lineRendererPrefab, transform.position, Quaternion.identity); previewLine.transform.parent = transform; previewLine.material.color = Color.yellow; // 用不同颜色区分已完成的线 } previewLine.SetPosition(0, currentStartPoint); previewLine.SetPosition(1, hits[0].pose.position); // 更新实时距离文本 float tempDistance = Vector3.Distance(currentStartPoint, hits[0].pose.position); float converted = ConvertDistance(tempDistance); distanceText.text = converted.ToString("#.##") + currentUnit; } else { // 隐藏并销毁预览线 if (previewLine != null) { Destroy(previewLine); previewLine = null; } }
5. 移除强制重置限制
删除原代码中阻断连续测量的强制重置逻辑:
// 修改原有的else if分支 else if (hits.Count == 0) { reticle.SetActive(false); // 移除原有的 currentTapePoint = 0; 这行代码 }
6. 新增全局重置功能(可选)
添加按钮调用的方法,一键清空所有测量结果:
public void ResetAllMeasurements() { // 销毁所有线段 foreach (var line in allLines) { Destroy(line); } // 销毁所有浮动文本 foreach (var text in allFloatingTexts) { Destroy(text); } // 销毁所有测量点 foreach (Transform child in transform) { if (child.gameObject.CompareTag("TapePoint")) { Destroy(child.gameObject); } } // 清空集合并重置状态 allLines.Clear(); allFloatingTexts.Clear(); currentMeasureStage = 0; distanceText.text = "0.00" + currentUnit; }
关键修改说明
- 用动态集合替代固定数组,实现无限测量的扩展性
- 把测量流程拆分为「选起点→选终点→完成一组→开启下一组」,支持连续操作
- 通过预制体实例化创建新的测量元素,避免复用旧组件导致的冲突
- 抽离重复逻辑(如单位转换),提升代码可维护性
内容的提问来源于stack exchange,提问作者Fannn
相关产品推荐
相关产品推荐

