From 698cb02c21c5b27ffc4b295b990f2247052b9ba7 Mon Sep 17 00:00:00 2001 From: yvmou_ Date: Fri, 2 Oct 2026 12:06:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=80=E5=A7=8B=E8=8F=9C=E5=8D=95=E3=80=81?= =?UTF-8?q?=E7=8E=A9=E5=AE=B6=E9=80=89=E6=8B=A9=E3=80=81=E8=84=B8=E9=83=A8?= =?UTF-8?q?=E7=BB=98=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .workbuddy-ai/memory/2026-10-02.md | 74 +++++++ .workbuddy-ai/memory/MEMORY.md | 39 +++- autoload/net.gd | 41 +++- character/player/face/face_paint.gdshader | 29 +++ character/player/face/face_paint.gdshader.uid | 1 + character/player/face/face_painter.gd | 190 ++++++++++++++++++ character/player/face/face_painter.gd.uid | 1 + character/player/face/face_rig.gd | 162 +++++++++++++++ character/player/face/face_rig.gd.uid | 1 + .../player/face/presets/face_00_blank.png | Bin 0 -> 1495 bytes .../face/presets/face_00_blank.png.import | 40 ++++ .../player/face/presets/face_01.png.import | 40 ++++ character/player/face/presets/face_02.png | Bin 0 -> 121633 bytes .../player/face/presets/face_02.png.import | 40 ++++ character/player/player.tscn | 7 + project.godot | 2 +- tests/test_face.gd | 132 ++++++++++++ tests/test_face.gd.uid | 1 + tests/test_net_replication.gd | 15 ++ ui/character_select.gd | 92 +++++++++ ui/character_select.gd.uid | 1 + ui/character_select.tscn | 187 +++++++++++++++++ ui/main_menu.gd | 66 ++++-- ui/paint_panel.gd | 130 ++++++++++++ ui/paint_panel.gd.uid | 1 + ui/paint_panel.tscn | 148 ++++++++++++++ 26 files changed, 1419 insertions(+), 21 deletions(-) create mode 100644 character/player/face/face_paint.gdshader create mode 100644 character/player/face/face_paint.gdshader.uid create mode 100644 character/player/face/face_painter.gd create mode 100644 character/player/face/face_painter.gd.uid create mode 100644 character/player/face/face_rig.gd create mode 100644 character/player/face/face_rig.gd.uid create mode 100644 character/player/face/presets/face_00_blank.png create mode 100644 character/player/face/presets/face_00_blank.png.import create mode 100644 character/player/face/presets/face_01.png.import create mode 100644 character/player/face/presets/face_02.png create mode 100644 character/player/face/presets/face_02.png.import create mode 100644 tests/test_face.gd create mode 100644 tests/test_face.gd.uid create mode 100644 ui/character_select.gd create mode 100644 ui/character_select.gd.uid create mode 100644 ui/character_select.tscn create mode 100644 ui/paint_panel.gd create mode 100644 ui/paint_panel.gd.uid create mode 100644 ui/paint_panel.tscn diff --git a/.workbuddy-ai/memory/2026-10-02.md b/.workbuddy-ai/memory/2026-10-02.md index ff52d70..2694bf8 100644 --- a/.workbuddy-ai/memory/2026-10-02.md +++ b/.workbuddy-ai/memory/2026-10-02.md @@ -121,3 +121,77 @@ SubViewportContainer`,输入天然可达** —— 不是把 SubViewport 当后 **发现**:`Net` autoload 的「联机测试」面板默认可见且在同位置,会把菜单中间的按钮盖住 —— 接线时必须先处理它(隐藏,或让菜单的「联机」按钮接管)。这条已记进 MEMORY.md。 +## 实现:角色选择 + 脸部预设选择 + 脸部绘制 + +按之前的方案落地了。`test_run` **26/26 通过**(含新增的 face suite 5 条),实机跑通并截图确认。 + +**新增** +- `character/player/face/face_paint.gdshader` — 孤岛 UV 重映射 + `mix(base, paint, paint.a)` +- `character/player/face/face_painter.gd` — 笔画层,直接改 RGBA8 字节缓冲 +- `character/player/face/face_rig.gd` — 挂 surface 1 的材质、切预设、存读档(`user://face_*.json/png`) +- `character/player/face/presets/face_01.png` `face_02.png` — 从 `mouse_表情测试.png` 裁的 512² 方形预设 +- `ui/paint_panel.tscn/.gd` — 绘画面板(颜色 / 粗细 / 橡皮 / 清空 / 取消 / 完成) +- `ui/character_select.tscn/.gd` — 3D 预览(自转)+ 预设缩略图 + 自己画 +- `tests/test_face.gd` — 钉住「surface 1 叫 face、UV 孤岛落在 shader 的框里、预设是正方形」 + +**改动**:`player.tscn` 加 `FaceRig` 节点;`main_menu.gd`「开始游戏」→ 角色选择,并把 Net 调试面板收起来。 + +**踩到的坑(都补进 MEMORY.md 了)** +1. Godot 4 的 canvas **没有擦除混合模式**,`draw_set_blend_mode` 也没了 → 橡皮改成自己乘 alpha。 +2. `Image.set_data()` 在 4.7 变成 5 个参数 → 改用 `Image.create_from_data`。 +3. 导出的**节点引用**在场景实例化时解析成 null → 改成 `mesh_path: NodePath` + `_ready()` 里 `get_node_or_null`。 +4. shader 里 `vec2` 不能用 `source_color`(只给 vec3/vec4/sampler)。 +5. 画布一开始只显示笔画层,等于让玩家对着空气画 → 底下垫一层预设 TextureRect。 +6. 拖拽判定原本看 motion 的 `button_mask`,MCP 注入的 motion 不带这个字段 → 改成自己记 `_drawing`。 +7. 排查时一度以为画笔没生效,其实黑点画在脸的黑色线条上被淹没了 —— 换到纯蓝区域才看见。 + 诊断顺序记一下:先 `print` 确认输入到了(`[PP]`)→ 再确认印章落了(`[FP] stamp`)→ 再看缓冲字节(`probe a=255`)。 + +## 收尾:入口换成开始菜单 + 联机脸同步 + +`test_run` **28/28 通过**。两件事都用实机验证过(入口流程用 MCP 点按钮走通;脸同步用**两个 +headless 实例** `--host` / `--join 127.0.0.1` 真连了一次)。 + +**入口场景** +- `project.godot` 的 `run/main_scene` 改成 `res://ui/main_menu.tscn`(用 `project_manage(set_main_scene)` 改的)。 +- `net.gd`:加 `WORLD_SCENE` / `MENU_SCENE`、`_enter_world()`、`_go_to()`、`set_menu_visible()`; + `host_game()` 和 `_on_connected_to_server()` 之后切进世界;`leave_game()` 切回菜单并把 `_spawner` 置空。 +- **关键**:世界是开局后才加载的,`bind_spawner()` 必须补生成已经连上的玩家,否则主机在菜单里 + 开好服、进世界时没有角色。 +- `main_menu.gd`:「确定」→ `Net.host_game()`;用 `Net.set_menu_visible()` 代替原来的节点路径 hack。 +- 新增测试 `test_main_scene_is_the_menu`(防有人把入口改回世界)。 + +**脸同步** +- `FaceRig` 加三个方法:`_pull_remote_face` / `_rpc_request_face` / `_rpc_send_face`。 + **用「谁缺谁来要」而不是出生时推** —— 各端玩家节点出现的先后顺序不保证,推的话很可能推给一个 + 还不存在的节点。非本机玩家在 `_ready` 里主动去要,带重试。 +- `FacePainter` 加 `to_png_bytes()` / `set_image()`,走内存不落盘。 +- **踩到的坑**:第一次跑双实例,客户端刷了一屏 + `Node not found: "Main//FaceRig"` / `Failed to get path from RPC` —— + 主机生成玩家比客户端早几帧,主机立刻去要时客户端还没建出那个节点。 + 加 `FACE_SYNC_INITIAL_DELAY = 1.0`(首次要之前先等一秒)后两边都干净了。 +- 验证结果:HOST 和 JOIN 都打出「收到 peer X 的脸,png=1930 字节」,且无任何报错。 + 1930 正好是 `user://face_paint.png` 的大小,说明笔画真的传过去了。 +- 新增测试 `test_face_sync_methods_exist`(钉住三个方法名)。 + +**找到 Godot 可执行文件**:`D:\_yvmou\Godot\Godot_v4.7.2-stable_win64.exe\Godot_v4.7.2-stable_win64_console.exe` +(注意那一串带 .exe 的其实是个**目录**)。双开调试命令: +` --headless --path E:/Godot/agame -- --host` / `-- --join 127.0.0.1`。 + +## 修 bug:点「自己画」不是空白画布 + +用户报的。根因是**语义理解错了**:我原先把「自己画」做成「在选中的预设上补几笔」, +用户要的是**从空白脸起手**。 + +- 生成 `presets/face_00_blank.png`(512² 纯色 `#89B3FF`,取自预设贴图里脸的底色)。 +- `character_select.gd`:「自己画」= 清掉缩略图高亮 + `_paint_panel.open(_rig, BLANK_FACE)`。 +- `paint_panel.gd`:`open()` 多一个 `blank_face` 参数,**先拍快照再换底图 + 清笔画**。 +- **顺带修了一个连带 bug**:`_on_cancel` 原来只还原笔画,而「自己画」会把底图换成空白 —— + 点取消会留下一张白脸。现在底图(`_preset_before`)也一起还原。 +- 移掉了 `_on_paint_done`(高亮在 `_on_draw` 里已经清了,那个回调成了死代码)。 + +验证:实机走了一遍「选预设 → 自己画(画布变纯色、预览里脸也变纯)→ 取消(底图还原回 face_01)」, +并用 `get_node_info` 确认两个缩略图 modulate 都回到 0.62。`test_run` 28/28。 + +**一个排查小教训**:截图里 Preset0 看着比 Preset1 亮,我一度以为高亮没清掉 —— +其实两张贴图本身明暗就不同,`modulate` 才是真相。**别靠截图判断颜色,去读属性。** + diff --git a/.workbuddy-ai/memory/MEMORY.md b/.workbuddy-ai/memory/MEMORY.md index bdd642f..4cd5ebb 100644 --- a/.workbuddy-ai/memory/MEMORY.md +++ b/.workbuddy-ai/memory/MEMORY.md @@ -11,8 +11,15 @@ - 界面放 `res://ui/`。项目没有 Theme 资源,风格一律用节点上的 `theme_override_*` 内联写; 给容器(如 VBoxContainer)设 `theme_override_styles/*` 会**向下继承**给子按钮,不用逐个设。 - 中文字体不用额外配:Godot 默认主题会回退到系统字体,实测中文正常渲染。 -- **`Net` 是 autoload,它的「联机测试」面板在 `_ready()` 里就 `visible = true`(CanvasLayer layer=20)**, - 会盖在任何场景正中间。做开始菜单时要么让菜单的「联机」按钮接管它,要么在菜单期间把它藏起来。 +- **入口场景是 `res://ui/main_menu.tscn`**(不再是世界)。流程:开始菜单 →「开始游戏」→ 角色选择 → + 「确定」= `Net.host_game()` → Net 切到 `world/main.tscn`;「联机」= 放出 Net 的创建/加入面板, + 选完同样由 Net 切进世界。**进世界 / 回菜单这两件事都归 Net 管**(`_enter_world` / `leave_game`), + 菜单只管「按了哪个按钮」。 +- **世界是开局之后才加载的**,所以 `MultiplayerSpawner` 的绑定时机跟着变了: + `Net.bind_spawner()` 里要把已经连上的玩家补生成一遍,否则主机在菜单里就开好服、 + 切进世界时一个角色都不会出现。 +- `Net` 是 autoload,它的「联机测试」面板在 `_ready()` 里就 `visible = true`(CanvasLayer layer=20), + 会盖在菜单正中间 —— 菜单调 `Net.set_menu_visible(false)` 收起来。 ## 动画(AnimationPlayer) @@ -40,6 +47,34 @@ - 面部孤岛只占 1024² 的 21%×20%,实际脸分辨率约 219×205 —— 要用 shader 把孤岛重映射到 0~1 再用方形小贴图,有效分辨率能翻一倍多。 +## 面部系统(character/player/face/ + ui/) + +- `face_paint.gdshader`:把孤岛 UV 重映射到 0~1,`ALBEDO = mix(base_tex, paint_tex, paint.a)`。 + **两层必须分开**:`base_tex` = 预设脸(切换就换它),`paint_tex` = 玩家笔画层。 + 这样橡皮擦掉笔画露出来的是预设脸,而且换预设不会丢手绘。 +- `FaceRig`(挂在 Player 下):建一张 512² 的笔画 Image + ImageTexture,`set_surface_override_material(1, mat)`。 + 存 `user://face_preset.json`(选了哪张预设)+ `user://face_paint.png`(透明底笔画层), + 玩家出生时 `apply_saved()` 读回来。预览和玩家是**两套 FaceRig、共用一份存档**。 +- `FacePainter`:**不用 `Control._draw()`,直接改 RGBA8 字节缓冲**。画 = source-over alpha 混合, + 擦 = 把目标 alpha 乘掉;一笔画完 `_sync()` 一次(512² 一次 1MB,别每盖一个印章就同步)。 +- 界面链路:`ui/main_menu.tscn` →「开始游戏」→ `ui/character_select.tscn`(3D 预览 + 预设缩略图 + 自己画) + → `ui/paint_panel.tscn`。**画布要「预设 TextureRect + 笔画 TextureRect」叠着显示** —— + 笔画层是透明底的,只显示它等于让玩家对着空气画。 +- **「自己画」= 从空白脸起手**(`presets/face_00_blank.png`,纯色底),不是在预设上补笔。 + 空白由面板来落(`open(rig, blank_face)`)—— 它必须**先拍快照再改**,否则点「取消」还原回来的 + 是已经清空的状态。取消要同时还原**底图和笔画**,只还原笔画会留下一张白脸。 + +## Godot 4 踩坑 + +- **canvas 没有「擦除」混合模式**:`CanvasItemMaterial.BlendMode` 只有 mix/add/sub/mul/premult, + `CanvasItem.draw_set_blend_mode()` 在 4.x 已移除。橡皮只能自己管像素。 +- `Image.set_data()` 在 4.7 签名变了(要 5 个参数);改用 + `Image.create_from_data(w, h, mipmaps, format, data)`。 +- **导出的节点引用解析不到**:`@export var mesh: MeshInstance3D` 在 .tscn 里存成 `NodePath`, + 实测场景实例化时拿到的是 null。改成 `@export var mesh_path: NodePath` + `_ready()` 里 `get_node_or_null`。 +- shader 里 `source_color` 只能用在 vec3 / vec4 / sampler 上,`vec2` 用了会编译失败。 +- 给容器(VBoxContainer 等)设 `theme_override_styles/*` 会**向下继承**给子按钮,不用逐个设。 + ## Godot MCP 踩坑 - **数值标量经 MCP 会被字符串化**:`node_set_property` 传 `0.15` 能写进去,但回显是 `"0.15"`; diff --git a/autoload/net.gd b/autoload/net.gd index e19d51e..8a1a7e5 100644 --- a/autoload/net.gd +++ b/autoload/net.gd @@ -18,6 +18,9 @@ const MAX_PLAYERS: int = 8 const DEFAULT_ADDRESS: String = "127.0.0.1" ## 所有玩家节点都会加入这个组,方便整批清场 const PLAYER_GROUP: String = "net_player" +## 开局后要进的世界场景,以及断开后要回的入口场景 +const WORLD_SCENE: String = "res://world/main.tscn" +const MENU_SCENE: String = "res://ui/main_menu.tscn" var _spawner: MultiplayerSpawner = null @@ -41,8 +44,20 @@ func _ready() -> void: # ---------------- 对外接口 ---------------- ## 世界根节点在 _ready 里调用,把 MultiplayerSpawner 托管给 Net。 +## +## 世界是「开局之后」才加载的(入口是开始菜单),所以这里得把已经连上的玩家补生成一遍 —— +## 否则主机在菜单里就开好了,切进世界时一个角色都不会出现。 func bind_spawner(spawner: MultiplayerSpawner) -> void: _spawner = spawner + if multiplayer.is_server(): + call_deferred("_spawn_player", 1) + for id in multiplayer.get_peers(): + call_deferred("_spawn_player", id) + + +## 菜单那边用它开关「联机」面板 —— 面板默认是显示的,会盖住入口菜单。 +func set_menu_visible(on: bool) -> void: + _menu.visible = on ## 创建主机。ENet 是客户端-服务器模型,主机同时是服务器与玩家。 @@ -55,8 +70,8 @@ func host_game() -> void: multiplayer.multiplayer_peer = peer _show_game_ui() print("[Net] 主机已启动,端口 %d" % PORT) - # 服务器自己也要一个角色。延后一帧,等各端场景就绪。 - call_deferred("_spawn_player", 1) + # 入口是开始菜单,世界这时还没加载 —— 切过去,角色由 bind_spawner 补生成 + call_deferred("_enter_world") ## 加入主机。address 为主机在局域网内的内网 IP。 @@ -74,13 +89,28 @@ func join_game(address: String = DEFAULT_ADDRESS) -> void: print("[Net] 正在连接 %s:%d" % [target, PORT]) -## 断开并清场,回到主菜单。 +## 断开并清场,回入口菜单。 func leave_game() -> void: multiplayer.multiplayer_peer = null _clear_players() + # 世界一卸载 spawner 就跟着没了,留着引用会指向已释放的节点 + _spawner = null Input.mouse_mode = Input.MOUSE_MODE_VISIBLE _show_menu_ui() _set_status("已断开") + call_deferred("_go_to", MENU_SCENE) + + +## 切到世界场景。已经在里面就不重复切 +func _enter_world() -> void: + _go_to(WORLD_SCENE) + + +func _go_to(path: String) -> void: + var current := get_tree().current_scene + if current != null and current.scene_file_path == path: + return + get_tree().change_scene_to_file(path) # ---------------- 网络事件 ---------------- @@ -99,6 +129,7 @@ func _on_peer_disconnected(id: int) -> void: func _on_connected_to_server() -> void: _show_game_ui() print("[Net] 已连接,等待主机生成角色") + call_deferred("_enter_world") func _on_connection_failed() -> void: @@ -117,7 +148,7 @@ func _on_server_disconnected() -> void: # ---------------- 玩家生成与回收 ---------------- func _spawn_player(peer_id: int) -> void: - if _spawner == null or not multiplayer.is_server(): + if not is_instance_valid(_spawner) or not multiplayer.is_server(): return var parent := _spawner.get_node_or_null(_spawner.spawn_path) if parent == null or parent.has_node(str(peer_id)): @@ -126,7 +157,7 @@ func _spawn_player(peer_id: int) -> void: func _despawn_player(peer_id: int) -> void: - if _spawner == null: + if not is_instance_valid(_spawner): return var parent := _spawner.get_node_or_null(_spawner.spawn_path) if parent == null: diff --git a/character/player/face/face_paint.gdshader b/character/player/face/face_paint.gdshader new file mode 100644 index 0000000..a1d158a --- /dev/null +++ b/character/player/face/face_paint.gdshader @@ -0,0 +1,29 @@ +shader_type spatial; +// 面部 = 两层贴图的合成:底图(预设脸)+ 笔画层(玩家自绘),后者带 alpha 盖在前面。 +// 两层都用「面部孤岛重映射后的 UV」采样,所以一张方形小图就能正好铺满整张脸。 +// +// 为什么不是直接把贴图换掉:画布只装笔画、不装底图,橡皮擦掉笔画后露出来的是预设脸, +// 而不是把脸擦成黑洞。这也是它能一边切预设一边保留手绘笔画的原因。 + +// 面部 UV 孤岛(实测自 mouse.glb 的 body_mesh surface 1 "face"): +// u 0.142~0.356,v 0.038~0.238。v 往下外扩到 0.031 是为了取成正方形,避免拉伸。 +uniform vec2 face_uv_min = vec2(0.142, 0.031); +uniform float face_uv_size : hint_range(0.01, 1.0) = 0.214; + +// 预设脸。没接上时给张白图,至少不会一片黑 +uniform sampler2D base_tex : source_color, filter_linear, repeat_disable, + hint_default_white; +// 玩家笔画层(一个透明底的 SubViewport)。没接上时给张全透明图,等于没画 +uniform sampler2D paint_tex : source_color, filter_linear, repeat_disable, + hint_default_transparent; + +void fragment() { + vec2 uv = (UV - face_uv_min) / face_uv_size; + vec4 base = texture(base_tex, uv); + vec4 paint = texture(paint_tex, uv); + + ALBEDO = mix(base.rgb, paint.rgb, paint.a); + // 顶掉 GLB 里 lambert1 那套手感,不然脸会比身体亮一块 + ROUGHNESS = 1.0; + METALLIC = 0.0; +} diff --git a/character/player/face/face_paint.gdshader.uid b/character/player/face/face_paint.gdshader.uid new file mode 100644 index 0000000..e782fcc --- /dev/null +++ b/character/player/face/face_paint.gdshader.uid @@ -0,0 +1 @@ +uid://boka801kewxls diff --git a/character/player/face/face_painter.gd b/character/player/face/face_painter.gd new file mode 100644 index 0000000..7100fbd --- /dev/null +++ b/character/player/face/face_painter.gd @@ -0,0 +1,190 @@ +class_name FacePainter +extends Node +## 面部画笔:直接往一张 Image 的字节缓冲上盖笔刷印章。 +## +## 为什么不用 Control._draw():Godot 4 的 canvas 已经没有「擦除」混合模式了 +## (CanvasItemMaterial 只有 mix / add / sub / mul / premult,也没有 draw_set_blend_mode), +## 橡皮没法靠 blend_mode 实现。自己管像素反而更直接: +## 画 = 标准的 source-over alpha 混合;擦 = 把目标的 alpha 乘掉;存档 = 就是存这张图。 + +var image: Image +var texture: ImageTexture +var canvas_size: int = 512 + +## 当前笔刷。绘画面板改这几个值,下一笔生效。 +var brush_color: Color = Color.BLACK +var brush_width: float = 12.0 +var erasing: bool = false + +## 像素缓冲(RGBA8)。所有绘制都改它,一笔画完再一次性推给显卡。 +var _buf: PackedByteArray +## 圆形笔刷的覆盖度,边长 _stamp_d +var _cov: PackedFloat32Array +var _stamp_d: int = 0 +var _stamp_rgb: Vector3 = Vector3.ZERO +var _last_stamp: Vector2 = Vector2.INF + + +func _init(size: int = 512) -> void: + canvas_size = size + + +func _ready() -> void: + _buf = PackedByteArray() + _buf.resize(canvas_size * canvas_size * 4) + _sync() + + +# ---------------- 画笔接口 ---------------- + +func begin_stroke(pos: Vector2) -> void: + _rebuild_stamp() + _last_stamp = Vector2.INF + _stamp_at(pos) + _last_stamp = pos + _sync() + + +func extend_stroke(pos: Vector2) -> void: + if not _last_stamp.is_finite(): + _stamp_at(pos) + _last_stamp = pos + _sync() + return + var spacing := maxf(1.0, brush_width * 0.25) + var dist := _last_stamp.distance_to(pos) + if dist < spacing: + return + # 鼠标动得快时两点之间得补章,否则线是一串断点 + var steps := int(ceil(dist / spacing)) + for i in range(1, steps + 1): + _stamp_at(_last_stamp.lerp(pos, float(i) / float(steps))) + _last_stamp = pos + _sync() + + +func end_stroke() -> void: + _last_stamp = Vector2.INF + + +func clear() -> void: + _buf.fill(0) + _last_stamp = Vector2.INF + _sync() + + +## 拍一张当前笔画层的快照。绘画面板打开时存一份,点「取消」时还原 +func snapshot() -> PackedByteArray: + return _buf.duplicate() + + +## 还原到快照。尺寸对不上就忽略(换过画布大小) +func restore(data: PackedByteArray) -> void: + if data.size() != _buf.size(): + return + _buf = data.duplicate() + _last_stamp = Vector2.INF + _sync() + + +# ---------------- 存档 ---------------- + +## 笔画层存成一张透明底 PNG +func save_png(path: String) -> void: + _sync() + image.save_png(path) + + +## 读回笔画层。尺寸对不上就当没读到(换了画布大小的话) +func load_png(path: String) -> void: + if not FileAccess.file_exists(path): + return + set_image(Image.load_from_file(path)) + + +## 从一张 Image 直接载入笔画层 —— 联机收到别人的脸时走这条,不用落盘 +func set_image(img: Image) -> void: + if img == null: + return + if img.get_width() != canvas_size or img.get_height() != canvas_size: + push_warning("笔画层尺寸是 %s,画布是 %d,忽略" % [img.get_size(), canvas_size]) + return + img.convert(Image.FORMAT_RGBA8) + _buf = img.get_data() + _last_stamp = Vector2.INF + _sync() + + +## 当前笔画层的 PNG 字节 —— 联机同步用,不落盘 +func to_png_bytes() -> PackedByteArray: + _sync() + return image.save_png_to_buffer() + + +# ---------------- 内部 ---------------- + +## 把字节缓冲变成 Image 再推给显卡。一笔画完调一次 —— 512² 一次就是 1MB,别每盖一个印章都来 +func _sync() -> void: + image = Image.create_from_data(canvas_size, canvas_size, false, Image.FORMAT_RGBA8, _buf) + if texture == null: + texture = ImageTexture.create_from_image(image) + else: + texture.update(image) + + +## 按当前粗细和颜色重造笔刷。边缘留 1 像素羽化 —— 硬边的线很难看。 +func _rebuild_stamp() -> void: + var r := maxi(2, int(round(brush_width * 0.5))) + var d := r * 2 + _stamp_d = d + _stamp_rgb = Vector3(brush_color.r, brush_color.g, brush_color.b) + _cov.resize(d * d) + for y in d: + for x in d: + var dx := float(x) - float(r) + 0.5 + var dy := float(y) - float(r) + 0.5 + var dist := sqrt(dx * dx + dy * dy) / float(r) + _cov[y * d + x] = clampf((1.0 - dist) * float(r), 0.0, 1.0) + + +## 在 pos 处盖一个印章。越界像素直接跳过,所以画到边上也不会出错。 +func _stamp_at(pos: Vector2) -> void: + var d := _stamp_d + var r := d / 2 + var cx := int(round(pos.x)) - r + var cy := int(round(pos.y)) - r + var sr := _stamp_rgb.x * 255.0 + var sg := _stamp_rgb.y * 255.0 + var sb := _stamp_rgb.z * 255.0 + + for sy in d: + var ty := cy + sy + if ty < 0 or ty >= canvas_size: + continue + var row := ty * canvas_size * 4 + var srow := sy * d + for sx in d: + var tx := cx + sx + if tx < 0 or tx >= canvas_size: + continue + var cov := _cov[srow + sx] + if cov <= 0.001: + continue + var o := row + tx * 4 + + if erasing: + # 擦:把 alpha 按覆盖度乘掉。RGB 留着不管 —— shader 只看 alpha + _buf[o + 3] = int(float(_buf[o + 3]) * (1.0 - cov)) + continue + + var sa := cov + var da := float(_buf[o + 3]) / 255.0 + var na := sa + da * (1.0 - sa) + if na <= 0.0001: + continue + var ws := sa / na + var wd := da * (1.0 - sa) / na + _buf[o] = int(clampf(sr * ws + float(_buf[o]) * wd, 0.0, 255.0)) + _buf[o + 1] = int(clampf(sg * ws + float(_buf[o + 1]) * wd, 0.0, 255.0)) + _buf[o + 2] = int(clampf(sb * ws + float(_buf[o + 2]) * wd, 0.0, 255.0)) + _buf[o + 3] = int(clampf(na * 255.0, 0.0, 255.0)) diff --git a/character/player/face/face_painter.gd.uid b/character/player/face/face_painter.gd.uid new file mode 100644 index 0000000..f61f6ae --- /dev/null +++ b/character/player/face/face_painter.gd.uid @@ -0,0 +1 @@ +uid://5fbgd46kg2hj diff --git a/character/player/face/face_rig.gd b/character/player/face/face_rig.gd new file mode 100644 index 0000000..cee2c32 --- /dev/null +++ b/character/player/face/face_rig.gd @@ -0,0 +1,162 @@ +class_name FaceRig +extends Node +## 角色的脸:把 mesh 上那个「face」surface 换成自定义材质, +## 材质把「预设底图」和「玩家自绘的笔画层」合成起来。 +## +## 笔画层是一张常驻的 Image(不是 SubViewport)—— 这样即使绘画面板没打开, +## 游戏内的脸也一直是玩家画的那张。绘画面板只是把 painter.texture 显示出来, +## 把鼠标坐标换算好之后喂给 painter。 + +const SHADER_PATH := "res://character/player/face/face_paint.gdshader" +## 存档:选的是哪张预设 +const SAVE_PRESET := "user://face_preset.json" +## 存档:笔画层(透明底 PNG) +const SAVE_PAINT := "user://face_paint.png" + +## 联机同步:非本机玩家主动去要脸的次数与间隔。 +## 各端玩家节点出现的先后顺序不保证,头几次请求可能打空,所以要重试。 +const FACE_SYNC_TRIES := 5 +const FACE_SYNC_INTERVAL := 0.8 +## 第一次要之前先等一会儿。实测:主机生成玩家比客户端早几帧,立刻要会打在一个 +## 还没建出来的节点上(Godot 报 "Node not found: Main//FaceRig"),白刷一堆红字。 +const FACE_SYNC_INITIAL_DELAY := 1.0 + +@export_group("接线") +## 面部所在的 MeshInstance3D 的路径(相对本节点)。默认就是 mouse.glb 里的 body_mesh。 +## 存路径而不是节点引用:节点引用是场景实例化时由 Godot 解析的,实测这里解析不到(拿到 null), +## 自己在 _ready() 里 get_node_or_null 才稳。 +@export var mesh_path: NodePath = ^"../Body/mouse/MouseRig/Skeleton3D/body_mesh" +## 面部是第几个 surface。mouse.glb 里是 1,名字就叫 face +@export var surface_index: int = 1 +## 没有存档时用哪张脸 +@export var default_preset: Texture2D + +@export_group("画布") +## 画布边长(像素)。玩家画的笔画坐标就在这个空间里 +@export var canvas_size: int = 512 + +@export_group("面部 UV") +## 面部孤岛在贴图上的起点(实测自模型)。模型重导后 UV 变了就改这里 +@export var face_uv_min: Vector2 = Vector2(0.142, 0.031) +## 孤岛的边长(UV 单位) +@export var face_uv_size: float = 0.214 + +## 当前预设的 res:// 路径。存档靠它记住「你选的是哪张脸」 +var preset_path: String = "" +## 联机时有没有收到过这张脸主人的数据(收到了就不用再重试) +var _got_face := false + +var mesh: MeshInstance3D +var material: ShaderMaterial +var painter: FacePainter + + +func _ready() -> void: + mesh = get_node_or_null(mesh_path) as MeshInstance3D + if mesh == null: + push_warning("%s 找不到面部 mesh(%s),脸不会有变化" % [get_path(), mesh_path]) + return + + painter = FacePainter.new(canvas_size) + painter.name = "FacePainter" + add_child(painter) + + material = ShaderMaterial.new() + material.shader = load(SHADER_PATH) + material.set_shader_parameter("face_uv_min", face_uv_min) + material.set_shader_parameter("face_uv_size", face_uv_size) + material.set_shader_parameter("paint_tex", painter.texture) + mesh.set_surface_override_material(surface_index, material) + + apply_saved() + + # 联机时非本机玩家去要脸。单机(OfflineMultiplayerPeer)不用同步 + var peer := multiplayer.multiplayer_peer + if peer != null and not (peer is OfflineMultiplayerPeer) and not is_multiplayer_authority(): + _pull_remote_face() + + +# ---------------- 对外接口 ---------------- + +## 换成某张预设脸。只换底图,玩家画的笔画保留 —— 所以可以边挑预设边留着笔迹。 +func set_preset(tex: Texture2D, path: String = "") -> void: + if material != null: + material.set_shader_parameter("base_tex", tex) + if not path.is_empty(): + preset_path = path + + +func clear_paint() -> void: + if painter != null: + painter.clear() + + +## 存:预设路径 + 笔画层。下次进游戏自动读回来 +func save() -> void: + if painter == null: + return + painter.save_png(SAVE_PAINT) + var f := FileAccess.open(SAVE_PRESET, FileAccess.WRITE) + if f == null: + push_warning("脸部预设存不下来:%s" % SAVE_PRESET) + return + f.store_string(JSON.stringify({"preset": preset_path})) + + +## 读存档;没有(或存的预设已经不在了)就退回 default_preset +func apply_saved() -> void: + var preset: Texture2D = default_preset + var path := default_preset.resource_path if default_preset != null else "" + + if FileAccess.file_exists(SAVE_PRESET): + var f := FileAccess.open(SAVE_PRESET, FileAccess.READ) + var data: Variant = JSON.parse_string(f.get_as_text()) if f != null else null + if data is Dictionary: + var saved := str(data.get("preset", "")) + if not saved.is_empty() and ResourceLoader.exists(saved): + preset = load(saved) + path = saved + + set_preset(preset, path) + if painter != null: + painter.load_png(SAVE_PAINT) + + +# ---------------- 联机同步 ---------------- +# 用「谁缺谁来要」而不是「出生时推」:各端玩家节点出现的先后顺序不保证, +# 推的话很可能推给一个还不存在的节点;而请求总是从已经存在的那一端发出去的。 + +## 非本机玩家在 _ready 里调,去要这张脸主人的那一份。带重试,因为对端节点可能还没建好。 +func _pull_remote_face() -> void: + await get_tree().create_timer(FACE_SYNC_INITIAL_DELAY).timeout + for i in FACE_SYNC_TRIES: + if not is_inside_tree() or _got_face: + return + _rpc_request_face.rpc_id(get_multiplayer_authority()) + await get_tree().create_timer(FACE_SYNC_INTERVAL).timeout + + +@rpc("any_peer", "call_remote", "reliable") +func _rpc_request_face() -> void: + # 只有这张脸的主人回应 —— 别人的脸不该由我来发 + if not is_multiplayer_authority(): + return + _rpc_send_face.rpc_id( + multiplayer.get_remote_sender_id(), + preset_path, + painter.to_png_bytes() if painter != null else PackedByteArray(), + ) + + +@rpc("any_peer", "call_remote", "reliable") +func _rpc_send_face(preset: String, png: PackedByteArray) -> void: + # 只认这张脸主人的回应;本机自己的脸不接受覆盖 + if is_multiplayer_authority() or multiplayer.get_remote_sender_id() != get_multiplayer_authority(): + return + _got_face = true + if not preset.is_empty() and ResourceLoader.exists(preset): + set_preset(load(preset), preset) + if png.size() > 0 and painter != null: + var img := Image.new() + if img.load_png_from_buffer(png) == OK: + painter.set_image(img) diff --git a/character/player/face/face_rig.gd.uid b/character/player/face/face_rig.gd.uid new file mode 100644 index 0000000..18ff24a --- /dev/null +++ b/character/player/face/face_rig.gd.uid @@ -0,0 +1 @@ +uid://c6l2fl5jgvr1h diff --git a/character/player/face/presets/face_00_blank.png b/character/player/face/presets/face_00_blank.png new file mode 100644 index 0000000000000000000000000000000000000000..4f29241b8e0c3331f28a8dc1bf0b57a201481e92 GIT binary patch literal 1495 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%0A4xx=naLoJCOdWV2HKbom@NuLS@+<8((pFCE3~ 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 literal 0 HcmV?d00001 diff --git a/character/player/face/presets/face_02.png.import b/character/player/face/presets/face_02.png.import new file mode 100644 index 0000000..bc8c622 --- /dev/null +++ b/character/player/face/presets/face_02.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bup0pyw24lsft" +path="res://.godot/imported/face_02.png-914865f7dedf5c93ed2fd1b1b037f243.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://character/player/face/presets/face_02.png" +dest_files=["res://.godot/imported/face_02.png-914865f7dedf5c93ed2fd1b1b037f243.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/character/player/player.tscn b/character/player/player.tscn index fbc1f5f..da41f69 100644 --- a/character/player/player.tscn +++ b/character/player/player.tscn @@ -11,6 +11,8 @@ [ext_resource type="AnimationLibrary" uid="uid://rqhclfyiingo" path="res://character/player/assets/animations/run.glb" id="7_muf2e"] [ext_resource type="AnimationLibrary" uid="uid://dy8a178vlbsof" path="res://character/player/assets/animations/sneak.glb" id="8_jo6ux"] [ext_resource type="AnimationLibrary" uid="uid://db83440o2cyr7" path="res://character/player/assets/animations/walk.glb" id="9_fkbv7"] +[ext_resource type="Script" uid="uid://c6l2fl5jgvr1h" path="res://character/player/face/face_rig.gd" id="12_lqp71"] +[ext_resource type="Texture2D" path="res://character/player/face/presets/face_01.png" id="13_face01"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_rkbax"] radius = 0.4 @@ -65,3 +67,8 @@ modulate = Color(1, 0.95, 0.6, 1) text = "按 E 挂上滑索" font_size = 48 outline_size = 8 + +[node name="FaceRig" type="Node" parent="." unique_id=792293233] +script = ExtResource("12_lqp71") +mesh_path = NodePath("../Body/mouse/MouseRig/Skeleton3D/body_mesh") +default_preset = ExtResource("13_face01") diff --git a/project.godot b/project.godot index 27df965..b815735 100644 --- a/project.godot +++ b/project.godot @@ -11,7 +11,7 @@ config_version=5 [application] config/name="agame" -run/main_scene="uid://bp8l1uwgshc86" +run/main_scene="res://ui/main_menu.tscn" config/features=PackedStringArray("4.7", "Forward Plus") config/icon="res://icon.svg" diff --git a/tests/test_face.gd b/tests/test_face.gd new file mode 100644 index 0000000..779c829 --- /dev/null +++ b/tests/test_face.gd @@ -0,0 +1,132 @@ +@tool +extends McpTestSuite +## 回归测试:面部那套「UV 孤岛 + 预设 + 画笔」的契约。 +## +## 脸是 body_mesh 的 surface 1,UV 是一个孤岛;shader 靠 face_uv_min / face_uv_size 把孤岛 +## 重映射到 0~1,再拿这个 UV 去采样预设和笔画层。**模型重导后 UV 一变,脸就会画歪或者被裁掉, +## 而且不报任何错** —— 所以这里把数值钉死,改模型时先让测试红一次。 + +const PLAYER_SCENE_PATH := "res://character/player/player.tscn" +const SHADER_PATH := "res://character/player/face/face_paint.gdshader" +const PRESET_DIR := "res://character/player/face/presets" +const BODY_MESH_PATH := "Body/mouse/MouseRig/Skeleton3D/body_mesh" + +## FaceRig 里 face_uv_min / face_uv_size 的默认值,必须和 shader 的 uniform 默认值一致 +const FACE_UV_MIN := Vector2(0.142, 0.031) +const FACE_UV_SIZE := 0.214 +## UV 是浮点,两边各写一份,给点容差 +const EPS := 0.003 + + +func suite_name() -> String: + return "face" + + +func _player() -> Node: + var packed := load(PLAYER_SCENE_PATH) as PackedScene + assert_true(packed != null, "%s 未能加载" % PLAYER_SCENE_PATH) + if packed == null: + return null + var player := packed.instantiate() + track(player) + return player + + +func _body_mesh() -> MeshInstance3D: + var player := _player() + if player == null: + return null + return player.get_node_or_null(BODY_MESH_PATH) as MeshInstance3D + + +func test_player_has_face_rig_wired() -> void: + var player := _player() + if player == null: + return + var rig := player.get_node_or_null("FaceRig") as FaceRig + assert_true(rig != null, "Player 下缺少 FaceRig 节点") + if rig == null: + return + assert_eq(rig.surface_index, 1, "面部是 surface 1(名字叫 face),索引写错就画到身体上了") + assert_true(rig.get_node_or_null(rig.mesh_path) is MeshInstance3D, + "FaceRig.mesh_path(%s)解析不到 MeshInstance3D —— 换模型后路径要跟着改" % rig.mesh_path) + + +func test_face_surface_exists() -> void: + var mi := _body_mesh() + assert_true(mi != null, "找不到 %s" % BODY_MESH_PATH) + if mi == null: + return + var m := mi.mesh as ArrayMesh + assert_true(m != null, "body_mesh 的 mesh 不是 ArrayMesh") + if m == null: + return + assert_gt(m.get_surface_count(), 1, "body_mesh 至少要有两个 surface(0 身体 / 1 脸)") + if m.get_surface_count() < 2: + return + assert_eq(m.surface_get_name(1), "face", "surface 1 不叫 face 了 —— 确认过再改 surface_index") + + +func test_face_uv_island_matches_shader() -> void: + var mi := _body_mesh() + if mi == null: + return + var m := mi.mesh as ArrayMesh + if m == null or m.get_surface_count() < 2: + return + var uv: PackedVector2Array = m.surface_get_arrays(1)[Mesh.ARRAY_TEX_UV] + var mn := Vector2(INF, INF) + var mx := Vector2(-INF, -INF) + for v in uv: + mn = mn.min(v) + mx = mx.max(v) + var far := FACE_UV_MIN + Vector2(FACE_UV_SIZE, FACE_UV_SIZE) + # 孤岛必须整个落在 shader 重映射用的那个方框里,否则脸会错位 / 被裁掉 + assert_true(mn.x >= FACE_UV_MIN.x - EPS and mn.y >= FACE_UV_MIN.y - EPS, + "面部 UV 起点 %s 跑出了 face_uv_min %s —— 模型重导后 UV 变了?" % [mn, FACE_UV_MIN]) + assert_true(mx.x <= far.x + EPS and mx.y <= far.y + EPS, + "面部 UV 终点 %s 超出了 face_uv_min + face_uv_size = %s" % [mx, far]) + + +func test_face_shader_has_expected_uniforms() -> void: + var sh: Shader = load(SHADER_PATH) + assert_true(sh != null, "%s 加载失败" % SHADER_PATH) + if sh == null: + return + var names: Array[String] = [] + for p in sh.get_shader_uniform_list(): + names.append(str(p.get("name"))) + for required in ["face_uv_min", "face_uv_size", "base_tex", "paint_tex"]: + assert_true(names.has(required), "shader 少了 uniform %s,实际为 %s" % [required, names]) + + +## 联机同步靠这三个方法名,改名了要一起改 —— 改了就不同步,而且不报错 +func test_face_sync_methods_exist() -> void: + var script := load("res://character/player/face/face_rig.gd") as GDScript + assert_true(script != null, "face_rig.gd 加载失败") + if script == null: + return + var names: Array[String] = [] + for m in script.get_script_method_list(): + names.append(str(m.get("name"))) + for required in ["_pull_remote_face", "_rpc_request_face", "_rpc_send_face"]: + assert_true(names.has(required), "face_rig.gd 少了 %s,联机时脸不会同步" % required) + + +func test_presets_are_square() -> void: + var dir := DirAccess.open(PRESET_DIR) + assert_true(dir != null, "打不开预设目录 %s" % PRESET_DIR) + if dir == null: + return + var found := 0 + for f in dir.get_files(): + if not f.ends_with(".png"): + continue + found += 1 + var tex: Texture2D = load(PRESET_DIR + "/" + f) + assert_true(tex != null, "预设 %s 加载失败" % f) + if tex == null: + continue + var s := tex.get_size() + assert_eq(int(s.x), int(s.y), "预设 %s 不是正方形(%s),贴到脸上会拉伸" % [f, s]) + assert_gt(found, 0, "%s 里一张预设都没有" % PRESET_DIR) diff --git a/tests/test_face.gd.uid b/tests/test_face.gd.uid new file mode 100644 index 0000000..49d4ce4 --- /dev/null +++ b/tests/test_face.gd.uid @@ -0,0 +1 @@ +uid://brw0ntpgcol2o diff --git a/tests/test_net_replication.gd b/tests/test_net_replication.gd index bbe078d..47b0e82 100644 --- a/tests/test_net_replication.gd +++ b/tests/test_net_replication.gd @@ -187,6 +187,21 @@ func test_animation_track_paths_resolve() -> void: ) +## 入口场景必须是开始菜单 —— 否则启动就直接落在世界里,还顶着 Net 那个调试面板。 +## 这条防的是「有人把 run/main_scene 改回世界」。 +func test_main_scene_is_the_menu() -> void: + var configured := str(ProjectSettings.get_setting("application/run/main_scene", "")) + assert_true(not configured.is_empty(), "project.godot 没设 application/run/main_scene") + if configured.is_empty(): + return + # 存的是 uid 也可能是 res:// 路径,两种都认 + var path := configured + if configured.begins_with("uid://"): + path = ResourceUID.get_id_path(ResourceUID.text_to_id(configured)) + assert_true(path.ends_with("ui/main_menu.tscn"), + "入口场景是 %s,不是开始菜单 —— 启动会直接进世界" % path) + + ## 片段在 AnimationPlayer 里按「库名/片段名」存(导入时每个 glb 各自成一个库), ## 短名 has_animation() / get_animation() 一律查不到 —— 拿短名断言会假红,必须按库扫一遍。 func _find_clip(anim_player: AnimationPlayer, clip: String) -> Animation: diff --git a/ui/character_select.gd b/ui/character_select.gd new file mode 100644 index 0000000..33e360a --- /dev/null +++ b/ui/character_select.gd @@ -0,0 +1,92 @@ +extends Control +## 角色选择:左边一个 3D 预览(慢慢自转),右边挑角色和脸。 +## +## 预览里这具模型和玩家场景里的模型是**两套独立的 FaceRig**,但共用同一份存档: +## 这里点「确定」写进 user://,玩家出生时自己的 FaceRig.apply_saved() 读回来。 +## +## 目前只有一个角色模型(mouse.glb),所以角色那一栏只有一个按钮 —— +## 以后加了新模型,往 CharRow 里再放一个按钮就行。 + +signal confirmed +## 「返回」按下 —— 这一趟的改动不写存档 +signal back_pressed + +## 预览里模型的自转速度(弧度/秒) +const SPIN_SPEED := 0.5 +## 「自己画」用的空白脸 —— 纯色底,等于「这张脸上什么都没画」 +const BLANK_FACE := preload("res://character/player/face/presets/face_00_blank.png") + +@onready var _model: Node3D = %Model +@onready var _camera: Camera3D = %PreviewCamera +@onready var _rig: FaceRig = %FaceRig +@onready var _paint_panel: Control = $PaintPanel + +var _selected_preset: Texture2D + + +func _ready() -> void: + # 菜单里鼠标要能点 + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + # 相机看向模型胸口高度,省得在场景里手算旋转 + _camera.look_at(Vector3(0.0, 0.45, 0.0), Vector3.UP) + + %ConfirmButton.pressed.connect(_on_confirm) + %BackButton.pressed.connect(_on_back) + %DrawButton.pressed.connect(_on_draw) + + # 预设缩略图就是 PresetRow 里的子节点 —— 加预设 = 往场景里多放一个 TextureButton + for child in %PresetRow.get_children(): + var btn := child as TextureButton + if btn == null or btn.texture_normal == null: + continue + btn.pressed.connect(_on_preset_pressed.bind(btn)) + # 存档里选的那张,就是当前高亮的 + if btn.texture_normal.resource_path == _rig.preset_path: + _selected_preset = btn.texture_normal + _sync_preset_highlight() + + +func _process(delta: float) -> void: + # 转的是外层 Model 而不是模型自己,免得和朝向/动画打架 + if _model != null: + _model.rotate_y(SPIN_SPEED * delta) + + +# ---------------- 选择 ---------------- + +func _on_preset_pressed(btn: TextureButton) -> void: + if _rig == null: + return + # 只换底图,玩家画的笔画保留 —— 所以可以先挑脸型再补几笔 + _rig.set_preset(btn.texture_normal, btn.texture_normal.resource_path) + _selected_preset = btn.texture_normal + _sync_preset_highlight() + + +func _sync_preset_highlight() -> void: + for child in %PresetRow.get_children(): + var btn := child as TextureButton + if btn == null: + continue + var picked := _selected_preset != null and btn.texture_normal == _selected_preset + btn.modulate = Color.WHITE if picked else Color(0.62, 0.62, 0.62) + + +## 「自己画」= 从一张空白脸起手。空白是在面板里落的 —— 它得先拍快照再改, +## 否则点「取消」还原回来的是已经清空的状态。 +func _on_draw() -> void: + _selected_preset = null + _sync_preset_highlight() + _paint_panel.open(_rig, BLANK_FACE) + + +# ---------------- 进出 ---------------- + +func _on_confirm() -> void: + if _rig != null: + _rig.save() + confirmed.emit() + + +func _on_back() -> void: + back_pressed.emit() diff --git a/ui/character_select.gd.uid b/ui/character_select.gd.uid new file mode 100644 index 0000000..3cf52a6 --- /dev/null +++ b/ui/character_select.gd.uid @@ -0,0 +1 @@ +uid://cwd4rsma685f diff --git a/ui/character_select.tscn b/ui/character_select.tscn new file mode 100644 index 0000000..41f2fd0 --- /dev/null +++ b/ui/character_select.tscn @@ -0,0 +1,187 @@ +[gd_scene load_steps=11 format=3] + +[ext_resource type="Script" path="res://ui/character_select.gd" id="1_select"] +[ext_resource type="Script" path="res://character/player/face/face_rig.gd" id="7_face_rig"] +[ext_resource type="PackedScene" path="res://ui/paint_panel.tscn" id="2_paint"] +[ext_resource type="PackedScene" uid="uid://css1vk3u8gt7o" path="res://character/player/assets/mouse.glb" id="3_mouse"] +[ext_resource type="Sky" uid="uid://bi632suyifms5" path="res://world/sky/cartoon_sky.tres" id="4_sky"] +[ext_resource type="Texture2D" path="res://character/player/face/presets/face_01.png" id="5_face01"] +[ext_resource type="Texture2D" path="res://character/player/face/presets/face_02.png" id="6_face02"] + +[sub_resource type="Gradient" id="Gradient_bg"] +offsets = PackedFloat32Array(0, 0.55, 1) +colors = PackedColorArray(0.09, 0.3, 0.78, 1, 0.28, 0.6, 0.95, 1, 0.78, 0.88, 1, 1) + +[sub_resource type="GradientTexture2D" id="GradientTexture2D_bg"] +gradient = SubResource("Gradient_bg") +width = 4 +height = 512 +fill_from = Vector2(0.5, 0) +fill_to = Vector2(0.5, 1) + +[sub_resource type="Environment" id="Environment_preview"] +background_mode = 2 +sky = ExtResource("4_sky") +ambient_light_source = 3 +reflected_light_source = 2 + +[node name="CharacterSelect" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_select") + +[node name="Background" type="TextureRect" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +texture = SubResource("GradientTexture2D_bg") +expand_mode = 1 + +[node name="Margin" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme_override_constants/margin_left = 48 +theme_override_constants/margin_top = 40 +theme_override_constants/margin_right = 48 +theme_override_constants/margin_bottom = 40 + +[node name="Layout" type="HBoxContainer" parent="Margin"] +layout_mode = 2 +mouse_filter = 2 +theme_override_constants/separation = 36 + +[node name="Preview" type="SubViewportContainer" parent="Margin/Layout"] +custom_minimum_size = Vector2(420, 520) +layout_mode = 2 +size_flags_horizontal = 0 +size_flags_vertical = 4 +stretch = true + +[node name="PreviewViewport" type="SubViewport" parent="Margin/Layout/Preview"] +own_world_3d = true +handle_input_locally = false +size = Vector2i(420, 520) +render_target_update_mode = 4 + +[node name="Environment" type="WorldEnvironment" parent="Margin/Layout/Preview/PreviewViewport"] +environment = SubResource("Environment_preview") + +[node name="Sun" type="DirectionalLight3D" parent="Margin/Layout/Preview/PreviewViewport"] +transform = Transform3D(0.866025, -0.353553, 0.353553, 0, 0.707107, 0.707107, -0.5, -0.612372, 0.612372, 0, 3, 0) +light_energy = 1.1 + +[node name="PreviewCamera" type="Camera3D" parent="Margin/Layout/Preview/PreviewViewport"] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.62, 1.5) + +[node name="Model" type="Node3D" parent="Margin/Layout/Preview/PreviewViewport"] +unique_name_in_owner = true +transform = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0) + +[node name="mouse" parent="Margin/Layout/Preview/PreviewViewport/Model" instance=ExtResource("3_mouse")] +transform = Transform3D(0.18240133, 0, 0, 0, 0.18240133, 0, 0, 0, 0.18240133, 0, 0, 0) + +[node name="FaceRig" type="Node" parent="Margin/Layout/Preview/PreviewViewport"] +unique_name_in_owner = true +script = ExtResource("7_face_rig") +mesh_path = NodePath("../Model/mouse/MouseRig/Skeleton3D/body_mesh") +default_preset = ExtResource("5_face01") + +[node name="Right" type="VBoxContainer" parent="Margin/Layout"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_constants/separation = 14 + +[node name="CharTitle" type="Label" parent="Margin/Layout/Right"] +layout_mode = 2 +theme_override_colors/font_color = Color(1, 1, 1, 1) +theme_override_colors/font_outline_color = Color(0.05, 0.1, 0.25, 0.85) +theme_override_constants/outline_size = 10 +theme_override_font_sizes/font_size = 40 +text = "角色" + +[node name="CharRow" type="HBoxContainer" parent="Margin/Layout/Right"] +layout_mode = 2 +theme_override_constants/separation = 10 + +[node name="CharButton" type="Button" parent="Margin/Layout/Right/CharRow"] +custom_minimum_size = Vector2(160, 46) +layout_mode = 2 +text = "小老鼠" + +[node name="Spacer" type="Control" parent="Margin/Layout/Right"] +custom_minimum_size = Vector2(0, 12) +layout_mode = 2 +mouse_filter = 2 + +[node name="FaceTitle" type="Label" parent="Margin/Layout/Right"] +layout_mode = 2 +theme_override_colors/font_color = Color(1, 1, 1, 1) +theme_override_colors/font_outline_color = Color(0.05, 0.1, 0.25, 0.85) +theme_override_constants/outline_size = 8 +theme_override_font_sizes/font_size = 28 +text = "脸部" + +[node name="PresetRow" type="HBoxContainer" parent="Margin/Layout/Right"] +unique_name_in_owner = true +layout_mode = 2 +theme_override_constants/separation = 12 + +[node name="Preset0" type="TextureButton" parent="Margin/Layout/Right/PresetRow"] +custom_minimum_size = Vector2(96, 96) +layout_mode = 2 +texture_normal = ExtResource("5_face01") +ignore_texture_size = true +stretch_mode = 5 + +[node name="Preset1" type="TextureButton" parent="Margin/Layout/Right/PresetRow"] +custom_minimum_size = Vector2(96, 96) +layout_mode = 2 +texture_normal = ExtResource("6_face02") +ignore_texture_size = true +stretch_mode = 5 + +[node name="DrawButton" type="Button" parent="Margin/Layout/Right"] +unique_name_in_owner = true +custom_minimum_size = Vector2(160, 46) +layout_mode = 2 +size_flags_horizontal = 0 +text = "自己画" + +[node name="Grow" type="Control" parent="Margin/Layout/Right"] +layout_mode = 2 +size_flags_vertical = 3 +mouse_filter = 2 + +[node name="Bottom" type="HBoxContainer" parent="Margin/Layout/Right"] +layout_mode = 2 +alignment = 2 +theme_override_constants/separation = 12 + +[node name="BackButton" type="Button" parent="Margin/Layout/Right/Bottom"] +unique_name_in_owner = true +custom_minimum_size = Vector2(130, 46) +layout_mode = 2 +text = "返回" + +[node name="ConfirmButton" type="Button" parent="Margin/Layout/Right/Bottom"] +unique_name_in_owner = true +custom_minimum_size = Vector2(130, 46) +layout_mode = 2 +text = "确定" + +[node name="PaintPanel" parent="." instance=ExtResource("2_paint")] +visible = false diff --git a/ui/main_menu.gd b/ui/main_menu.gd index d22b7e7..b45c29d 100644 --- a/ui/main_menu.gd +++ b/ui/main_menu.gd @@ -1,30 +1,70 @@ extends Control -## 游戏开始菜单 —— 只有界面,没有逻辑。 +## 游戏开始菜单 —— 项目的入口场景(project.godot 的 run/main_scene)。 ## -## 四个按钮按下去只把对应信号发出去:谁接、接了之后是加载世界、连服务器还是弹设置面板, -## 都不在这个文件里。这样菜单版式可以单独改,主流程也能单独换。 +## 「开始游戏」→ 角色选择 → 确定 = 开主机并进世界。这个项目是客户端-服务器模型, +## 单人玩也是本机开服(没有单独的「离线模式」)。 +## 「联机」把 Net 的创建/加入面板放出来,那边选完同样会切进世界。 ## -## 接线示例(放在外层,比如以后的主场景或一个菜单流程单例): -## menu.start_pressed.connect(_on_start) -## menu.multiplayer_pressed.connect(_on_multiplayer) +## 进世界、回菜单这两件事都归 Net 管(见 net.gd 的 _enter_world / leave_game), +## 菜单只负责「按了哪个按钮」。 +## +## 接线示例(放在外层): ## menu.settings_pressed.connect(_on_settings) ## menu.quit_pressed.connect(get_tree().quit) -## -## 用法:把本场景设成 project.godot 的 application/run/main_scene 即可(这一步也没做)。 + +const CHARACTER_SELECT := preload("res://ui/character_select.tscn") +## 用节点路径而不是全局标识符访问单例:autoload 的全局名只在引擎启动时注册, +## 这样写不依赖注册时机(和 world/main.gd 一致) +const NET_PATH := "/root/Net" signal start_pressed signal multiplayer_pressed signal settings_pressed signal quit_pressed +var _net: Node +var _character_select: Control + func _ready() -> void: - # 从游戏内退回菜单时鼠标可能还是被捕获的,先放出来 —— 不然菜单点不动。 - # 这不算逻辑,是菜单能不能用的前提。 + # 从游戏内退回菜单时鼠标可能还是被捕获的,先放出来 —— 不然菜单点不动 Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + _net = get_node_or_null(NET_PATH) + # Net 那个「联机测试」面板默认可见(CanvasLayer layer 20),会正好盖在菜单中间 + if _net != null: + _net.set_menu_visible(false) - # 按钮只负责把 pressed 转发成信号,不在这里做任何决定。 - %StartButton.pressed.connect(start_pressed.emit) - %MultiplayerButton.pressed.connect(multiplayer_pressed.emit) + %StartButton.pressed.connect(_on_start_pressed) + %MultiplayerButton.pressed.connect(_on_multiplayer_pressed) %SettingsButton.pressed.connect(settings_pressed.emit) %QuitButton.pressed.connect(quit_pressed.emit) + + +## 「开始游戏」:先把信号发出去(外部想接就接),再把角色选择盖上来 +func _on_start_pressed() -> void: + start_pressed.emit() + if _character_select == null: + _character_select = CHARACTER_SELECT.instantiate() + add_child(_character_select) + _character_select.confirmed.connect(_on_character_confirmed) + _character_select.back_pressed.connect(_close_character_select) + _character_select.visible = true + + +## 角色选择点「确定」:脸这时已经写进 user:// 了,开主机,Net 负责切进世界 +func _on_character_confirmed() -> void: + _close_character_select() + if _net != null: + _net.host_game() + + +func _on_multiplayer_pressed() -> void: + multiplayer_pressed.emit() + # 暂时直接把 Net 那个创建/加入面板放出来顶着 —— 换成正经的联机子页后删掉这行 + if _net != null: + _net.set_menu_visible(true) + + +func _close_character_select() -> void: + if _character_select != null: + _character_select.visible = false diff --git a/ui/paint_panel.gd b/ui/paint_panel.gd new file mode 100644 index 0000000..92c078e --- /dev/null +++ b/ui/paint_panel.gd @@ -0,0 +1,130 @@ +extends Control +## 画脸面板:把 FaceRig 的笔画层显示出来,并把鼠标坐标换算成画布坐标喂给画笔。 +## +## 面板自己不画任何东西 —— 笔画直接落在 FaceRig 的画笔上,所以关掉面板后角色脸上立刻就是刚画的。 +## 打开时拍一张快照,点「取消」还原;点「完成」才写进存档。 + +signal finished +signal cancelled + +## 画布在屏幕上的显示边长。真实画布是 rig.canvas_size 见方,坐标按比例换算 +const VIEW_SIZE := 420 + +@onready var _canvas_rect: TextureRect = %StrokeRect +@onready var _preset_rect: TextureRect = %PresetRect +@onready var _color_button: ColorPickerButton = %ColorButton +@onready var _width_slider: HSlider = %WidthSlider +@onready var _width_label: Label = %WidthLabel +@onready var _eraser_toggle: CheckButton = %EraserToggle + +var _rig: FaceRig +## 打开面板时的笔画层快照,取消时还原 +var _snapshot: PackedByteArray +## 打开面板时用的是哪张预设,取消时一并还原(「自己画」会把底图换成空白) +var _preset_before: String = "" +## 左键是不是按着 —— 拖拽判定用这个,不看 motion 事件里的 button_mask +var _drawing := false + + +func _ready() -> void: + visible = false + _canvas_rect.custom_minimum_size = Vector2(VIEW_SIZE, VIEW_SIZE) + _canvas_rect.gui_input.connect(_on_canvas_input) + _color_button.color_changed.connect(_on_color_changed) + _width_slider.value_changed.connect(_on_width_changed) + _eraser_toggle.toggled.connect(_on_eraser_toggled) + %ClearButton.pressed.connect(_on_clear) + %DoneButton.pressed.connect(_on_done) + %CancelButton.pressed.connect(_on_cancel) + _on_width_changed(_width_slider.value) + + +# ---------------- 对外接口 ---------------- + +## 打开面板并绑定到某个 FaceRig。 +## blank_face 传了就从这张空白脸起手(「自己画」用)—— 快照仍然记的是改动之前的状态, +## 所以点「取消」能把底图和笔画一起还原。 +func open(rig: FaceRig, blank_face: Texture2D = null) -> void: + if rig == null or rig.painter == null: + push_warning("画脸面板没拿到可用的 FaceRig") + return + _rig = rig + _snapshot = rig.painter.snapshot() + _preset_before = rig.preset_path + if blank_face != null: + rig.set_preset(blank_face, blank_face.resource_path) + rig.clear_paint() + _canvas_rect.texture = rig.painter.texture + # 画布只显示笔画层,底下得把底图一起摆出来 —— 不然玩家是在对着空气画 + _preset_rect.texture = rig.material.get_shader_parameter("base_tex") as Texture2D + rig.painter.brush_color = _color_button.color + rig.painter.brush_width = _width_slider.value + rig.painter.erasing = _eraser_toggle.button_pressed + visible = true + + +# ---------------- 画布输入 ---------------- + +## 屏幕坐标 → 画布坐标。显示尺寸和画布尺寸不一致时按比例缩 +func _canvas_pos(event: InputEventMouse) -> Vector2: + var scale := float(_rig.painter.canvas_size) / maxf(1.0, _canvas_rect.size.x) + return event.position * scale + + +func _on_canvas_input(event: InputEvent) -> void: + if _rig == null: + return + if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT: + # 自己记「按没按下」,不靠 motion 事件里的 button_mask —— 那个字段不总是可靠 + _drawing = event.pressed + if event.pressed: + _rig.painter.begin_stroke(_canvas_pos(event)) + else: + _rig.painter.end_stroke() + elif event is InputEventMouseMotion and _drawing: + _rig.painter.extend_stroke(_canvas_pos(event)) + + +# ---------------- 工具条 ---------------- + +func _on_color_changed(c: Color) -> void: + if _rig != null: + _rig.painter.brush_color = c + # 选了颜色就顺手退出橡皮 —— 不然「我选了红色怎么还是擦」 + _eraser_toggle.set_pressed_no_signal(false) + if _rig != null: + _rig.painter.erasing = false + + +func _on_width_changed(w: float) -> void: + if _rig != null: + _rig.painter.brush_width = w + _width_label.text = "%d px" % int(w) + + +func _on_eraser_toggled(on: bool) -> void: + if _rig != null: + _rig.painter.erasing = on + + +func _on_clear() -> void: + if _rig != null: + _rig.painter.clear() + + +func _on_done() -> void: + if _rig != null: + _rig.save() + visible = false + finished.emit() + + +func _on_cancel() -> void: + if _rig != null: + if _snapshot.size() > 0: + _rig.painter.restore(_snapshot) + # 底图也要还原 —— 「自己画」把它换成空白了,只还原笔画会留下一张白脸 + if not _preset_before.is_empty() and ResourceLoader.exists(_preset_before): + _rig.set_preset(load(_preset_before), _preset_before) + visible = false + cancelled.emit() diff --git a/ui/paint_panel.gd.uid b/ui/paint_panel.gd.uid new file mode 100644 index 0000000..09830c1 --- /dev/null +++ b/ui/paint_panel.gd.uid @@ -0,0 +1 @@ +uid://cjxxd2m1w00y5 diff --git a/ui/paint_panel.tscn b/ui/paint_panel.tscn new file mode 100644 index 0000000..87c7489 --- /dev/null +++ b/ui/paint_panel.tscn @@ -0,0 +1,148 @@ +[gd_scene load_steps=2 format=3] + +[ext_resource type="Script" path="res://ui/paint_panel.gd" id="1_paint"] + +[node name="PaintPanel" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_paint") + +[node name="Dim" type="ColorRect" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0.03, 0.06, 0.14, 0.72) + +[node name="Center" type="CenterContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 + +[node name="Panel" type="PanelContainer" parent="Center"] +layout_mode = 2 + +[node name="Margin" type="MarginContainer" parent="Center/Panel"] +layout_mode = 2 +theme_override_constants/margin_left = 18 +theme_override_constants/margin_top = 14 +theme_override_constants/margin_right = 18 +theme_override_constants/margin_bottom = 14 + +[node name="Box" type="VBoxContainer" parent="Center/Panel/Margin"] +layout_mode = 2 +theme_override_constants/separation = 12 + +[node name="Title" type="Label" parent="Center/Panel/Margin/Box"] +layout_mode = 2 +theme_override_font_sizes/font_size = 22 +text = "画脸" + +[node name="Row" type="HBoxContainer" parent="Center/Panel/Margin/Box"] +layout_mode = 2 +theme_override_constants/separation = 16 + +[node name="CanvasStack" type="Control" parent="Center/Panel/Margin/Box/Row"] +custom_minimum_size = Vector2(420, 420) +layout_mode = 2 +mouse_filter = 2 + +[node name="PresetRect" type="TextureRect" parent="Center/Panel/Margin/Box/Row/CanvasStack"] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +expand_mode = 1 + +[node name="StrokeRect" type="TextureRect" parent="Center/Panel/Margin/Box/Row/CanvasStack"] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 0 +expand_mode = 1 + +[node name="Tools" type="VBoxContainer" parent="Center/Panel/Margin/Box/Row"] +layout_mode = 2 +theme_override_constants/separation = 10 + +[node name="ColorButton" type="ColorPickerButton" parent="Center/Panel/Margin/Box/Row/Tools"] +unique_name_in_owner = true +custom_minimum_size = Vector2(160, 36) +layout_mode = 2 +color = Color(0, 0, 0, 1) + +[node name="WidthRow" type="HBoxContainer" parent="Center/Panel/Margin/Box/Row/Tools"] +layout_mode = 2 +theme_override_constants/separation = 8 + +[node name="Label" type="Label" parent="Center/Panel/Margin/Box/Row/Tools/WidthRow"] +layout_mode = 2 +text = "粗细" + +[node name="WidthSlider" type="HSlider" parent="Center/Panel/Margin/Box/Row/Tools/WidthRow"] +unique_name_in_owner = true +custom_minimum_size = Vector2(110, 0) +layout_mode = 2 +min_value = 2.0 +max_value = 48.0 +value = 12.0 + +[node name="WidthLabel" type="Label" parent="Center/Panel/Margin/Box/Row/Tools/WidthRow"] +unique_name_in_owner = true +custom_minimum_size = Vector2(52, 0) +layout_mode = 2 +text = "12 px" + +[node name="EraserToggle" type="CheckButton" parent="Center/Panel/Margin/Box/Row/Tools"] +unique_name_in_owner = true +layout_mode = 2 +text = "橡皮" + +[node name="ClearButton" type="Button" parent="Center/Panel/Margin/Box/Row/Tools"] +unique_name_in_owner = true +layout_mode = 2 +text = "清空" + +[node name="Hint" type="Label" parent="Center/Panel/Margin/Box/Row/Tools"] +layout_mode = 2 +custom_minimum_size = Vector2(160, 0) +modulate = Color(1, 1, 1, 0.65) +theme_override_font_sizes/font_size = 13 +text = "在左边画布上直接画。 +橡皮擦掉笔画,露出来的是预设脸。" +autowrap_mode = 3 + +[node name="Bottom" type="HBoxContainer" parent="Center/Panel/Margin/Box"] +layout_mode = 2 +alignment = 2 +theme_override_constants/separation = 10 + +[node name="CancelButton" type="Button" parent="Center/Panel/Margin/Box/Bottom"] +unique_name_in_owner = true +custom_minimum_size = Vector2(120, 40) +layout_mode = 2 +text = "取消" + +[node name="DoneButton" type="Button" parent="Center/Panel/Margin/Box/Bottom"] +unique_name_in_owner = true +custom_minimum_size = Vector2(120, 40) +layout_mode = 2 +text = "完成"