Unity中使用Ray-cast时如何防止物体向相机漂移?
解决Unity物体静止时向射线相机漂移的问题
可能的原因及对应修复方案
1. 仅在鼠标移动时更新物体位置
若当前每帧都执行射线计算并赋值位置,即使鼠标静止,浮点运算的微小误差会持续累积引发漂移。
- 修复逻辑:记录上一帧鼠标位置,仅当鼠标位置发生变化时,才重新计算并设置物体位置
private Vector3 _lastMousePos; void Start() { _lastMousePos = Input.mousePosition; } void Update() { Vector3 currentMousePos = Input.mousePosition; // 加入微小阈值过滤鼠标抖动 if (Vector3.Distance(currentMousePos, _lastMousePos) > 0.01f) { Ray ray = Camera.main.ScreenPointToRay(currentMousePos); if (Physics.Raycast(ray, out RaycastHit hit)) { transform.position = hit.point; } _lastMousePos = currentMousePos; } }
2. 固定平面替代物理射线检测
如果物体仅在某一固定平面(比如地面、XY平面)移动,不要依赖物理碰撞体的射线检测(易受碰撞体精度影响),直接计算屏幕点与固定平面的交点:
// 示例:物体在Y=0的平面移动 private Vector3 _lastMousePos; void Start() { _lastMousePos = Input.mousePosition; } void Update() { Vector3 currentMousePos = Input.mousePosition; if (Vector3.Distance(currentMousePos, _lastMousePos) > 0.01f) { Ray ray = Camera.main.ScreenPointToRay(currentMousePos); // 计算射线与Y=0平面的交点 float distance = -ray.origin.y / ray.direction.y; Vector3 targetPos = ray.GetPoint(distance); transform.position = targetPos; _lastMousePos = currentMousePos; } }
3. 修正透视相机的精度问题
使用透视相机时,近裁剪面设置过小(比如0.001)会导致屏幕坐标转世界坐标时出现浮点误差。
- 修复:将相机近裁剪面设为合理值(比如0.1);或在计算射线时,将起点适当后移,避开近裁剪面的精度盲区。
4. 锁定物体固定轴向
若物体不需要全3D移动,固定不需要变化的轴向(比如Y轴高度),避免射线计算的微小波动引发轴向漂移:
// 固定Y轴高度,仅更新X、Z轴 transform.position = new Vector3(hit.point.x, transform.position.y, hit.point.z);
额外排查点
- 检查相机是否存在细微位移(比如脚本控制、动画组件驱动),相机移动会导致射线起点变化,进而引发物体漂移
- 排查物体是否有其他脚本修改位置(比如刚体物理、动画约束),多脚本的位置控制冲突也会导致漂移
内容的提问来源于stack exchange,提问作者Heebo
相关产品推荐
相关产品推荐

