godot-project-templates

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Project Templates

项目模板

Genre-specific scaffolding, AutoLoad patterns, and modular architecture define rapid prototyping.
特定游戏类型的脚手架、AutoLoad模式与模块化架构,助力快速原型开发。

Available Scripts

可用脚本

base_game_manager.gd

base_game_manager.gd

Expert AutoLoad template for game state management (pause, scene transitions, scoring).
用于游戏状态管理(暂停、场景切换、计分)的专业AutoLoad模板。

NEVER Do in Project Templates

项目模板中的绝对禁忌

  • NEVER hardcode scene paths
    get_tree().change_scene_to_file("res://levels/level_1.tscn")
    in 20 places? Nightmare refactoring. Use AutoLoad + constants OR scene registry.
  • NEVER forget AutoLoad registration — Template includes
    game_manager.gd
    but not in Project Settings? Script won't load. MUST add to Project → AutoLoad.
  • NEVER use
    get_tree().paused
    without groups
    — Pausing entire tree = pause menu also freezes. Use process mode groups (
    PROCESS_MODE_PAUSABLE
    vs
    PROCESS_MODE_ALWAYS
    ).
  • NEVER skip Input.MOUSE_MODE_CAPTURED in FPS — FPS template without mouse capture = cursor visible during gameplay. Set in player
    _ready()
    .
  • NEVER copy-paste templates as-is — Using platformer template for RPG? Leads to architectural debt. UNDERSTAND the structure, then adapt.

  • 绝对不要硬编码场景路径 — 在20个地方写
    get_tree().change_scene_to_file("res://levels/level_1.tscn")
    ?重构时会噩梦缠身。请使用AutoLoad+常量或场景注册表。
  • 绝对不要忘记注册AutoLoad — 模板包含
    game_manager.gd
    但未在项目设置中注册?脚本将无法加载。必须添加到「项目→AutoLoad」中。
  • 绝对不要在未使用分组的情况下调用
    get_tree().paused
    — 暂停整个场景树会导致暂停菜单也被冻结。请使用处理模式分组(
    PROCESS_MODE_PAUSABLE
    vs
    PROCESS_MODE_ALWAYS
    )。
  • 绝对不要在FPS模板中忽略Input.MOUSE_MODE_CAPTURED — 未设置鼠标捕获的FPS模板会导致游戏过程中光标可见。请在玩家脚本的
    _ready()
    方法中设置。
  • 绝对不要直接复制粘贴模板使用 — 用平台游戏模板开发RPG?会导致架构债务。请先理解模板结构,再进行适配。

Directory Structure

目录结构

my_platformer/
├── project.godot
├── autoloads/
│   ├── game_manager.gd
│   ├── audio_manager.gd
│   └── scene_transitioner.gd
├── scenes/
│   ├── main_menu.tscn
│   ├── game.tscn
│   └── pause_menu.tscn
├── entities/
│   ├── player/
│   │   ├── player.tscn
│   │   ├── player.gd
│   │   └── player_states/
│   └── enemies/
│       ├── base_enemy.gd
│       └── goblin/
├── levels/
│   ├── level_1.tscn
│   └── tilesets/
├── ui/
│   ├── hud.tscn
│   └── themes/
├── audio/
│   ├── music/
│   └── sfx/
└── resources/
    └── data/
my_platformer/
├── project.godot
├── autoloads/
│   ├── game_manager.gd
│   ├── audio_manager.gd
│   └── scene_transitioner.gd
├── scenes/
│   ├── main_menu.tscn
│   ├── game.tscn
│   └── pause_menu.tscn
├── entities/
│   ├── player/
│   │   ├── player.tscn
│   │   ├── player.gd
│   │   └── player_states/
│   └── enemies/
│       ├── base_enemy.gd
│       └── goblin/
├── levels/
│   ├── level_1.tscn
│   └── tilesets/
├── ui/
│   ├── hud.tscn
│   └── themes/
├── audio/
│   ├── music/
│   └── sfx/
└── resources/
    └── data/

Core Scripts

核心脚本

game_manager.gd:
gdscript
extends Node

signal game_started
signal game_paused(paused: bool)
signal level_completed

var current_level: int = 1
var score: int = 0
var is_paused: bool = false

func start_game() -> void:
    score = 0
    current_level = 1
    SceneTransitioner.change_scene("res://levels/level_1.tscn")
    game_started.emit()

func pause_game(paused: bool) -> void:
    is_paused = paused
    get_tree().paused = paused
    game_paused.emit(paused)

func complete_level() -> void:
    current_level += 1
    level_completed.emit()

game_manager.gd:
gdscript
extends Node

signal game_started
signal game_paused(paused: bool)
signal level_completed

var current_level: int = 1
var score: int = 0
var is_paused: bool = false

func start_game() -> void:
    score = 0
    current_level = 1
    SceneTransitioner.change_scene("res://levels/level_1.tscn")
    game_started.emit()

func pause_game(paused: bool) -> void:
    is_paused = paused
    get_tree().paused = paused
    game_paused.emit(paused)

func complete_level() -> void:
    current_level += 1
    level_completed.emit()

Top-Down RPG Template

俯视视角RPG模板

Directory Structure

目录结构

my_rpg/
├── autoloads/
│   ├── game_data.gd
│   ├── dialogue_manager.gd
│   └── inventory_manager.gd
├── entities/
│   ├── player/
│   ├── npcs/
│   └── interactables/
├── maps/
│   ├── overworld/
│   ├── dungeons/
│   └── interiors/
├── systems/
│   ├── combat/
│   ├── dialogue/
│   ├── quests/
│   └── inventory/
├── ui/
│   ├── inventory_ui.tscn
│   ├── dialogue_box.tscn
│   └── quest_log.tscn
└── resources/
    ├── items/
    ├── quests/
    └── dialogues/
my_rpg/
├── autoloads/
│   ├── game_data.gd
│   ├── dialogue_manager.gd
│   └── inventory_manager.gd
├── entities/
│   ├── player/
│   ├── npcs/
│   └── interactables/
├── maps/
│   ├── overworld/
│   ├── dungeons/
│   └── interiors/
├── systems/
│   ├── combat/
│   ├── dialogue/
│   ├── quests/
│   └── inventory/
├── ui/
│   ├── inventory_ui.tscn
│   ├── dialogue_box.tscn
│   └── quest_log.tscn
└── resources/
    ├── items/
    ├── quests/
    └── dialogues/

Core Systems

核心系统

inventory_manager.gd:
gdscript
extends Node

signal item_added(item: Resource)
signal item_removed(item: Resource)

var inventory: Array[Resource] = []

func add_item(item: Resource) -> void:
    inventory.append(item)
    item_added.emit(item)

func remove_item(item: Resource) -> bool:
    if item in inventory:
        inventory.erase(item)
        item_removed.emit(item)
        return true
    return false

func has_item(item_id: String) -> bool:
    for item in inventory:
        if item.id == item_id:
            return true
    return false

inventory_manager.gd:
gdscript
extends Node

signal item_added(item: Resource)
signal item_removed(item: Resource)

var inventory: Array[Resource] = []

func add_item(item: Resource) -> void:
    inventory.append(item)
    item_added.emit(item)

func remove_item(item: Resource) -> bool:
    if item in inventory:
        inventory.erase(item)
        item_removed.emit(item)
        return true
    return false

func has_item(item_id: String) -> bool:
    for item in inventory:
        if item.id == item_id:
            return true
    return false

3D FPS Template

3D FPS模板

Directory Structure

目录结构

my_fps/
├── autoloads/
│   ├── game_manager.gd
│   └── weapon_manager.gd
├── player/
│   ├── player.tscn
│   ├── player.gd
│   ├── camera_controller.gd
│   └── weapons/
│       ├── weapon_base.gd
│       ├── pistol/
│       └── rifle/
├── enemies/
│   ├── ai_controller.gd
│   └── soldier/
├── levels/
│   ├── level_1/
│   └── level_2/
├── ui/
│   ├── hud.tscn
│   └── crosshair.tscn
└── resources/
    ├── weapons/
    └── pickups/
my_fps/
├── autoloads/
│   ├── game_manager.gd
│   └── weapon_manager.gd
├── player/
│   ├── player.tscn
│   ├── player.gd
│   ├── camera_controller.gd
│   └── weapons/
│       ├── weapon_base.gd
│       ├── pistol/
│       └── rifle/
├── enemies/
│   ├── ai_controller.gd
│   └── soldier/
├── levels/
│   ├── level_1/
│   └── level_2/
├── ui/
│   ├── hud.tscn
│   └── crosshair.tscn
└── resources/
    ├── weapons/
    └── pickups/

Player Controller

玩家控制器

player.gd:
gdscript
extends CharacterBody3D

@export var speed := 5.0
@export var jump_velocity := 4.5

var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity")

@onready var camera: Camera3D = $Camera3D
@onready var weapon_holder: Node3D = $Camera3D/WeaponHolder

func _ready() -> void:
    Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

func _physics_process(delta: float) -> void:
    if not is_on_floor():
        velocity.y -= gravity * delta
    
    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = jump_velocity
    
    var input_dir := Input.get_vector("move_left", "move_right", "move_forward", "move_backward")
    var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
    
    if direction:
        velocity.x = direction.x * speed
        velocity.z = direction.z * speed
    else:
        velocity.x = move_toward(velocity.x, 0, speed)
        velocity.z = move_toward(velocity.z, 0, speed)
    
    move_and_slide()

player.gd:
gdscript
extends CharacterBody3D

@export var speed := 5.0
@export var jump_velocity := 4.5

var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity")

@onready var camera: Camera3D = $Camera3D
@onready var weapon_holder: Node3D = $Camera3D/WeaponHolder

func _ready() -> void:
    Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

func _physics_process(delta: float) -> void:
    if not is_on_floor():
        velocity.y -= gravity * delta
    
    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = jump_velocity
    
    var input_dir := Input.get_vector("move_left", "move_right", "move_forward", "move_backward")
    var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
    
    if direction:
        velocity.x = direction.x * speed
        velocity.z = direction.z * speed
    else:
        velocity.x = move_toward(velocity.x, 0, speed)
        velocity.z = move_toward(velocity.z, 0, speed)
    
    move_and_slide()

Input Map Template

输入映射模板

ini
undefined
ini
undefined

All templates should include these actions:

All templates should include these actions:

[input] move_left=Keys: A, Left, Gamepad Left move_right=Keys: D, Right, Gamepad Right move_up=Keys: W, Up, Gamepad Up move_down=Keys: S, Down, Gamepad Down jump=Keys: Space, Gamepad A interact=Keys: E, Gamepad X pause=Keys: Escape, Gamepad Start ui_accept=Keys: Enter, Gamepad A ui_cancel=Keys: Escape, Gamepad B
undefined
[input] move_left=Keys: A, Left, Gamepad Left move_right=Keys: D, Right, Gamepad Right move_up=Keys: W, Up, Gamepad Up move_down=Keys: S, Down, Gamepad Down jump=Keys: Space, Gamepad A interact=Keys: E, Gamepad X pause=Keys: Escape, Gamepad Start ui_accept=Keys: Enter, Gamepad A ui_cancel=Keys: Escape, Gamepad B
undefined

Usage

使用方法

  1. Copy template structure
  2. Rename project in
    project.godot
  3. Register AutoLoads
  4. Configure Input Map
  5. Begin development
  1. 复制模板结构
  2. project.godot
    中重命名项目
  3. 注册AutoLoad脚本
  4. 配置输入映射
  5. 开始开发

Reference

参考资料

  • GDSkills godot-project-foundations
  • GDSkills godot-project-foundations

Related

相关内容

  • Master Skill: godot-master
  • 核心技能:godot-master