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
相关产品推荐
相关产品推荐

