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

Unity中未移动鼠标时骨骼自行晃动的原因排查

鼠标未移动时骨骼晃动的原因及修复方案

问题重现

你编写的代码用于实现鼠标沿X方向移动时旋转骨骼,但未移动鼠标时骨骼出现晃动现象,代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class shootscript : MonoBehaviour
{
    public Transform bone_2;
    private Vector3 startPos;
    // Start is called before the first frame update
    void Start()
    {
        startPos=bone_2.localEulerAngles;
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 mousePos=Input.mousePosition;
        float dx = mousePos.x - Screen.width / 2;
        float angle = startPos.z+dx*100f*Time.deltaTime;
        bone_2.localEulerAngles=new Vector3(0,0, angle);
    }
}

核心原因

问题出在角度计算的逻辑上:

  • 当前代码是每帧都在初始角度上累加基于鼠标位置的增量,而非直接根据鼠标X位置映射到固定的骨骼旋转角度。
  • 当鼠标未移动时,dx是固定值(比如鼠标在屏幕左侧则为负,右侧为正),每帧执行angle = startPos.z + dx*100f*Time.deltaTime会让angle持续递增或递减,导致骨骼不停旋转,视觉上表现为“晃动”。
  • 此外,Time.deltaTime每帧的微小波动会让旋转速度出现细微变化,进一步加剧晃动的观感。

修复方案

调整逻辑为根据鼠标X位置直接映射到骨骼旋转角度,而非每帧累加增量。以下是修复后的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ShootScript : MonoBehaviour
{
    public Transform bone_2;
    private float startAngleZ;
    // 可自定义的旋转参数
    public float maxRotationAngle = 45f; // 骨骼最大旋转角度
    public float rotationSensitivity = 0.1f; // 旋转灵敏度

    void Start()
    {
        startAngleZ = bone_2.localEulerAngles.z;
    }

    void Update()
    {
        Vector3 mousePos = Input.mousePosition;
        // 计算鼠标X位置相对于屏幕中心的偏移比例(范围:-1 到 1)
        float xOffsetRatio = (mousePos.x - Screen.width / 2) / Screen.width;
        // 根据偏移比例计算目标角度,限制在设定的最大范围内
        float targetAngle = startAngleZ + xOffsetRatio * maxRotationAngle / rotationSensitivity;
        // 直接设置骨骼的Z轴旋转角度
        bone_2.localEulerAngles = new Vector3(0, 0, targetAngle);
    }
}

修复细节说明

  1. 逻辑调整:通过计算鼠标位置的偏移比例,直接映射到固定的目标角度,鼠标不动时目标角度固定,骨骼不再晃动。
  2. 参数化控制:新增maxRotationAngle和rotationSensitivity参数,方便灵活调整骨骼的旋转范围和响应灵敏度。
  3. 命名规范:将类名改为ShootScript,遵循C#大驼峰命名规范,提升代码可读性。

可选优化:平滑旋转

如果想要更自然的平滑旋转效果,可以使用Mathf.Lerp做插值过渡,替换Update中设置角度的代码:

float currentAngle = bone_2.localEulerAngles.z;
// 插值到目标角度,5f为平滑速度,可自行调整
float smoothAngle = Mathf.Lerp(currentAngle, targetAngle, Time.deltaTime * 5f);
bone_2.localEulerAngles = new Vector3(0, 0, smoothAngle);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 08:27:34