You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 03:05:00