Files
agame/character/player/player_look.gd
T
2026-10-09 15:10:44 +08:00

55 lines
1.9 KiB
GDScript

class_name PlayerLook
extends Node
## 视角组件:把鼠标位移转成 CameraRig 的 yaw 与 Camera 的 pitch。
## 只管转摄像机 —— 不碰速度、不碰动画。
##
## 接法:Player 下挂一个普通 Node,脚本挂上去;由 Player._ready() 调 setup() 注入依赖。
@export_group("视角")
## 鼠标灵敏度(弧度/像素)
@export var mouse_sensitivity: float = 0.0025
## 最低俯角(向下看)
@export var pitch_min_deg: float = -89.0
## 最高仰角(向上看)
@export var pitch_max_deg: float = 89.0
## 眼睛分两层转:CameraRig 绕竖直轴转(yaw),Camera 原地抬头低头(pitch)。
## 分开是为了让 pitch 不掺进移动方向 —— 移动只用 rig 的 basis,低头看地也不会走歪。
var _yaw: float = 0.0
var _pitch: float = 0.0
var _rig: Node3D
var _camera: Camera3D
var _body: Node3D
## 由 Player 在 _ready() 注入依赖。组件不自己 get_node,才能脱离具体场景复用。
func setup(rig: Node3D, camera: Camera3D, body: Node3D) -> void:
_rig = rig
_camera = camera
_body = body
_yaw = rig.rotation.y
_pitch = clampf(camera.rotation.x, deg_to_rad(pitch_min_deg), deg_to_rad(pitch_max_deg))
_apply()
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
_yaw -= event.relative.x * mouse_sensitivity
_pitch = clampf(
_pitch - event.relative.y * mouse_sensitivity,
deg_to_rad(pitch_min_deg),
deg_to_rad(pitch_max_deg)
)
_apply()
## 把 _yaw / _pitch 落到节点上。鼠标一动就调一次(渲染帧),所以视角跟手、不等物理帧。
## 身体跟着一起转 —— 第一人称里「你看哪,身体就朝哪」,别人看你也是这个朝向。
func _apply() -> void:
if _rig == null:
return
_rig.rotation.y = _yaw
_camera.rotation.x = _pitch
_body.rotation.y = _yaw