Unity Oculus VR中通过子对象移动父对象问题求助
通过手柄移动棋盘时出现来回跳动问题
我尝试通过预制体中的手柄(Handle)移动棋盘(ChessBoard),当前代码看似能运行,但棋盘每帧会跳到我身后再返回,一直来回跳动。这是我目前最接近正确实现的版本,求解决建议。
当前代码
using Oculus.Interaction; using Oculus.Interaction.HandGrab; using System.Linq; using UnityEngine; public class MoveBoardWithHandle : MonoBehaviour { private HandGrabInteractable interactor; private Rigidbody board; private Rigidbody handle; Quaternion initRoataion; void Start() { interactor = GetComponent<HandGrabInteractable>(); var rigidBodies = GetComponentsInParent<Rigidbody>(); handle = rigidBodies.FirstOrDefault(x => x.name == "Handle"); board = rigidBodies.FirstOrDefault(x => x.name == "ChessBoard"); initRoataion = handle.rotation; } bool reSetHandleRotation = false; void Update() { if(interactor.State == InteractableState.Select) { Vector3 boardOffset = board.transform.position - handle.transform.position; board.transform.position = handle.transform.position -= boardOffset; reSetHandleRotation = true; } else { if(reSetHandleRotation) { handle.transform.rotation = initRoataion; reSetHandleRotation = false; } } } }
相关截图
- 父物体Inspector截图:

- 子物体Inspector截图:

问题分析与修复方案
核心问题
你在每帧修改了手柄的位置(handle.transform.position -= boardOffset),这和Oculus交互系统对手柄的控制逻辑冲突,导致位置来回跳动。同时直接修改transform.position会绕过物理引擎,容易引发异常行为。
修复代码
using Oculus.Interaction; using Oculus.Interaction.HandGrab; using System.Linq; using UnityEngine; public class MoveBoardWithHandle : MonoBehaviour { private HandGrabInteractable _handGrabInteractable; private Rigidbody _boardRb; private Rigidbody _handleRb; private Vector3 _boardToHandleOffset; // 棋盘与手柄的初始相对偏移 private Quaternion _initialHandleRotation; void Start() { _handGrabInteractable = GetComponent<HandGrabInteractable>(); var rigidBodies = GetComponentsInParent<Rigidbody>(); _handleRb = rigidBodies.FirstOrDefault(x => x.name == "Handle"); _boardRb = rigidBodies.FirstOrDefault(x => x.name == "ChessBoard"); if (_boardRb != null && _handleRb != null) { // 提前记录初始偏移,避免每帧计算出错 _boardToHandleOffset = _boardRb.transform.position - _handleRb.transform.position; } _initialHandleRotation = _handleRb.transform.rotation; } private bool _needResetHandleRotation = false; void FixedUpdate() // 物理操作放在FixedUpdate更稳定 { if (_handGrabInteractable?.State == InteractableState.Select) { if (_boardRb != null && _handleRb != null) { // 根据手柄当前位置+初始偏移,计算棋盘目标位置 Vector3 targetBoardPos = _handleRb.transform.position + _boardToHandleOffset; // 用MovePosition让物理引擎处理移动,避免冲突 _boardRb.MovePosition(targetBoardPos); } _needResetHandleRotation = true; } else { if (_needResetHandleRotation && _handleRb != null) { _handleRb.MoveRotation(_initialHandleRotation); _needResetHandleRotation = false; } } } }
额外配置建议
- 将手柄(Handle)的Rigidbody设置为运动学(Is Kinematic),因为它由Oculus交互系统控制,不需要物理模拟
- 棋盘(ChessBoard)的Rigidbody可根据需求设置是否运动学,开启重力或碰撞检测,确保物理交互正常
内容的提问来源于stack exchange,提问作者JISH
相关产品推荐
相关产品推荐

