ARCore场景中单个球体触摸拖拽移动异常问题求助
解决ARCore中多个球体拖拽的两个问题
首先咱们拆解下你遇到的两个问题根源:
- 所有球体一起移动:每个球体上的脚本都在独立执行相同的触摸逻辑,而且完全没判断当前触摸是否命中自己——只要有触摸事件,每个脚本都会移动自己挂载的球体,自然看起来所有球同步动。
- 触摸任意位置都响应:原代码根本没做「触摸点是否命中当前球体」的校验,不管点在哪,脚本都会触发移动逻辑。
再说说你尝试的射线检测为啥无效:Physics.Raycast(touch.position, touch.position, out hit) 参数完全错了——射线得从相机位置出发,方向指向触摸点对应的世界方向,而不是用触摸坐标当起点和方向。另外,GameObject.FindGameObjectWithTag 会返回场景中第一个匹配标签的物体,这也不是你要的「当前被点击的那个球体」。
下面是修正后的完整脚本,我标注了关键改进点:
using UnityEngine; public class SphereDrag : MonoBehaviour { private Vector3 offset; private Vector3 screenPoint; // 标记当前球体是否被选中,每个球独立维护自己的状态 private bool isSelected = false; void Update() { // 遍历所有触摸点(单点触摸场景下逻辑足够清晰) for (int i = 0; i < Input.touchCount; i++) { Touch touch = Input.GetTouch(i); switch (touch.phase) { case TouchPhase.Began: // 生成从相机指向触摸点的射线,这才是正确的屏幕转世界射线方式 Ray ray = Camera.main.ScreenPointToRay(touch.position); if (Physics.Raycast(ray, out RaycastHit hit)) { // 只有射线命中当前脚本挂载的球体时,才标记为选中状态 if (hit.collider.gameObject == this.gameObject) { isSelected = true; // 计算球体与触摸点的偏移量,避免拖拽时球体瞬移到触摸点 screenPoint = Camera.main.WorldToScreenPoint(transform.position); offset = transform.position - Camera.main.ScreenToWorldPoint( new Vector3(touch.position.x, touch.position.y, screenPoint.z) ); } } break; case TouchPhase.Moved: // 只有被选中的球体才执行移动逻辑,避免所有球同时响应 if (isSelected) { Vector3 cursorPoint = new Vector3(touch.position.x, touch.position.y, screenPoint.z); Vector3 cursorPosition = Camera.main.ScreenToWorldPoint(cursorPoint) + offset; transform.position = cursorPosition; } break; case TouchPhase.Ended: case TouchPhase.Canceled: // 触摸结束或中断时,取消选中状态,防止球体继续跟随触摸移动 isSelected = false; break; } } } }
关键改进说明:
- 添加
isSelected状态标记:每个球体独立维护自己的选中状态,只有被点击的球才会响应移动逻辑,解决了所有球一起动的问题。 - 正确的射线检测逻辑:用
Camera.main.ScreenPointToRay生成射线,确保能准确检测到触摸点对应的世界物体。 - 精准判断命中当前物体:通过
hit.collider.gameObject == this.gameObject确认点击的是当前脚本挂载的球体,而非其他物体。 - 处理触摸结束状态:触摸松开或意外中断时取消选中,避免球体无意义地继续移动。
额外注意事项:
- 确保每个球体都添加了Sphere Collider(没有Collider的话,射线检测会完全失效),且Collider处于启用状态。
- ARCore的相机要设置
MainCamera标签,保证Camera.main能正确获取到相机实例。 - 如果场景中有其他带Collider的物体,你可以给球体设置专属标签,然后在射线检测时增加标签判断(比如
hit.collider.CompareTag("Sphere")),避免误触其他物体。
内容的提问来源于stack exchange,提问作者nerk
相关产品推荐
相关产品推荐

