From b826bfb562cab69389a717e19c01ef4b415eb2c5 Mon Sep 17 00:00:00 2001 From: yvmou_ Date: Sun, 4 Oct 2026 19:46:30 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E7=A0=94=E6=8F=92=E4=BB=B6=EF=BC=9A?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E7=BC=96=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/mesh_collider/README.md | 8 +++++++ addons/mesh_collider/mesh_collider_plugin.gd | 24 ++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/addons/mesh_collider/README.md b/addons/mesh_collider/README.md index d2c7661..589792f 100644 --- a/addons/mesh_collider/README.md +++ b/addons/mesh_collider/README.md @@ -40,6 +40,8 @@ 一次拖入多个模型只弹**一个**弹窗,确认后整批处理。不想被问就把 `ask_before_adding` 关掉,改由 `auto_add_collision` 决定。 +加完碰撞的模型会被自动**编组**:视图里点它的任何子节点,选中的都是模型本身(见下面「生成的节点结构」)。 + 菜单里还有四个手动操作: | 菜单项 | 作用 | @@ -59,6 +61,12 @@ Chair_PC_04 ← 模型实例,仍然引用 res://.../chair. └─ Chair_PC_04Shape (CollisionShape3D) ``` +加碰撞的同时,插件会给**模型实例**打上编辑器自己的「编组」标记(在场景面板点 Ctrl+G 是同一个东西,存成 `metadata/_edit_group_ = true`)。效果是:**在 2D / 3D 视图里点这个模型的任何子节点,选中的都是模型本身**,而不是 `CollisionBody` 或某个 `CollisionShape3D`。 + +- 这个标记会写进 `.tscn`,关掉编辑器再打开依然有效; +- 只在模型**还没有**这个标记时才打 —— 你自己手工编组过的不会被覆盖,撤销一次注入也不会把你自己编的组撤掉; +- 「移除选中模型的碰撞」**不会**取消编组(编组对模型本身是有益的,而且可能本来就是你加的)。 + 这个布局与 **Godot 自己**用 `-col` / `-convcol` 名字后缀导入时生成的完全一致。我实测过每种后缀的行为: | 后缀 | Godot 生成的形状 | diff --git a/addons/mesh_collider/mesh_collider_plugin.gd b/addons/mesh_collider/mesh_collider_plugin.gd index 432da00..c4ce619 100644 --- a/addons/mesh_collider/mesh_collider_plugin.gd +++ b/addons/mesh_collider/mesh_collider_plugin.gd @@ -65,6 +65,16 @@ const MENU_ADD := "Mesh Collider: 给选中模型加碰撞 / Add collision to se const MENU_REMOVE := "Mesh Collider: 移除选中模型的碰撞 / Remove collision" const MENU_SETTINGS := "Mesh Collider: 打开项目设置 / Open project settings" +## The editor's own "group selected nodes" flag - the toggle next to the lock +## icon in the Scene dock, bound to Ctrl+G. +## +## A node carrying it is what gets selected when any of its children is clicked +## in the 2D/3D view, which is exactly what a model with a CollisionBody and a +## pile of CollisionShape3D under it needs. It is a plain node meta, and Godot +## serialises it into the scene as `metadata/_edit_group_ = true`, so setting it +## here is all it takes - no editor-only state, nothing to re-apply on load. +const META_GROUP := &"_edit_group_" + func _enter_tree() -> void: Settings.install() @@ -226,11 +236,21 @@ func _inject(model: Node, source: String = "") -> bool: undo.add_do_method(Collider, "prepare_for_scene", body, scene_root) undo.add_do_reference(body) undo.add_undo_method(model, "remove_child", body) + # Group the model, so clicking it in the viewport selects the model rather + # than the body or a shape we just hung under it. Only when it is not already + # grouped, so a choice made by hand is never overwritten - and the undo entry + # is only added in that same case, so undoing an injection cannot un-group + # something the user had grouped themselves. + var grouping := not model.has_meta(META_GROUP) + if grouping: + undo.add_do_method(model, "set_meta", META_GROUP, true) + undo.add_undo_method(model, "remove_meta", META_GROUP) undo.commit_action() get_editor_interface().mark_scene_as_unsaved() - print("[MeshCollider] %s (%s): added %s with %d shape(s)" - % [model.name, source.get_file(), body.get_class(), Collider.count_shapes(body)]) + print("[MeshCollider] %s (%s): added %s with %d shape(s)%s" + % [model.name, source.get_file(), body.get_class(), Collider.count_shapes(body), + " [已编组]" if grouping else ""]) return true