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

godot-adapt-3d-to-2d

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

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

帮助 Godot 开发者将 3D 游戏机制迁移到 2D 或 2.5D 的技能,提供高度模拟、深度排序、命中深度检查和模型转精灵等脚本模式。

主要功能

  1. 012.5D 高度与跳跃模拟
  2. 02地面与空中命中检查
  3. 03Y 轴深度排序
  4. 04等距投影数学工具
  5. 053D 模型转精灵烘焙

适用场景

  1. 01将 3D 角色控制器改为 2D
  2. 02在 2.5D 中区分空中与地面攻击
  3. 03为俯视游戏模拟跳跃高度
  4. 04从 3D 模型烘焙多角度精灵

安装

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

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

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

包含的文件

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

references/
dimension-reduction.md
migration-notes.md
scripts/
2d_lighting_normals.gd
adapt_3d_to_2d_patterns.gd
billboard_sprite_manager.gd
depth_sorting_y_sort.gd
directional_sprite_resolver.gd
fake_3d_shadows.gd
grid_nav_bridge.gd
hitbox_depth_manager.gd
isometric_math_core.gd
jump_z_axis_sim.gd
model_to_sprite_bake.gd
nav_region_flattening.gd
ortho_simulation.gd
ortho_to_perspective_fx.gd
parallax_depth_camera.gd
projection_utils.gd

详细介绍

绝对不要做的事

  • 绝对不要在没有玩法补偿的情况下移除 Z 轴——盲目地将 3D 压平为 2D 会移除空间策略。请添加其他深度机制(图层、不同的跳跃高度)。
  • 绝对不要保留 3D 碰撞形状——使用更简单的 2D 形状(CapsuleShape2D、RectangleShape2D)。3D 形状不会自动转换。
  • 绝对不要将正交 Camera3D 当作“2D 模式”使用——原因:你仍需承担 3D 变换和光照开销,还会错过 CanvasItem 批处理。请使用 Camera2D + 2D 节点(ortho_simulation.gd 仅用于模拟高度)。
  • 绝对不要假设性能会自动提升——优化不佳的 2D(绘制调用过多、精灵图集过大)可能比优化良好的 3D 更慢。
  • 绝对不要忘记调整重力——3D 重力是 Vector3(0, -9.8, 0)。2D 重力是浮点数(980 像素/秒²)。请按比例调整。
  • 绝对不要将地面和空中攻击视为相同的 Area2D 重叠——在 2.5D 中,地面斩击不能命中跳跃中的目标。原因:2D 物理没有 Z 轴。请使用 hitbox_depth_manager.gd 进行高度 AABB 检查。
  • 绝对不要用每个精灵上的 z_index 滥用来对抗 Y 排序——原因:排序顺序应由执行 Y 排序的父节点负责。请使用 depth_sorting_y_sort.gd;手动设置的 z_index 每帧都会偏移。

可用脚本

必须执行:实现相应模式前,请先阅读对应脚本。

策略路由器(必须 / 不要加载)
策略加载不要加载
纯 2D(移除 Z)仅当平台跳跃游戏仍需高度时加载 jump_z_axis_sim.gd;否则使用 CharacterBody2D 模式ortho_simulation.gd、等距数学、假阴影
2.5D / 假深度必须 ortho_simulation.gd + jump_z_axis_sim.gd + hitbox_depth_manager.gd + depth_sorting_y_sort.gd(+ parallax_depth_camera.gd / fake_3d_shadows.gd)手动滥用 z_index = int(y);将正交 Camera3D 当作 2D
保持等距必须 isometric_math_core.gd + depth_sorting_y_sort.gd仅笛卡尔坐标速度示例;用 Camera3D 正交投影伪装
将 3D 烘焙为精灵必须 model_to_sprite_bake.gd(Doom 风格还需 billboard_sprite_manager.gd)正文中的 Blender 烘焙步骤
仅转换节点/物理使用下方的决策树 + 重力/碰撞说明策略代码示例;未经审核的 Dimensional Patcher 正则表达式
ortho_simulation.gd

在 2D 俯视游戏中模拟 3D Z 轴高度。处理垂直速度、重力、精灵偏移和阴影缩放。

projection_utils.gd

将 3D 世界位置投影到 2D 屏幕空间,用于名牌、生命条和目标定位。处理相机后方检测和基于距离的缩放。

isometric_math_core.gd

专家级工具,可在不使用 2D Node 变换的情况下生成二维笛卡尔坐标与真正的等距屏幕空间投影矩阵之间的转换。

depth_sorting_y_sort.gd

专家级动态 Z-index Y 排序脚本,用于对独立树进行假 3D 排序,与 CanvasItem 的 _update_sorting() 相匹配。

jump_z_axis_sim.gd

完整的 CharacterBody2D 代码片段,将俯视游戏中的结构性物理地面移动(X、Y)与通过数学方式模拟的跳跃高度(Z)分离。

parallax_depth_camera.gd

假深度相机,根据索引对完全独立的 CanvasLayers 应用不同的偏移算法,以模拟 3D 相机平移。

hitbox_depth_manager.gd

派生自 Area2D 的类,在验证 2D 触发器前要求显式检查自定义 Z 高度重叠(1D AABB 碰撞),以避免 2.5D 中错误的“地面与空中”碰撞。

fake_3d_shadows.gd

Sprite2D 阴影模拟器,利用 Godot 4.x 的 Transform2D 矩阵倾斜剪切,将阴影投射到 2D 地面上,并使其远离模拟的 3D 光照方向。

billboard_sprite_manager.gd

8 方向的 FPS Doom 风格精灵控制器,用于隔离移动的 2D CharacterBody 与 Camera2D 视角之间模拟的 3D 相对角度。

nav_region_flattening.gd

俯视 2D 寻路变通方案:利用多个分层的 2D Navigation Layer,而不是正确实现 3D 垂直空间,让“空中”单位能够穿过墙壁。

ortho_to_perspective_fx.gd

屏幕空间 CanvasItem 扭曲 Shader,用于模拟 Mode 7/桌面式透视倾斜。通过除法收窄顶部屏幕坐标。

2d_lighting_normals.gd

在运行时自动以程序方式生成结合基础反照率与烘焙法线贴图的 CanvasTexture,使精灵能够像 3D 几何体一样正确响应 2D PointLIGHT。

model_to_sprite_bake.gd

通过 SubViewport 自动烘焙 3D→精灵角度时必须使用。将主体保留为策略路由器。

grid_nav_bridge.gd

将 3D 导航意图映射到 AStarGrid2D,供基于网格的 2D 移植使用(XZ → 单元格索引)。


降维策略

从上方的策略路由器中选择一行——不要在场景中粘贴转换教程。

策略意图脚本
真正的 2D移除 Z;使用 Vector2 速度;Camera2D同级项目 godot-characterbody-2d / godot-camera-systems
2.5D/伪深度模拟高度 + Y-sort 所有权 + 地面与空中碰撞箱ortho_simulation.gd、jump_z_axis_sim.gd、hitbox_depth_manager.gd、depth_sorting_y_sort.gd
保留等距视角2D 物理 + 等距投影必须使用 isometric_math_core.gd

重力缩放:3D 9.8 m/s² → 2D ~980 px/s²(当 1 m ≈ 100 px 时)。碰撞:CapsuleShape3D → CapsuleShape2D(参见“物理调整”)。摄像机:Camera3D/SpringArm → Camera2D——绝不要将正交 Camera3D 当作“2D 模式”。


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

从 GLB/场景烘焙多角度精灵时必须使用:model_to_sprite_bake.gd(@tool SubViewport 烘焙器)。 手动 Blender 导出应在此技能之外进行。策略选择应在下方决策树中完成——不要在正文中重复插入烘焙步骤。


物理调整

重力缩放
# 3D gravity (m/s²): 9.8
# 2D gravity (pixels/s²): Scale to pixel units

# If 1 meter = 100 pixels:
const GRAVITY_2D = 9.8 * 100  # = 980 pixels/s²

# Adjust jump velocity proportionally:
# 3D jump: 4.5 m/s
# 2D jump: -450 pixels/s
碰撞简化
# 3D: CapsuleShape3D (16 segments, expensive)
var shape_3d := CapsuleShape3D.new()
shape_3d.radius = 0.5
shape_3d.height = 2.0

# 2D: CapsuleShape2D (much simpler)
var shape_2d := CapsuleShape2D.new()
shape_2d.radius = 16  # pixels
shape_2d.height = 64

控制简化

3D 自由移动 → 2D 受限移动
# 3D: Full 3D movement with camera-relative controls
var input_3d := Input.get_vector("left", "right", "forward", "back")
var camera_basis := camera.global_transform.basis
var direction := (camera_basis * Vector3(input_3d.x, 0, input_3d.y)).normalized()

# 2D: Simple 4-direction (or 8-direction with diagonals)
var input_2d := Input.get_vector("left", "right", "up", "down")
velocity = input_2d.normalized() * SPEED

性能提升

优化技术
# 1. Use TileMapLayer instead of individual Sprite2D nodes
var tilemap := TileMapLayer.new()
tilemap.tile_set = load("res://tileset.tres")

# 2. Batch sprite rendering
# Use single large sprite sheet instead of individual textures

# 3. Reduce particle count
var godot-particles := GPUParticles2D.new()
godot-particles.amount = 50  # Down from 200 in 3D

UI 适配

# Most 3D games already use 2D UI (CanvasLayer)
# No changes needed!

# Just verify UI scaling for new aspect ratios
get_viewport().size_changed.connect(_on_viewport_resized)

func _on_viewport_resized() -> void:
    var viewport_size := get_viewport().get_visible_rect().size
    # Adjust UI anchors/margins

边缘情况

深度排序

绝不要使用每个精灵的 z_index = int(global_position.y) 来驱动排序——这与 Y-sort 所有权相矛盾。必须使用 depth_sorting_y_sort.gd:在父节点上启用 y_sort_enabled,并让子节点保持默认的相对 z 值。

空间音频丢失
# 3D spatial audio (AudioStreamPlayer3D) → 2D panning (AudioStreamPlayer2D)

var audio_2d := AudioStreamPlayer2D.new()
audio_2d.stream = load("res://sounds/footstep.ogg")
audio_2d.max_distance = 1000.0  # 2D range
audio_2d.attenuation = 2.0
add_child(audio_2d)

决策树:何时简化为 2D

因素保留 3D转为 2D
目标平台桌面端、主机移动端、Web
美术风格写实、沉浸式风格化、复古
游戏玩法需要 3D 空间可在 2D 平面中运行
性能GPU 预算充足需要在低端设备上达到 60 FPS
团队技能3D 美术师2D 美术师或像素美术

专家技巧与优化

1. 扁平化导航(3D 导航网格转 2D 网格)

虽然 Godot 将 2D 和 3D 导航视为独立系统,但你可以使用 AStarGrid2D 将 3D 寻路逻辑投影到 2D 网格上。这针对基于 2D 网格的移动进行了高度优化,并避免了完整 3D 导航网格带来的额外开销。

class_name GridNavBridge extends Node

var astar_grid: AStarGrid2D

func _ready() -> void:
    astar_grid = AStarGrid2D.new()
    astar_grid.region = Rect2i(0, 0, 100, 100)
    astar_grid.cell_size = Vector2(16, 16)
    astar_grid.update()

## Converts a 3D target position to a 2D grid path.
func get_grid_path_from_3d(start_3d: Vector3, end_3d: Vector3) -> PackedVector2Array:
    var start_map := Vector2i(start_3d.x / 16, start_3d.z / 16)
    var end_map := Vector2i(end_3d.x / 16, end_3d.z / 16)
    
    return astar_grid.get_point_path(start_map, end_map)
2. 2D 自动 LOD(性能优化)

自动 LOD 原本是 3D 功能,但可以使用 VisibleOnScreenEnabler2D 在 2D 中模拟。此节点会在目标节点(如高分辨率精灵或复杂 AI)离开屏幕时,自动切换其 process_mode,从而节省 CPU 周期并降低 GPU 填充率。

# Attach to a complex 2D entity
func setup_2d_lod(target_node: Node2D) -> void:
    var enabler := VisibleOnScreenEnabler2D.new()
    # Define the 'high-detail' rect
    enabler.rect = Rect2(-64, -64, 128, 128) 
    enabler.enable_node_path = target_node.get_path()
    add_child(enabler)
3. 维度转换补丁(CharacterBody3D 到 2D 的正则表达式)

若要自动将 3D 控制器降级移植到 2D,可使用 RegEx 脚本将 Vector3 映射为 Vector2,并替换特定于 3D 的属性。对于大规模移植任务,这一点至关重要,因为手动转换移动逻辑容易出错。

@tool
extends EditorScript

func _run() -> void:
    var regex = RegEx.new()
    # Pattern to find Vector3 constructors and replace with Vector2
    regex.compile("Vector3\\(([^,]+),\\s*([^,]+),\\s*([^)]+)\\)")
    
    var script_content = "velocity = Vector3(input.x, 0.0, input.y) * speed"
    var result = regex.sub(script_content, "Vector2($1, $3)", true)
    
    # Output: "velocity = Vector2(input.x, input.y) * speed"
    print(result)

深入方案(按需查阅)

主题参考资料 / 脚本
真正的 2D / 烘焙 / 摄像机转换dimension-reduction.md

参考资料

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

官方文档
  • 2D 简介 — 介绍 CanvasItem/Camera2D 渲染流程;从 Node3D 渲染切换到真正的 2D 性能时,必须转而使用此流程。
  • 使用 CharacterBody2D — 将 CharacterBody3D 转换为 CharacterBody2D 后,move_and_slide / 地面 / 跳跃的标准模式。
  • 物理简介 — 单位、层 / 遮罩,以及重力变为 2D 标量时,3D 重力 / Vector3 假设失效的原因。
  • 2D 变换 — 用于等距放置和模拟投影阴影的 Transform2D 基向量 / 倾斜数学。
  • 2D 视差 — 当游戏玩法压缩到一个平面时,用于替代 Z 轴深度的图层滚动比例。
  • 画布图层 — 叠加多个 CanvasLayer,打造模拟深度的摄像机,无需保留正交 Camera3D。
  • 2D 光照与阴影 — 使用法线贴图的 CanvasTexture / Light2D 流程,在精灵上还原 3D 风格的光照。
  • 导航简介(2D) — 使用 2D 导航区域 / 图层,将垂直 3D 寻路扁平化为分层的 2D Agent。
  • 使用视口 — 将 3D 模型捕获到 Sprite2D 纹理中的 SubViewport(运行时或烘焙流程)。
  • Camera2D — 缩放、限制和跟随 API,应以此替代“将正交 Camera3D 用作 2D 模式”。
  • CanvasItem — 失去真实 Z 轴后用于深度排序的 y_sort_enabled / z_index / z_as_relative。
  • 常规优化 — 提醒你:只有实际减少绘制调用、过度绘制和处理开销,2D 才能带来性能优势。
相关技能
前置条件
  • godot-characterbody-2d — 一旦模拟或移除 Z 轴,即可用于俯视角/平台游戏移植的目标移动 API。
  • godot-2d-physics — 移除 3D 形状后,使用 CapsuleShape2D/Area2D 简化碰撞并设置图层遮罩。
  • godot-camera-systems — 使用 Camera2D 跟随、限制和缩放,避免移植时继续使用伪正交 Camera3D。
  • godot-gdscript-mastery — 类型化的 Vector2/Transform2D 数学运算和工具脚本,贯穿各类降维辅助工具。
补充
  • godot-2d-animation — 将 3D 模型烘焙为方向帧后,使用精灵表/AnimatedSprite2D 工作流。
  • godot-shaders-basics — 用于 Mode-7/透视倾斜以及其他屏幕空间深度假象的 CanvasItem 着色器。
  • godot-tilemap-mastery — TileMapLayer 批处理,常用于在 2D 移植中替代单个 3D 网格实例。
  • godot-navigation-pathfinding — 将空中/垂直路线压平时,使用更深入的 2D 导航网格/AStarGrid2D 模式。
  • godot-audio-systems — 空间音频失效后,将 AudioStreamPlayer3D 替换为 AudioStreamPlayer2D,并设置声像/衰减。
  • godot-adapt-2d-to-3d — 反向适配矩阵,用于决定移植时保留或反转哪个轴。
下游/使用方
主索引
  • godot-master — 技能库路由器和镜像模块入口;查找哪个领域技能负责跨领域 2D/3D 问题时可打开此项。

评论

支持 Markdown