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

Unity C#:Cinemachine Freelook相机下Player抬头斜移闪烁问题

问题修复:抬头斜向移动时对象闪烁

问题根源

你的代码里有两个核心问题导致闪烁:

  • 直接用camera.eulerAngles.x * movementInput.y计算角色俯仰角,相机的欧拉角x范围是0-360°(比如抬头时可能接近360°而非负角度),乘以输入值会导致旋转值突变。
  • 移动方向moveDir包含了相机的俯仰角,导致斜向移动时方向计算异常,角色的位置和旋转冲突引发闪烁。

修复步骤及代码

1. 分离水平移动与俯仰旋转逻辑

移动方向只基于相机的水平方向(忽略俯仰),角色俯仰旋转单独处理并做平滑,同时限制俯仰范围避免翻转。

2. 修改后的完整代码

// 可调整参数:角色俯仰角度限制范围
public float minPitch = -60f;
public float maxPitch = 60f;
// 俯仰旋转的平滑时间
public float pitchSmoothTime = 0.1f;
private float pitchSmoothVelocity;

// 原移动逻辑修改
direction = new Vector3(movementInput.x, 0f, movementInput.y).normalized;
if(direction.magnitude >= 0.1f)
{
    // 水平转向逻辑(保留原平滑处理)
    float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + camera.eulerAngles.y;
    float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);

    // 俯仰旋转逻辑:处理相机俯仰角的突变问题,平滑并限制范围
    // 将相机x角转换为-180~180°范围,避免0/360跳变
    float cameraPitch = Mathf.DeltaAngle(0, camera.eulerAngles.x);
    // 根据前后输入计算目标俯仰角(movementInput.y为前后输入,可根据需求调整正负)
    float targetPitch = cameraPitch * movementInput.y;
    // 限制俯仰范围,防止角色翻转
    targetPitch = Mathf.Clamp(targetPitch, minPitch, maxPitch);
    // 平滑俯仰旋转
    float currentPitch = Mathf.SmoothDampAngle(transform.eulerAngles.x, targetPitch, ref pitchSmoothVelocity, pitchSmoothTime);

    // 应用角色最终旋转
    transform.rotation = Quaternion.Euler(currentPitch, angle, 0f);

    // 移动方向仅基于水平转向,保持平面移动稳定性
    moveDir = Quaternion.Euler(0, targetAngle, 0f) * Vector3.forward;
    characterController.Move(moveDir.normalized * speed * Time.deltaTime);
}

额外说明

  • Mathf.DeltaAngle用来解决相机抬头时x欧拉角从360°跳变到0°的问题,确保俯仰计算的连续性。
  • 增加俯仰角度限制,避免角色过度抬头/低头出现异常姿态。
  • 移动方向移除俯仰角影响,确保斜向移动时方向始终在水平平面,消除旋转与移动的冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 11:40:10