Unity中物体缩放状态无法保留问题求助
问题解决:XR物体缩放抖动、缩放值重置问题
问题分析
你的脚本从XR Origin下的全局脚本改成挂载在被抓取物体上后,出现缩放抖动、值被重置的核心原因是:XR交互工具包的抓取系统会在每一帧同步被抓取物体的变换(包括缩放)到控制器的抓取点,导致你在Update中修改的缩放值被立即覆盖,形成“抖动”效果。另外当前直接累加手部localPosition差值的逻辑也不合理——localPosition是相对于父物体的坐标,手部控制器的父物体是XR Origin,用它计算移动量会导致缩放值异常。
修复方案
修改脚本,只在双手抓取物体时执行缩放逻辑,同时基于手部世界空间间距的比例计算缩放,避免被XR抓取系统的变换重置影响:
using UnityEngine; using UnityEngine.XR.Interaction.Toolkit; public class UpdateScaleObject : MonoBehaviour { public XRBaseInteractor leftHandInteractor; public XRBaseInteractor rightHandInteractor; private Vector3 _initialScale; private float _initialHandDistance; private bool _isScaling = false; void Update() { // 检查是否双手都抓取了当前物体 bool leftGrabsThis = leftHandInteractor.hasSelection && leftHandInteractor.interactableObject.transform == transform; bool rightGrabsThis = rightHandInteractor.hasSelection && rightHandInteractor.interactableObject.transform == transform; if (leftGrabsThis && rightGrabsThis) { if (!_isScaling) { // 初始化缩放基准参数 _initialScale = transform.localScale; _initialHandDistance = Vector3.Distance(leftHandInteractor.transform.position, rightHandInteractor.transform.position); _isScaling = true; } // 计算当前手部间距与初始间距的比例 float currentHandDistance = Vector3.Distance(leftHandInteractor.transform.position, rightHandInteractor.transform.position); float scaleRatio = currentHandDistance / _initialHandDistance; // 应用比例缩放 transform.localScale = _initialScale * scaleRatio; } else { _isScaling = false; } } }
关键改动说明
- 改用XR交互器判断抓取状态:通过
XRBaseInteractor可以精准判断双手是否抓取了当前物体,避免直接引用手部物体带来的位置计算误差 - 基于间距比例计算缩放:用初始缩放值乘以手部间距的比例,保证缩放逻辑的连贯性,不会被XR抓取系统的变换同步操作干扰
- 添加缩放状态开关:只有在双手抓取时才初始化基准参数并执行缩放逻辑,避免无意义的空计算
额外注意事项
- 需给脚本的
leftHandInteractor和rightHandInteractor赋值为场景中的左右手XR交互器(比如XR Direct Interactor) - 如果物体带有碰撞体,缩放后记得同步调整碰撞体大小(例如通过
GetComponent<BoxCollider>().size适配缩放比例)
内容的提问来源于stack exchange,提问作者A J
相关产品推荐
相关产品推荐

