Unity中如何计算控制器沿指定轴的移动距离以驱动对象
解决VR控制器仅沿对象指定轴驱动移动的问题
你的核心问题是原代码用Vector3.Distance计算的是两点间直线距离,包含了所有方向的移动分量,导致非目标轴的手部移动也会驱动对象。正确的做法是把控制器的位移向量投影到对象的目标轴(这里是自身forward轴)上,只保留该方向的移动分量。
修正思路
- 抓取对象时,除了记录控制器初始位置,还要记录对象的初始位置(用于计算目标位置)
- 计算控制器从初始位置到当前位置的位移向量
- 通过向量点积,提取位移向量在对象
forward轴上的分量(这就是我们需要的有效移动距离) - 用这个有效分量驱动对象沿自身
forward轴移动
修正后的代码
private IController controller; private Vector3 controllerStartPosition; private Vector3 objectStartPosition; // 新增:记录抓取时对象的初始位置 public float sensitivity = 1f; // 可调整的灵敏度参数 private void OnTriggerEnter(Collider other) { controller = other.GetComponentInParent<IController>(); if (controller == null || controller.IsOccupied) { return; } controller.IsOccupied = true; controllerStartPosition = controller.GetPosition(); objectStartPosition = transform.position; // 保存对象初始位置 } private void Update() { if (controller == null) return; Vector3 currentControllerPos = controller.GetPosition(); // 计算控制器的位移向量(当前位置 - 初始位置) Vector3 controllerDelta = currentControllerPos - controllerStartPosition; // 提取位移向量在对象forward轴上的分量(点积运算) float validMoveDistance = Vector3.Dot(controllerDelta, transform.forward); // 驱动对象沿自身forward轴移动对应距离 transform.position = objectStartPosition + transform.forward * validMoveDistance * sensitivity; }
关键原理说明
Vector3.Dot(a, b)的作用是计算两个向量的点积,当b是单位向量(比如transform.forward)时,结果就是a向量在b方向上的投影长度。这一步会自动过滤掉非目标方向的移动分量——比如手部上下移动时,位移向量在forward轴上的投影为0,对象就不会产生误动。
内容的提问来源于stack exchange,提问作者SagiZiv
相关产品推荐
相关产品推荐

