From 5360e988fa7c47da8d58ee3a25a7ed92fd700a57 Mon Sep 17 00:00:00 2001 From: Weicao-CatilGrass <1992414357@qq.com> Date: Fri, 22 May 2026 12:40:52 +0800 Subject: 让DeepSeek添加详尽的注释 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Scripts/CameraHandler.cs | 146 +++++++++++++++++++++++++++++----------- 1 file changed, 105 insertions(+), 41 deletions(-) (limited to 'Assets/Scripts/CameraHandler.cs') diff --git a/Assets/Scripts/CameraHandler.cs b/Assets/Scripts/CameraHandler.cs index b0b8a70..e170503 100644 --- a/Assets/Scripts/CameraHandler.cs +++ b/Assets/Scripts/CameraHandler.cs @@ -8,113 +8,177 @@ namespace DS { public class CameraHandler : MonoBehaviour { - public Transform cameraTransform; - public Transform targetTransform; - public Transform cameraPivotTransform; - private Transform _myTransform; - private Vector3 _cameraTransformPosition; - private LayerMask _ignoreLayers; - private Vector3 cameraFollowVelocity = Vector3.zero; - - private bool _cursorLocked = false; - - public static CameraHandler singleton; - public float lookSpeed = 0.1f; - public float followSpeed = 0.1f; - public float pivotSpeed = 0.03f; - - private float _targetPosition; - private float _defaultPosition; - private float _lookAngle; - private float _pivotAngle; - public float minimumPivot = -35; - public float maximumPivot = 35; - - public float cameraSphereRadius = 0.2f; - public float cameraCollisionOffSet = 0.2f; - public float minimumCollisionOffSet = 0.2f; - + // ========== 公开引用 ========== + [Header("Camera Transforms")] + public Transform cameraTransform; // 摄像机 Transform(子物体) + public Transform targetTransform; // 跟踪目标(如玩家角色) + public Transform cameraPivotTransform; // 摄像机枢轴 Transform(用于俯仰旋转) + + // ========== 私有引用与状态 ========== + private Transform _myTransform; // 当前对象的 Transform 缓存 + private Vector3 _cameraTransformPosition; // 用于 Lerp 的摄像机局部位置 + private LayerMask _ignoreLayers; // 忽略的碰撞层(玩家、UI 等) + private Vector3 cameraFollowVelocity = Vector3.zero; // SmoothDamp 速度参考值 + + private bool _cursorLocked = false; // 鼠标是否锁定 + + // ========== 单例 ========== + public static CameraHandler singleton; // 全局访问实例 + + // ========== 速度参数(可调) ========== + [Header("Movement Speeds")] + public float lookSpeed = 0.1f; // 水平旋转速度 + public float followSpeed = 0.1f; // 跟随目标的速度 + public float pivotSpeed = 0.03f; // 俯仰旋转速度 + + // ========== 内部状态 ========== + private float _targetPosition; // 摄像机与枢轴的目标距离 + private float _defaultPosition; // 摄像机的默认 Z 轴局部位置(距离) + private float _lookAngle; // 水平旋转角度(Y 轴) + private float _pivotAngle; // 俯仰旋转角度(X 轴) + + [Header("Pivot Clamps")] + public float minimumPivot = -35; // 俯仰最小角度 + public float maximumPivot = 35; // 俯仰最大角度 + + // ========== 碰撞检测参数 ========== + [Header("Collision Settings")] + public float cameraSphereRadius = 0.2f; // 球体投射的半径 + public float cameraCollisionOffSet = 0.2f; // 碰撞后摄像机偏移量 + public float minimumCollisionOffSet = 0.2f; // 最小偏移量,防止穿透 + + // ==================================================================== + // Awake:初始化引用与默认值 + // ==================================================================== private void Awake() { - singleton = this; - _myTransform = transform; - _defaultPosition = cameraTransform.localPosition.z; + singleton = this; // 设置单例 + _myTransform = transform; // 缓存自身 Transform + _defaultPosition = cameraTransform.localPosition.z; // 记录默认 Z 距离 + // 忽略层级:8(玩家)、9、10;使用位取反运算 _ignoreLayers = ~(1 << 8 | 1 << 9 | 1 << 10); } + // ==================================================================== + // Update:每帧检测鼠标锁定状态 + // ==================================================================== private void Update() { UpdateCursorLock(); } + // ==================================================================== + // UpdateCursorLock:管理鼠标锁定与可见性 + // ==================================================================== private void UpdateCursorLock() { + // 左键点击 -> 锁定鼠标(游戏控制模式) if (Input.GetMouseButtonDown(0)) { - Cursor.lockState = CursorLockMode.Locked; - Cursor.visible = false; + Cursor.lockState = CursorLockMode.Locked; // 锁定鼠标到窗口中心 + Cursor.visible = false; // 隐藏鼠标 _cursorLocked = true; } + // 按下 Escape -> 解锁鼠标(UI / 菜单模式) if (Input.GetKeyDown(KeyCode.Escape)) { - Cursor.lockState = CursorLockMode.None; - Cursor.visible = true; + Cursor.lockState = CursorLockMode.None; // 释放鼠标 + Cursor.visible = true; // 显示鼠标 _cursorLocked = false; } } + // ==================================================================== + // FollowTarget:平滑跟随目标,并处理摄像机碰撞 + // ==================================================================== public void FollowTarget(float delta) { - Vector3 targetPosition = Vector3.SmoothDamp(_myTransform.position, targetTransform.position, - ref cameraFollowVelocity, delta / followSpeed); + // 使用 SmoothDamp 平滑移动到目标位置 + Vector3 targetPosition = Vector3.SmoothDamp( + _myTransform.position, + targetTransform.position, + ref cameraFollowVelocity, + delta / followSpeed); + _myTransform.position = targetPosition; - + + // 处理摄像机与场景物体的碰撞 HandleCameraCollisions(delta); } + // ==================================================================== + // HandleCameraRotation:处理鼠标输入的摄像机旋转 + // ==================================================================== public void HandleCameraRotation(float delta, float mouseInputX, float mouseInputY) { + // 鼠标未锁定时不处理旋转 if (!_cursorLocked) return; - + + // 累加水平旋转角度(左右) _lookAngle += (mouseInputX * lookSpeed) / delta; + // 累加俯仰旋转角度(上下,取反使鼠标向上移动时视角向上) _pivotAngle -= (mouseInputY * pivotSpeed) / delta; + // 限制俯仰角度范围,防止视角翻转 _pivotAngle = Mathf.Clamp(_pivotAngle, minimumPivot, maximumPivot); + // 应用水平旋转到当前对象(Y 轴旋转) Vector3 rotation = Vector3.zero; rotation.y = _lookAngle; Quaternion targetRotation = Quaternion.Euler(rotation); _myTransform.rotation = targetRotation; + // 应用俯仰旋转到枢轴对象(X 轴旋转,局部坐标) rotation = Vector3.zero; rotation.x = _pivotAngle; - targetRotation = Quaternion.Euler(rotation); cameraPivotTransform.localRotation = targetRotation; } + // ==================================================================== + // HandleCameraCollisions:检测并避免摄像机与场景物体穿插 + // ==================================================================== public void HandleCameraCollisions(float delta) { + // 目标距离默认设为默认距离 _targetPosition = _defaultPosition; + RaycastHit hit; + + // 计算从枢轴指向摄像机的方向向量 Vector3 direction = cameraTransform.position - cameraPivotTransform.position; direction.Normalize(); - if (Physics.SphereCast(cameraPivotTransform.position,cameraSphereRadius,direction,out hit,Mathf.Abs(_targetPosition))) + // 从枢轴位置沿 direction 方向进行 SphereCast 检测 + // 检测距离为 _targetPosition 的绝对值 + if (Physics.SphereCast( + cameraPivotTransform.position, + cameraSphereRadius, + direction, + out hit, + Mathf.Abs(_targetPosition))) { + // 计算枢轴到碰撞点的实际距离 float dis = Vector3.Distance(cameraPivotTransform.position, hit.point); + // 摄像机应位于碰撞点前方 cameraCollisionOffSet 处 _targetPosition = -(dis - cameraCollisionOffSet); } + // 如果计算出的目标距离绝对值太小,强制使用最小值防止视觉异常 if (Mathf.Abs(_targetPosition) < minimumCollisionOffSet) { _targetPosition = -minimumCollisionOffSet; } - _cameraTransformPosition.z = Mathf.Lerp(cameraTransform.localPosition.z, _targetPosition, delta / 0.2f); + // 使用 Lerp 平滑调整摄像机的局部 Z 轴位置 + _cameraTransformPosition.z = Mathf.Lerp( + cameraTransform.localPosition.z, + _targetPosition, + delta / 0.2f); + + // 应用位置 cameraTransform.localPosition = _cameraTransformPosition; } } } - -- cgit