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

Unity开发建筑系统时如何实现物体沿Y轴缓慢旋转90度?

原有代码问题
  • 接口用途混淆:Vector3.RotateTowards仅适用于计算方向向量(如物体前向轴)的旋转,直接传入欧拉角(角度计量值)做参数,计算逻辑从根源上错误
  • 逻辑时序错误:RotateBuild是按键触发的单次调用函数,没有维护旋转起始值、目标值、进度状态,无法支撑跨多帧的平滑旋转效果
  • 参数传递错误:Quaternion.LookRotation接收前向方向向量作为入参,传入计算出的欧拉角数值会导致旋转轴错位,出现模型歪扭、旋转角度不对的异常
  • 时间参数误用:单次函数内直接调用Time.fixedDeltaTime无法累计旋转时长,根本无法实现随时间缓慢旋转的过渡效果
正确实现方案

实现逻辑为:按键触发时初始化旋转状态、记录目标旋转值,在逐帧生命周期函数中匀速向目标角度插值,直到旋转完成后重置状态,全程使用四元数接口规避欧拉角万向节锁问题。
首先在类中声明所需状态变量:

// 待旋转的建筑模型对象
public Transform buildModel;
// 旋转速度,单位:度/秒,默认180度/秒即半秒转完90度,可按需调整匹配手感
public float rotateSpeed = 180f;
// 旋转状态标记,避免旋转过程中重复触发按键
private bool isRotating = false;
// 旋转目标四元数
private Quaternion targetRotation;

修改按键触发的RotateBuild函数:

public void RotateBuild()
{
    // 正在旋转过程中直接返回,不响应重复输入
    if (isRotating) return;
    
    isRotating = true;
    // 计算沿Y轴旋转90度后的目标旋转值
    targetRotation = buildModel.rotation * Quaternion.Euler(0, 90f, 0);
}

在Update生命周期函数中处理逐帧旋转逻辑:

private void Update()
{
    if (isRotating)
    {
        // 逐帧向目标角度匀速旋转
        buildModel.rotation = Quaternion.RotateTowards(
            buildModel.rotation,
            targetRotation,
            rotateSpeed * Time.deltaTime
        );

        // 到达目标角度后重置旋转状态
        if (buildModel.rotation == targetRotation)
        {
            isRotating = false;
        }
    }
}
适配说明
  • 如果建筑模型是父物体下的子物体,需要基于本地坐标旋转,把代码中所有的rotation替换为localRotation即可
  • 如果需要旋转带缓动效果(启动/停止时加减速),可以把Quaternion.RotateTowards替换为Quaternion.Slerp,调整插值参数实现对应手感
  • 不要直接对欧拉角做插值/累加计算,四元数接口可以自动规避旋转跳变、轴错乱的问题

内容的提问来源于stack exchange,提问作者Emiel VdV

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:39:26