Raycast未捕获所有坐标求助:Unity鼠标绘制坐标存储异常
问题分析与解决方案
mousePositions在每次鼠标按下时都会尝试添加坐标,而linePositions仅在Physics.Raycast命中GameObject时才会添加,两者数量差异的本质是部分鼠标位置对应的Raycast未命中目标GameObject,同时mousePositions的重复判断逻辑存在精度漏洞,导致无效元素过多。
具体问题排查与修复
1. Collider配置问题
- 问题:目标GameObject缺少Collider,或Collider未覆盖全屏,或Mesh Collider存在异常
- 修复:
- 给GameObject添加合适的Collider:如果是全屏平面,优先用
Box Collider,调整Size使其覆盖屏幕范围;若用Mesh Collider,确保Mesh是完整的平面网格,动态物体需勾选Convex选项。 - 检查Collider的位置是否与视觉上的GameObject重合,避免偏移导致Raycast打空。
- 给GameObject添加合适的Collider:如果是全屏平面,优先用
2. Layer与Raycast过滤问题
- 问题:Raycast可能命中了其他Layer的物体,或目标GameObject的Layer被忽略
- 修复:
- 在Raycast时指定目标Layer,避免无关物体干扰:
// 替换成你的目标物体所在Layer的序号 int targetLayer = LayerMask.NameToLayer("YourLayer"); int layerMask = 1 << targetLayer; // 只检测目标Layer,忽略其他 if (Physics.Raycast(Camera.main.ScreenPointToRay(mousePos), out RaycastHit hit, Mathf.Infinity, layerMask)) { // 原有逻辑... }
- 在Raycast时指定目标Layer,避免无关物体干扰:
3. 相机引用不一致
- 问题:代码中同时使用
_camera和Camera.main,若两者不是同一个相机,会导致坐标转换偏差,Raycast方向错误 - 修复:
- 统一相机引用:在Start方法中初始化
_camera = Camera.main;,后续代码仅使用_camera进行坐标转换和Raycast:private void Start() { _camera = Camera.main; } private void Update() { if (Input.GetMouseButton(0)) { Vector2 mousePos = Input.mousePosition; Vector2 Pos = _camera.ScreenToWorldPoint(mousePos); // ... if (Physics.Raycast(_camera.ScreenPointToRay(mousePos), out RaycastHit hit, Mathf.Infinity, layerMask)) { // 原有逻辑... } } }
- 统一相机引用:在Start方法中初始化
4. 浮点数精度导致mousePositions无效元素过多
- 问题:
Vector2.Contains依赖精确匹配,而ScreenToWorldPoint返回的浮点数存在微小精度误差,导致看似相同的坐标被重复添加 - 修复:
- 使用距离阈值判断坐标是否重复:
// 设定一个极小的阈值,比如0.01,根据需求调整 bool isPositionExist = mousePositions.Any(pos => Vector2.Distance(pos, Pos) < 0.01f); if (!isPositionExist) mousePositions.Add(Pos);
- 使用距离阈值判断坐标是否重复:
5. 性能优化(额外建议)
- 问题:每次Update都遍历所有linePositions并重复绘制像素,会随着列表变大导致帧率急剧下降
- 修复:
- 仅绘制新添加的坐标,避免重复操作:
if (!linePositions.Contains(paintPixelPosition)) { linePositions.Add(paintPixelPosition); // 只处理新加入的坐标 int pixelXOffset = paintPixelPosition.x - (_brush.width / 2); int pixelYOffset = paintPixelPosition.y - (_brush.height / 2); for (int x = 0; x < _brush.width; x++) { for (int y = 0; y < _brush.height; y++) { _templateDirtMask.SetPixel( pixelXOffset + x, pixelYOffset + y, Color.black ); } } }
- 仅绘制新添加的坐标,避免重复操作:
内容的提问来源于stack exchange,提问作者Newboy11
相关产品推荐
相关产品推荐

