mcpField
G
godot-adapt-2d-to-3d

godot-adapt-2d-to-3d

github.com/thedivergentai开发907287 次安装2 周前更新
代码仓库

关于 godot-adapt-2d-to-3d

面向 Godot 项目的 2D 转 3D 与 2.5D 技能,涵盖相机、移动和物理迁移脚本,并提供美术、界面及性能指导。

主要功能

  1. 012D 到 3D 节点迁移指导
  2. 02相机与移动迁移脚本
  3. 03物理层迁移清单
  4. 04精灵、模型与界面适配
  5. 053D 性能与缩放指导

适用场景

  1. 01将 CharacterBody2D 游戏移植到 3D
  2. 02使用广告牌精灵制作 2.5D 游戏
  3. 03将 Camera2D 相机系统替换为 3D 相机
  4. 04在目标硬件上分析 2D 转 3D 项目

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/thedivergentai/game-dev-agentic-skills --skill godot-adapt-2d-to-3d

安装后在 Claude Code 中输入/godot-adapt-2d-to-3d确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
migration-notes.md
migration-recipes.md
scripts/
adapt_2d_to_3d_patterns.gd
characterbody3d_migration_movement.gd
crisp_projected_ui.gd
light_migration_tool.gd
massive_crowd_manager.gd
navigation_bridge_2d5d.gd
physics_layer_migration_checklist.gd
spring_arm_camera_setup.gd
sprite_plane.gd
vector_mapping.gd

详细介绍

绝对不要做的事

  • 绝对不要直接将 Vector2 替换为 Vector3(x, y, 0) — 这会创建一款没有深度玩法的“扁平 3D”游戏。添加 Z 轴移动或摄像机旋转,让 3D 有其意义。
  • 绝对不要保留 2D 碰撞层 — 2D 和 3D 物理使用独立的层系统。必须为 3D 节点重新配置 collision_layer/collision_mask。
  • 绝对不要忘记添加光照 — 3D 场景没有灯光时会一片漆黑(除非使用无光照材质)。至少添加一个 DirectionalLight3D。
  • 绝对不要在 3D 中使用 Camera2D 跟随逻辑 — Camera3D 需要弹簧臂或注视目标逻辑。直接复制位置会导致穿模和方向感混乱。
  • 绝对不要假设性能相同 — 3D 的性能开销是 2D 的 5-10 倍。应减少绘制调用,并为移动设备使用更小的视口分辨率。
  • 绝对不要使用 rotation 属性处理复杂的 3D 逻辑 — 3D 旋转使用欧拉角。插值欧拉角会导致路径不可预测和万向节锁。3D 旋转插值始终使用 Quaternion,方向向量则使用 Basis 矩阵。
  • 绝对不要忽略公制缩放 — 3D 物理和光照默认 1 个单位 = 1 米。在引擎内缩放模型会引入精度误差。请从 DCC 导出公制比例正确的资源。
  • 使用自定义摄像机跟随脚本时,绝对不要禁用物理插值 — 在 _process 中更新摄像机位置以跟随在 _physics_process 中移动的物体,会导致抖动。使用 Node3D.get_global_transform_interpolated() 平滑变换。

可用脚本

必须遵守:粘贴摄像机/移动方案前,先加载迁移脚本。

spring_arm_camera_setup.gd

必须遵守:第三人称 SpringArm3D + Camera3D。不要将 Camera3D 直接作为物体的子节点。

characterbody3d_migration_movement.gd

必须遵守:适用于 2D→3D 移植的、相对于摄像机的 CharacterBody3D 移动方式。

physics_layer_migration_checklist.gd

必须遵守:检查清单:3D 物理层名称与 2D 分开——先镜像名称,再设置位。

sprite_plane.gd

用于在 3D 物体上放置 2D UI 的 Sprite3D 广告牌配置和世界到屏幕投影。

vector_mapping.gd

Vector2↔Vector3 映射辅助工具(Y 向上与 Z 向前的常见问题)。

crisp_projected_ui.gd

Diegetic/投影式 UI 清晰度方案。

adapt_2d_to_3d_patterns.gd

广告牌、鼠标→3D 射线、CanvasLayer 覆盖层辅助工具。

navigation_bridge_2d5d.gd

将 NavigationServer3D 路径投影到 2D 屏幕/游戏平面,供 2.5D 精灵角色使用。

massive_crowd_manager.gd

使用 MultiMesh + 广告牌着色器管理人群(由 GPU 控制朝向;而非逐节点使用 Sprite3D)。

不要加载此处的深入光照指南——请转到 godot-3d-lighting。仅添加 DirectionalLight3D + 环境光;GI/级联内容请参阅该指南。


节点转换对照表

2D 节点3D 等效项备注
CharacterBody2DCharacterBody3D必须遵守 characterbody3d_migration_movement.gd
RigidBody2DRigidBody3D重力 Vector3(0, -9.8, 0)
StaticBody2DStaticBody3DShape3D 资源(不会自动转换)
Area2DArea3D触发器概念相同;使用新层
Sprite2DMeshInstance3D / Sprite3D选择广告牌或网格美术资源
Camera2DCamera3D必须遵守 spring_arm_camera_setup.gd
CollisionShape2DCollisionShape3D重新制作形状
RayCast2DRayCast3Dtarget_position 为 Vector3

迁移步骤(脚本优先)

  1. 物理层 — 必需 physics_layer_migration_checklist.gd。项目设置 → 层名称 → 3D 物理。
  2. 摄像机 — 必需 spring_arm_camera_setup.gd。切勿将 Camera2D 跟随逻辑照搬到 Camera3D。
  3. 移动 — 必需 characterbody3d_migration_movement.gd。相机相对的 XZ 移动;在 Y 轴跳跃。

美术资源流程:精灵 → 3D 模型

选项 1:广告牌精灵(2.5D)
# Use Sprite3D for quick conversion
extends Sprite3D

func _ready() -> void:
    texture = load("res://sprites/character.png")
    billboard = BaseMaterial3D.BILLBOARD_ENABLED  # Always face camera
    pixel_size = 0.01  # Scale sprite in 3D space
选项 2:四边形网格(浮动精灵)
# Create textured quads
var mesh_instance := MeshInstance3D.new()
var quad := QuadMesh.new()
quad.size = Vector2(1, 1)
mesh_instance.mesh = quad

var material := StandardMaterial3D.new()
material.albedo_texture = load("res://sprites/character.png")
material.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
material.cull_mode = BaseMaterial3D.CULL_DISABLED  # Show both sides
mesh_instance.material_override = material
选项 3:完整 3D 模型(Blender/资源库)
# Import .glb, .fbx models
var character := load("res://models/character.glb").instantiate()
add_child(character)

# Access animations
var anim_player := character.get_node("AnimationPlayer")
anim_player.play("idle")

光照注意事项

最低配置:一个 DirectionalLight3D + WorldEnvironment 环境光,避免场景一片漆黑。此技能中不要加载级联阴影/GI/烘焙教程 — godot-3d-lighting。


UI 适配

# ✅ GOOD: Keep 2D UI overlay
# Scene structure:
# Main (Node3D)
#   ├─ WorldEnvironment
#   ├─ DirectionalLight3D
#   ├─ Player (CharacterBody3D)
#   └─ CanvasLayer  # 2D UI on top of 3D world
#       └─ Control (HUD)

# UI remains 2D (Control nodes, Sprite2D for HUD elements)

性能预算(性能分析器门槛)

推测性的“2D 与 3D 预算”表格并不可靠。应以实测数据为准:

  1. 移植版本在目标硬件上运行后,打开“性能分析器 / 调试器 → 监视器”。
  2. 绘制调用 / 图元 — 如果 MeshInstance 数量激增,应先添加网格 LOD / 可见范围,再猜测顶点上限。
  3. 阴影开销 — 降低 directional_shadow_max_distance 和带阴影的 Omni/Spot 数量,直到帧时间恢复(在 godot-3d-lighting 中调整)。
  4. LOD 流程 — 为远处的 GeometryInstance3D 设置 visibility_range_*;在近距离范围之外使用无光照 / 简化材质。
  5. 失败门槛 — 只有当第 95 百分位帧时间达到平台目标时才发布(例如 60 FPS 时 ≤16.6 ms),而不是因为电子表格写着“50–100 次绘制调用”。

输入方案变更

2D → 3D 输入映射
# 2D: left/right for horizontal movement
Input.get_axis("left", "right")

# 3D: Add forward/back, use get_vector()
var input := Input.get_vector("left", "right", "forward", "back")
# Returns Vector2(horizontal, vertical) for 3D movement

# Configure in Project Settings → Input Map:
# forward: W, Up Arrow
# back: S, Down Arrow
# left: A, Left Arrow
# right: D, Right Arrow

# Mouse look (lock cursor)
func _ready() -> void:
    Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

func _input(event: InputEvent) -> void:
    if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
        rotate_camera(event.relative)

边缘情况

物理不起作用
# Problem: Forgot to set collision layers for 3D
# Solution: Reconfigure layers

var body := CharacterBody3D.new()
body.collision_layer = 0b0001  # What AM I?
body.collision_mask = 0b0110   # What do I DETECT?
摄像机穿墙

使用必需的 spring_arm_camera_setup.gd — 将 spring_arm.collision_mask 设为 World 层,让弹簧臂缩回而不是穿墙。

玩家穿过地面
# Problem: StaticBody3D floor has no CollisionShape3D
# Solution: Add collision

var floor_collision := CollisionShape3D.new()
var box_shape := BoxShape3D.new()
box_shape.size = Vector3(100, 1, 100)
floor_collision.shape = box_shape
floor.add_child(floor_collision)

决策树:何时转为 3D

因素保持 2D转为 3D
玩法平台游戏、俯视视角、无需深度探索、第一人称、3D 空间战斗
美术预算像素美术、资源有限有现成 3D 模型或必须使用 3D 模型
性能目标移动设备、Web、低端设备桌面设备、主机、高端移动设备
开发时间有限有时间学习 3D
团队技能只有 2D 美术人员有 3D 美术人员或资源库

专家技巧与优化

1. 使用向量数学,而非欧拉角

移动 3D 角色时,应大量使用 Transform3D 基向量,而不是计算三角函数角度。若要在本地坐标系中向前移动,从变换的基中提取负 Z 轴:velocity = transform.basis.z * speed。

2. 理解坐标差异

在 2D 中,Y 轴朝下。在 3D 中,Godot 使用右手坐标系,Y 轴朝上,前方为 -Z。将 2D 跳跃迁移到 3D 时,需要反转 Y 轴速度逻辑(例如,使用 velocity.y = JUMP_SPEED 而不是 -JUMP_SPEED)。

3. 2.5D 导航(相机投影路径)

对于角色在 3D 地面上移动、但以 2D 精灵显示的 2.5D 游戏,可直接查询 NavigationServer3D,并使用 Camera3D.unproject_position 将得到的 PackedVector3Array 投影到 2D 屏幕空间(或展平的游戏平面)。

class_name NavigationBridge2D5D extends Node

## Projects 3D NavigationServer paths to 2D screenspace for 2.5D movement.
static func query_2_5d_path(camera: Camera3D, map_rid: RID, start_2d: Vector2, target_2d: Vector2) -> PackedVector2Array:
    # 1. Project 2D screen points to the 3D ground plane (Y=0).
    var start_3d := camera.project_position(start_2d, 0.0)
    var target_3d := camera.project_position(target_2d, 0.0)
    
    # 2. Query optimized 3D path.
    var path_3d := NavigationServer3D.map_get_path(map_rid, start_3d, target_3d, true)
    
    # 3. Project 3D world points back to 2D screenspace coordinates for the sprite.
    var path_2d := PackedVector2Array()
    for point in path_3d:
        path_2d.append(camera.unproject_position(point))
        
    return path_2d
4. 基于着色器的广告牌(大规模人群渲染)

若要渲染数百万个实例,可将 MultiMeshInstance3D 与自定义 Visual Shader 搭配使用。使用 VisualShaderNodeBillboard 和 BILLBOARD_TYPE_FIXED_Y,确保精灵在平坦地形上保持直立。

class_name MassiveCrowdManager extends MultiMeshInstance3D
## Efficiently manages millions of camera-facing instances via GPU hardware.

func _ready() -> void:
    # 1. Configure the MultiMesh for 3D transforms.
    multimesh = MultiMesh.new()
    multimesh.transform_format = MultiMesh.TRANSFORM_3D
    multimesh.instance_count = 10000
    
    # 2. Build a ShaderMaterial using VisualShaderNodeBillboard.
    var material := ShaderMaterial.new()
    # Note: Logic assumes billboard_type=BILLBOARD_TYPE_FIXED_Y and keep_scale=true.
    multimesh.mesh = QuadMesh.new()
    multimesh.mesh.surface_set_material(0, material)
    
    # 3. Populate transforms. The GPU handles orientation.
    for i in range(multimesh.instance_count):
        var pos := Vector3(randf() * 100, 0, randf() * 100)
        multimesh.set_instance_transform(i, Transform3D(Basis(), pos))
5. 光照迁移

PointLight2D→OmniLight3D 转换是一次性的编辑器工作——如有需要,可保留项目工具。持续提升光照质量应交由 godot-3d-lighting。

深入教程(按需查看)

主题参考资料 / 脚本
分步迁移 / 性能门槛migration-recipes.md
2.5D 导航桥接 / 人群广告牌内嵌专家技巧 + 附带脚本

参考

渐进式展开:仅在研究特定 API 时打开官方文档链接;在转交给相关领域时加载相关技能——不要预加载整个技能网络。

官方文档
  • 3D 简介 — 离开 CanvasItem/Y 轴向下的 2D 世界时必须采用的坐标系、Node3D 和摄像机基础知识。
  • 使用变换 — 用来替代欧拉角 Camera2D 跟随和 2D 旋转习惯的 Basis/Transform3D/Quaternion 模式。
  • CharacterBody3D — 将 CharacterBody2D 转换为 CharacterBody3D 后使用的目标 move_and_slide API(没有专门的 3D 教程页面)。
  • 物理简介 — 独立的 2D/3D 层系统、单位(1 单位 ≈ 1 米)和重力向量;这些因素会使复制的 2D 遮罩失效。
  • 碰撞形状(3D) — 重建 CollisionShape3D 堆栈时,BoxShape2D/CapsuleShape2D 对应的 Shape3D 等效项。
  • SpringArm3D — 必须用来替代直接复制 Camera2D 位置的第三人称延长臂和遮挡回拉功能。
  • 3D 灯光与阴影 — DirectionalLight3D/OmniLight3D 的最低限度配置;没有灯光或未受光照材质时,3D 场景会一片漆黑。
  • 环境与后期处理 — 使用 WorldEnvironment 提供环境补光,避免场景在主光源之间漆黑一片。
  • Standard Material 3D — Sprite3D/QuadMesh 精灵转平面美术流程所需的广告牌、透明度和着色模式。
  • 使用 GridMaps — 在 3D 中替代 TileMapLayer 式关卡布局的 MeshLibrary/GridMap。
  • 导入 3D 场景 — 从精灵工作流转向真实网格时的 GLB/FBX 缩放和动画导入。
  • 物理插值简介 — 物理步进移动后,为何在 _process 中跟随摄像机需要使用插值变换。
相关技能
前置条件
  • godot-gdscript-mastery — 在应用 Y→Z 映射辅助函数之前,熟练掌握类型化的 Vector2/Vector3 和 Transform3D。
  • godot-characterbody-2d — 将平台跳跃/俯视视角的移动语义移植到 CharacterBody3D 时,作为参考来源。
  • godot-2d-physics — 需要在独立的 3D 物理层表中重新创建的现有 2D 层/遮罩设计。
  • godot-input-handling — 使用 Input.get_vector 和鼠标捕获视角控制,将 2D 左右移动映射为相机相对的 XZ 移动。
补充技能
  • godot-camera-systems — 移植后取代 Camera2D 跟随的 SpringArm3D / 环绕 / 第一人称摄影机架构。
  • godot-3d-lighting — 精灵变为受光照影响的网格后所需的 DirectionalLight3D、阴影和环境光。
  • godot-3d-materials — 用于 QuadMesh 和 Sprite3D 美术资源迁移的 PBR/公告板/透明材质。
  • godot-3d-world-building — TileMapLayer 世界转为 3D 后所需的 GridMap、碰撞生成和 LOD。
  • godot-raycasting-queries — 点选式 3D 移植中使用的鼠标→世界 PhysicsRayQueryParameters3D 拾取。
  • godot-ui-containers — 当世界内容变为 Node3D 时仍保持 2D 的 CanvasLayer HUD。
  • godot-navigation-pathfinding — 用于投影到屏幕或游戏平面的 2.5D 桥接方案的 NavigationServer3D 路径。
  • godot-adapt-3d-to-2d — 决定是否重新压平或保留混合 2.5D 时使用的逆向适配体系。
下游 / 使用者
主技能
  • godot-master — 技能库路由器和镜像模块入口;在需要确定哪个领域技能负责跨领域 2D/3D 问题时打开。

评论

支持 Markdown