Unity手部仅绕Y轴旋转物体:解决旋转复位跳转问题
问题根源
你的代码中offsetSet变量仅在第一次执行SetOffsets时被设为true,后续再也不会重置startPos和currentRot。这导致每次重新旋转时,计算的旋转差值都是基于第一次操作时的手部位置和物体旋转,而非上次操作结束后的状态,所以物体旋转会直接跳转到基于初始基准计算出的角度。
解决方案
需要添加一个交互触发机制,在每次开始新的旋转操作时,重新初始化起始基准(当前物体旋转、当前手部相对位置),而非仅初始化一次。以下是修改后的实现:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class RotateObj : MonoBehaviour { private Quaternion currentRot; private Vector3 startPos; public Transform hand; // 标记是否正在进行旋转操作,需根据你的交互逻辑(比如手部碰撞、手势)设置其值 public bool isRotating; void Update () { if (isRotating) { Rotate(); } } // 每次开始旋转时调用此方法重置基准 void ResetRotationOffsets() { startPos = Vector3.Normalize(hand.position - transform.position); currentRot = transform.rotation; } void Rotate () { // 首次进入旋转状态时初始化基准 if (startPos == Vector3.zero) { ResetRotationOffsets(); } Vector3 currentHandDir = Vector3.Normalize(hand.position - transform.position); // 计算手部从起始位置到当前位置的旋转差值 var rotDiff = Quaternion.FromToRotation(startPos, currentHandDir); // 仅提取Y轴旋转并放大倍数 float yRot = rotDiff.eulerAngles.y * 10f; // 基于当前物体旋转叠加差值 transform.rotation = currentRot * Quaternion.Euler(0, yRot, 0); } // 示例:当手部进入物体碰撞体时开始旋转(需给物体添加Collider并勾选IsTrigger) void OnTriggerEnter(Collider other) { if (other.transform == hand) { isRotating = true; // 重置基准 ResetRotationOffsets(); } } // 示例:当手部离开物体碰撞体时结束旋转 void OnTriggerExit(Collider other) { if (other.transform == hand) { isRotating = false; // 清空起始位置,下次旋转时重新初始化 startPos = Vector3.zero; } } }
关键改动说明
- 新增
isRotating变量:用于控制旋转逻辑的启停,你可以根据实际交互方式(比如手势识别、按键)替换示例中的碰撞触发逻辑。 ResetRotationOffsets方法:每次开始旋转时,将currentRot设为物体当前的旋转角度,startPos设为当前手部相对于物体的归一化方向,确保旋转计算基于最新的起始基准。- 旋转逻辑调整:将旋转差值的叠加顺序改为
currentRot * Quaternion.Euler(0, yRot, 0),确保旋转是基于物体当前状态的增量,而非从初始状态重新计算。 - 触发时重置:在开始旋转时主动调用
ResetRotationOffsets,并在结束旋转时清空startPos,保证下次旋转会重新初始化基准。
内容的提问来源于stack exchange,提问作者Yidi
相关产品推荐
相关产品推荐

