如何在Godot工具模式下合并多个Sprite节点为单个Sprite?
在Godot工具模式下合并多个Sprite为单个Sprite节点
完全可以通过Image类或VisualServer实现这个需求,以下是两种方案的具体实现:
方案一:使用Image类手动绘制(精确控制,适合简单场景)
这种方法需要计算每个Sprite的位置和尺寸,手动将所有Sprite的图片绘制到一张新的Image上,适合对合并细节有精准要求的场景。
实现步骤
- 获取选中的所有Sprite节点,计算它们的整体包围盒(确定新Image的尺寸)
- 创建对应尺寸的空白Image
- 遍历每个Sprite,将其图片绘制到新Image的对应位置(处理坐标转换)
- 创建新的Sprite节点,将合并后的Image赋值给它
工具脚本示例
@tool extends EditorScript func _run(): # 获取编辑器中选中的Sprite节点 var selected_nodes = get_editor_interface().get_selection().get_selected_nodes() var sprites = [] for node in selected_nodes: if node is Sprite2D: sprites.append(node) if sprites.size() < 2: print("请至少选中2个Sprite2D节点") return # 计算所有Sprite的全局包围盒 var global_rect = Rect2() for sprite in sprites: var sprite_global_rect = sprite.get_global_rect() if global_rect.position == Vector2.ZERO: global_rect = sprite_global_rect else: global_rect = global_rect.merge(sprite_global_rect) # 创建足够大的空白Image(带透明通道) var merged_image = Image.create(global_rect.size.x, global_rect.size.y, false, Image.FORMAT_RGBA8) merged_image.fill(Color(0,0,0,0)) # 逐个绘制每个Sprite的图片到新Image for sprite in sprites: var sprite_texture = sprite.texture if not sprite_texture: continue var sprite_image = sprite_texture.get_image() # 计算Sprite在新Image中的局部位置(全局坐标转成新Image的相对坐标) var draw_pos = sprite.get_global_position() - global_rect.position - sprite.get_offset() # 绘制图片,考虑Sprite的缩放 merged_image.blit_rect(sprite_image, Rect2(Vector2.ZERO, sprite_image.get_size()), Rect2(draw_pos, sprite_image.get_size() * sprite.scale)) # 创建新的Sprite节点并设置合并后的图片 var new_sprite = Sprite2D.new() var new_texture = ImageTexture.create_from_image(merged_image) new_sprite.texture = new_texture # 设置新Sprite的位置为原包围盒的左上角(保持全局位置一致) new_sprite.global_position = global_rect.position # 添加到当前场景 get_editor_interface().get_edited_scene_root().add_child(new_sprite) print("Sprite合并完成!")
方案二:使用VisualServer通过Viewport渲染(更便捷,支持复杂节点)
如果Sprite带有旋转、特效或其他复杂变换,使用Viewport渲染的方式更简单,相当于直接“截图”合并后的效果。
实现步骤
- 创建临时Viewport,设置尺寸为所有Sprite的包围盒大小
- 将选中的Sprite临时复制到Viewport中(避免影响原场景)
- 渲染Viewport并抓取纹理,转成Image
- 创建新Sprite并赋值Image,清理临时节点
工具脚本示例
@tool extends EditorScript func _run(): var selected_nodes = get_editor_interface().get_selection().get_selected_nodes() var sprites = [] for node in selected_nodes: if node is Sprite2D: sprites.append(node) if sprites.size() < 2: print("请至少选中2个Sprite2D节点") return # 计算全局包围盒 var global_rect = Rect2() for sprite in sprites: var sprite_global_rect = sprite.get_global_rect() global_rect = global_rect.merge(sprite_global_rect) # 创建临时Viewport var viewport = Viewport.new() viewport.size = global_rect.size viewport.transparent_bg = true # 添加到场景临时渲染 get_editor_interface().get_edited_scene_root().add_child(viewport) # 复制每个Sprite到Viewport中,调整位置为相对Viewport的坐标 for sprite in sprites: var sprite_copy = sprite.duplicate() # 转换全局坐标为Viewport局部坐标 sprite_copy.position = sprite.get_global_position() - global_rect.position viewport.add_child(sprite_copy) # 强制渲染Viewport并等待完成 viewport.render_target_update_mode = Viewport.UPDATE_ONCE await get_tree().process_frame # 获取Viewport的纹理并转成Image var viewport_texture = viewport.get_texture() var merged_image = viewport_texture.get_image() # 创建新Sprite var new_sprite = Sprite2D.new() var new_texture = ImageTexture.create_from_image(merged_image) new_sprite.texture = new_texture new_sprite.global_position = global_rect.position get_editor_interface().get_edited_scene_root().add_child(new_sprite) # 清理临时Viewport viewport.queue_free() print("Sprite合并完成!")
使用说明
- 将上述任意脚本保存为
.gd文件,放入Godot项目中 - 在编辑器中选中要合并的多个Sprite节点
- 点击编辑器顶部的
Script->Run Script执行脚本,即可生成合并后的新Sprite
内容的提问来源于stack exchange,提问作者cak3_lover
相关产品推荐
相关产品推荐

