Files
agame/.workbuddy/memory/2026-10-09.md
T
2026-10-09 15:17:05 +08:00

4.0 KiB
Raw Blame History

2026-10-09

简易准心(Crosshair)

  • 新增 ui/crosshair.gd:@tool extends Control,用 _draw() 画十字(gap/length/thickness/dot 可导出调参),mouse_filter = IGNORE,监听 NOTIFICATION_RESIZED 重绘。
  • 挂载约定:CanvasLayer > Crosshair(Control),Control 锚点为 Full Rect,中心即屏幕中心;推荐挂在 CameraRig 之下 —— 因为 player.gd _ready() 对非 authority 会 camera_rig.queue_free(),远端玩家准心随之一并释放,无需额外代码。
  • 项目 stretch 模式为 canvas_items + expand,CanvasLayer 会自动跟随缩放。

后续改动:只保留「点」

  • 最终形态:准心 = 屏幕中心一个点,无十字、无样式开关(enum Style 已移除)。
  • 导出参数:dot_color / dot_radius(默认 2.5) / outline / outline_color / outline_width。
  • _draw() 先画描边圆再画主体圆,保证浅背景可见。

player.gd 拆解方案(待执行)

  • 现状:character/player/player.gd 155 行,混了视角 / 移动跳跃 / 拾取 / 多人权限四类职责。
  • 方案:子节点组件化(与既有 PlayerAnimator 同模式)。根节点降为协调器(~40 行),新增 Look / Motor / Pickup 三个 Node 子节点,各自挂 player_look.gd / player_motor.gd / player_pickup.gd。
  • 三条硬约束:① move_and_slide() 留在根节点,Motor 只写 body.velocity;② 物理顺序由根节点显式编排(motor.step → move_and_slide → animator → pickup),不让子节点各写 _physics_process;③ 非 authority 时三个组件的输入/物理必须一并关闭。
  • 范式定位:组合优于继承 + 组件模式(Component Pattern);协调器部分带 Facade/Mediator 色彩;setup() 注入属手工依赖注入。不是 ECS(Godot 节点是「带行为的对象」,非纯数据组件)。
  • 状态:已落地(2026-10-09)。新增 player_look.gd / player_motor.gd / player_pickup.gd(均带 class_name:PlayerLook / PlayerMotor / PlayerPickup);player.gd 重写为协调器(~65 行);player.tscn 追加 Look / Motor / Pickup 三个 Node 子节点(挂 FaceRig 之后,ext_resource id 13_look / 14_motor / 15_pickup,未写 uid 由 Godot 补)。
  • 场景格式注意:本项目的 .tscn 节点带非标准 unique_id=(Godot 4.7 特性),unique_id 与 load_steps 均可省略;paint_panel.tscn 就完全没写,可作参照。
  • 已确认无外部脚本引用被搬走的属性(仅 world/main.tscn 通过场景 uid 引用玩家场景)。
  • 顺手去掉了原 _pickObject 里的两行 print() 调试输出。

拾取改为长按拖拽

  • player_pickup.gd:由「按一下切换」改为「按下抓起、松开放下」——is_action_pressed("carry") → _grab(),is_action_released("carry") → _drop()。
  • carry 动作确认绑定鼠标左键(button_index: 1);项目里另有未被任何脚本使用的 throw_carry(绑 Q 键),可作投掷功能的预留。
  • 加了 Input.mouse_mode != MOUSE_MODE_CAPTURED 早退,并在 player.gd 重新锁定鼠标那一支补 get_viewport().set_input_as_handled(),避免「点一下重新锁定鼠标」顺带抓起物体(两种分支执行顺序下都成立)。
  • physics_step() 与 has_object() 改用 is_instance_valid() —— 防止拖拽途中物体被 destroy 时取属性报错。
  • _drop() 保留线速度(松手有惯性 / 可甩出);想要「就地放下」需补 set_linear_velocity(Vector3.ZERO)。

按 Q 投掷

  • player_pickup.gd 接入 throw_carry(Q 键)→ _throw():取 -_hold_pos.global_transform.basis.z 作投掷方向(持握点挂在摄像机下且仅有平移,其 basis 即视线朝向,故无需再注入摄像机),set_linear_velocity(dir * throw_speed) 后置 _current = null。
  • 新增导出参数 throw_speed: float = 12.0。
  • 备选手感(注释里留了行):改用 apply_central_impulse 则重物飞得慢。