Unity左键点击冻结:FPS相机后坐力脚本故障求助
FPS相机后坐力脚本导致Unity冻结的解决方案
问题根源
- 核心问题是
recoilRecover()方法里的无限while循环:Unity主线程每帧执行Update逻辑,while循环会持续占用CPU直到条件不满足,但你在循环里直接给transform.localEulerAngles.y设置固定值,没有逐步向目标角度靠近,导致transform.localEulerAngles.y > recoverToAngle的条件永远成立,主线程被彻底阻塞,最终Unity无响应。 - 额外逻辑错误:后坐力被加到了Y轴(左右方向),不符合FPS游戏后坐力通常为X轴(上下方向)的设计;同时直接覆盖
localEulerAngles会丢失相机原本的垂直旋转角度。
修复后的完整代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class FirstPersonCamera : MonoBehaviour { public Transform player; public float mouseSensitivity = 2f; float cameraVerticalRotation = 0f; public float recoilAmount = 5f; // 后坐力幅度(上下方向) public float recoilRecoverySpeed = 10f; // 每秒恢复速度 float currentRecoilOffset = 0f; // 当前后坐力偏移量 float ammo = 12; bool lockedCursor = true; void Start() { Cursor.visible = false; Cursor.lockState = CursorLockMode.Locked; } void Update() { // 鼠标输入处理 float inputX = Input.GetAxis("Mouse X") * mouseSensitivity; float inputY = Input.GetAxis("Mouse Y") * mouseSensitivity; // 帧同步的后坐力恢复 if (currentRecoilOffset > 0) { currentRecoilOffset = Mathf.Max(0, currentRecoilOffset - recoilRecoverySpeed * Time.deltaTime); } // 相机垂直旋转(叠加后坐力偏移) cameraVerticalRotation -= inputY + currentRecoilOffset; cameraVerticalRotation = Mathf.Clamp(cameraVerticalRotation, -90f, 90f); transform.localEulerAngles = Vector3.right * cameraVerticalRotation; // 玩家水平旋转 player.Rotate(Vector3.up * inputX); // 射击检测(添加弹药判断) if (Input.GetKeyDown(KeyCode.Mouse0) && ammo > 0) { ammo--; AddRecoil(); } // 换弹检测 if (Input.GetKeyDown(KeyCode.R)) { ammo = 12; } } void AddRecoil() { // 叠加后坐力偏移,不直接覆盖旋转角度 currentRecoilOffset += recoilAmount; } }
关键修改说明
- 移除阻塞主线程的
while循环,改用Update中逐帧减少后坐力偏移量,结合Time.deltaTime保证帧率无关的平滑恢复。 - 将后坐力逻辑改为垂直方向的偏移叠加,避免覆盖相机原本的鼠标控制旋转角度。
- 添加弹药数量判断,防止出现负数弹药的无效射击。
- 用
currentRecoilOffset跟踪剩余后坐力量,通过Mathf.Max确保偏移量不会低于0。
内容的提问来源于stack exchange,提问作者the real spy the rapper
相关产品推荐
相关产品推荐

