Unity VR开发:如何实现3D模型仅随手部动作沿自身Z轴旋转
问题修复方案
问题根源
你当前的写法不生效有两个核心原因:
Quaternion.FromToRotation生成的是两个世界空间方向向量之间的最短路径旋转,本身就包含X、Y、Z三个轴的旋转分量,直接转欧拉角取Z值的方式不可靠:eulerAngles返回的是世界空间下取值范围在[0,360]的角度,不是物体绕自身Z轴的相对旋转量,加上万向锁的存在,你取到的Z值完全不符合预期。- 旋转相乘的顺序错误,导致最终旋转不是叠加在自身Z轴上。
修复代码
你只需修改Rotate方法即可,修改后代码如下:
void Rotate () { SetOffsets (); // 计算世界空间下手相对于开关的方向 Vector3 handDir = Vector3.Normalize (targetHand.transform.position - powerSwitch.transform.position); // 把起始方向和当前手方向都转换到开关的局部空间,过滤Z轴分量 Vector3 startDirLocal = powerSwitch.transform.InverseTransformDirection(startPos); startDirLocal.z = 0; startDirLocal.Normalize(); Vector3 handDirLocal = powerSwitch.transform.InverseTransformDirection(handDir); handDirLocal.z = 0; handDirLocal.Normalize(); // 计算两个向量在局部XY平面的带符号夹角,就是绕自身Z轴的旋转量 float rotZ = Vector3.SignedAngle(startDirLocal, handDirLocal, Vector3.forward); // 初始旋转叠加Z轴旋转,保证旋转轴为自身Z轴 powerSwitch.transform.rotation = currentRot * Quaternion.Euler(0, 0, rotZ); }
补充说明
- 代码核心逻辑是把所有方向向量投影到开关自身的XY平面,完全过滤了X、Y轴的旋转分量,只保留绕Z轴的旋转
- 用
Vector3.SignedAngle直接计算角度,避免了四元数转欧拉角的取值误差 - 如果你的模型需要绕的旋转轴不是自身Z轴,把
Vector3.forward替换为对应的轴即可(比如绕自身Y轴就用Vector3.up)
内容的提问来源于stack exchange,提问作者Programmer
相关产品推荐
相关产品推荐

