Godot 基础入门语法

2026-04-28
22128 分钟
...

 

Godot 是什么

Godot 是一个游戏引擎,支持 2D、3D、UI、动画、物理、音频等开发。
它的脚本语言最常用的是 GDScript,语法风格有点像 Python,但它不是 Python。

一、第一眼要知道的几个核心概念

在 Godot 里,最重要的是这几个东西:

  • Scene(场景):一个功能模块,比如主菜单、玩家、敌人、关卡
  • Node(节点):场景里的组成单位,比如精灵、按钮、相机、角色
  • Script(脚本):给节点写逻辑
  • Signal(信号):事件机制,比如按钮点击、碰撞发生

你可以理解成:

  • Scene = 一个组件或页面
  • Node = 组件里的 DOM / 实例
  • Script = JS / TS 逻辑
  • Signal = 事件回调

二、GDScript 基础语法

1. 定义变量

var name = "hua"
var age = 18
var hp = 100
var speed = 200.5
var is_alive = true

也可以显式写类型:

var name: String = "hua"
var age: int = 18
var hp: float = 100.0
var is_alive: bool = true

也可以定义常量:

const MAX_HP = 100
const PLAYER_NAME = "Knight"

2. 输出日志

print("Hello Godot")
print("hp =", hp)

格式化字符串:

var score = 100
print("score = %d" % score)

或者:

var name = "hua"
print("hello %s" % name)

3. 注释

# 这是单行注释

4. if 条件判断

var hp = 50

if hp > 80:
    print("状态很好")
elif hp > 30:
    print("状态一般")
else:
    print("状态危险")

注意:

  • Godot 用 缩进 表示代码块
  • 结尾有 冒号 :

5. while 循环

var i = 0

while i < 5:
    print(i)
    i += 1

6. for 循环

for i in range(5):
    print(i)

输出 0 到 4。

也可以指定范围:

for i in range(2, 6):
    print(i)

输出 2 到 5。

带步长:

for i in range(0, 10, 2):
    print(i)

7. 函数定义

func say_hello():
    print("hello")

带参数:

func add(a, b):
    return a + b

带类型:

func add(a: int, b: int) -> int:
    return a + b

调用:

var result = add(2, 3)
print(result)

三、常用数据类型

1. 字符串 String

var title = "Godot"
print(title.length())
print(title.to_upper())
print(title.to_lower())

字符串拼接:

var name = "hua"
print("hello " + name)

2. 数字 int / float

var a = 10
var b = 3.5
var c = a + b

3. 布尔 bool

var is_run = true
var is_dead = false

4. 数组 Array

var arr = [1, 2, 3]
print(arr[0])  # 1

常用操作:

arr.append(4)
arr.push_back(5)
arr.remove_at(0)
print(arr.size())

遍历:

for item in arr:
    print(item)

带索引遍历:

for i in range(arr.size()):
    print(i, arr[i])

类型数组:

var nums: Array[int] = [1, 2, 3]

5. 字典 Dictionary

类似 JS 对象 / Map。

var player = {
    "name": "hua",
    "hp": 100,
    "level": 1
}

取值:

print(player["name"])
print(player["hp"])

赋值:

player["hp"] = 80

判断键是否存在:

if player.has("name"):
    print("有 name")

6. Vector2 / Vector3

游戏开发里非常常用。

Vector2

var pos = Vector2(100, 200)
var dir = Vector2(1, 0)

Vector3

var pos3 = Vector3(0, 1, 2)

常见写法:

var a = Vector2(10, 20)
var b = Vector2(5, 5)
var c = a + b
print(c)

长度:

print(a.length())

归一化:

var dir = Vector2(3, 4).normalized()

四、脚本挂载与节点基础

在 Godot 里,脚本一般是挂在某个节点上的。

例如:

extends Node2D

这表示当前脚本继承自 Node2D,所以它能操作 2D 节点的位置、旋转等。

常见继承:

extends Node
extends Node2D
extends CharacterBody2D
extends Control
extends Area2D

你可以理解成“当前脚本所属组件类型”。

五、生命周期函数

Godot 里最常用的几个函数:

1.****_ready()

节点进入场景树后执行一次。
类似初始化、mounted。

extends Node2D

func _ready():
    print("节点准备好了")

2.****_process(delta)

每一帧执行一次,适合做普通刷新逻辑。

func _process(delta):
    print("每帧执行", delta)

delta 表示距离上一帧经过的时间。

3.****_physics_process(delta)

物理帧执行,适合角色移动、碰撞相关。

func _physics_process(delta):
    print("物理帧执行")

一般角色移动优先放这里。

4.****_input(event)

处理输入事件。

func _input(event):
    if event.is_action_pressed("ui_accept"):
        print("按下确认键")

六、节点获取与操作

1. 获取子节点

var sprite = $Sprite2D

这是一种快捷写法。

等价于:

var sprite = get_node("Sprite2D")

更深层路径:

var label = get_node("CanvasLayer/Label")

2. 获取当前节点父节点

var parent = get_parent()

3. 修改节点属性

比如修改位置:

position = Vector2(100, 200)

修改子节点位置:

$Sprite2D.position = Vector2(50, 50)

隐藏显示:

$Sprite2D.visible = false
$Sprite2D.show()
$Sprite2D.hide()

4. 删除节点

queue_free()

删除当前节点。

删除别的节点:

$Enemy.queue_free()

七、输入系统

Godot 推荐通过 Input Map 配置按键,而不是写死键盘码。

比如你在项目设置里配置:

  • move_left
  • move_right
  • jump

然后脚本里这样写:

func _process(delta):
    if Input.is_action_pressed("move_left"):
        print("向左")
    
    if Input.is_action_pressed("move_right"):
        print("向右")

按下一次:

if Input.is_action_just_pressed("jump"):
    print("刚按下跳跃")

刚松开:

if Input.is_action_just_released("jump"):
    print("刚松开")

八、一个最简单的角色移动例子

这是 Godot 入门一定会写的。

extends CharacterBody2D

var speed = 200.0

func _physics_process(delta):
    var direction = Vector2.ZERO

    if Input.is_action_pressed("move_left"):
        direction.x -= 1
    if Input.is_action_pressed("move_right"):
        direction.x += 1
    if Input.is_action_pressed("move_up"):
        direction.y -= 1
    if Input.is_action_pressed("move_down"):
        direction.y += 1

    direction = direction.normalized()
    velocity = direction * speed
    move_and_slide()

这里重点理解:

  • direction:输入方向
  • normalized():防止斜向移动更快
  • velocity:角色速度
  • move_and_slide():让角色移动并处理碰撞

九、信号 Signal

信号就是 Godot 的事件系统。

比如按钮点击:

func _on_button_pressed():
    print("按钮被点击了")

这个函数一般是通过编辑器连接信号自动生成的。

也可以自己定义信号:

signal hp_changed(new_hp)

触发信号:

emit_signal("hp_changed", 80)

Godot 4 也常写成:

hp_changed.emit(80)

连接信号:

func _ready():
    hp_changed.connect(_on_hp_changed)

func _on_hp_changed(new_hp):
    print("hp 更新为", new_hp)

这个机制非常重要,后面 UI 更新、怪物死亡、任务系统都会用到。

十、预加载与实例化场景

游戏里经常需要动态生成对象,比如子弹、敌人。

1. preload

const BulletScene = preload("res://scenes/bullet.tscn")

提前加载资源。

2. 实例化

var bullet = BulletScene.instantiate()
add_child(bullet)

设置位置:

bullet.position = position

完整例子:

extends Node2D

const BulletScene = preload("res://bullet.tscn")

func shoot():
    var bullet = BulletScene.instantiate()
    bullet.position = position
    get_parent().add_child(bullet)

十一、类与面向对象基础

GDScript 支持类。

1. class_name

extends Node
class_name Player

这样这个脚本会注册成一个全局类,别的地方可以直接用 Player

2. 成员变量和函数

extends Node
class_name Player

var hp = 100

func take_damage(value):
    hp -= value

3.****_init()

构造

func _init():
    print("对象初始化")

带参数:

func _init(name: String, hp: int):
    self.name = name
    self.hp = hp

不过在场景节点开发里,更多还是依赖节点实例,而不是手动 new 很多类。

十二、导出变量

@export

这个非常重要。
它可以让变量显示在编辑器里,方便调参。

@export var speed: float = 200.0
@export var hp: int = 100

这样你在编辑器选中节点时,就能直接改 speedhp

还可以导出节点引用、资源等。

例如范围:

@export_range(0, 1000, 10) var move_speed = 200

十三、onready

有些节点要等场景准备好后才能拿到,常配合 @onready 使用。

@onready var sprite = $Sprite2D
@onready var label = $CanvasLayer/Label

这样 _ready() 前就能安全拿到引用。

例如:

extends Node2D

@onready var sprite = $Sprite2D

func _ready():
    sprite.rotation = 1.0

十四、常见判断与语法糖

1. 三元表达式

var result = "大于10" if score > 10 else "小于等于10"

2. 判空

if target != null:
    print("有目标")

3. 逻辑运算

if hp > 0 and is_alive:
    print("还能行动")

if hp <= 0 or not is_alive:
    print("已经不能行动")

十五、常用内置函数

1. 随机数

Godot 4 一般这样:

var num = randi()
var f = randf()

范围随机:

var n = randi_range(1, 10)
var f = randf_range(0.0, 1.0)

2. 取绝对值、夹紧

var a = abs(-10)
var b = clamp(150, 0, 100)

3. 类型转换

var a = int(3.8)
var b = float(10)
var c = str(123)

十六、数组和字典的实战例子

1. 背包数组

var items = ["sword", "shield", "potion"]

func add_item(item_name: String):
    items.append(item_name)

2. 玩家属性字典

var player_data = {
    "name": "hero",
    "hp": 100,
    "mp": 50
}

func take_damage(damage: int):
    player_data["hp"] -= damage
    print(player_data["hp"])

十七、一个完整入门示例

下面给你一个比较像正式项目的入门写法:

extends CharacterBody2D

@export var speed: float = 200.0
@export var max_hp: int = 100

var hp: int = 100

@onready var sprite = $Sprite2D
@onready var hp_label = $CanvasLayer/HpLabel

func _ready():
    hp = max_hp
    update_hp_ui()

func _physics_process(delta):
    var direction = Vector2.ZERO

    if Input.is_action_pressed("move_left"):
        direction.x -= 1
    if Input.is_action_pressed("move_right"):
        direction.x += 1
    if Input.is_action_pressed("move_up"):
        direction.y -= 1
    if Input.is_action_pressed("move_down"):
        direction.y += 1

    direction = direction.normalized()
    velocity = direction * speed
    move_and_slide()

func take_damage(value: int):
    hp -= value
    hp = clamp(hp, 0, max_hp)
    update_hp_ui()

    if hp <= 0:
        die()

func update_hp_ui():
    hp_label.text = "HP: %d" % hp

func die():
    print("角色死亡")
    queue_free()

这个脚本里面已经包含了:

  • 导出变量
  • onready 获取节点
  • _ready
  • _physics_process
  • 输入控制
  • UI 更新
  • 血量处理
  • 销毁节点

你看懂这个,就已经能开始做一个非常基础的小项目了。

十八、Godot 新手最容易犯的错误

1. 忘了缩进

GDScript 和 Python 一样很依赖缩进。

错误:

if true:
print("hello")

正确:

if true:
    print("hello")

2. 节点路径写错

$Sprite2D

前提是场景里真的有这个节点名。

3. 在**_process**里做物理移动

角色移动一般建议放在:

func _physics_process(delta):

而不是 _process

4. 没有在 Input Map 配置动作

你代码里写:

Input.is_action_pressed("jump")

但是项目设置里没加 jump,就不会生效。

5. 把 GDScript 当 Python 用

它像 Python,但不是 Python。
有些语法类似,但 Godot 的 API、装饰器、节点系统都是自己的。

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
godot2026-07-27
Godot 4 常用 UI 节点详解
Godot 4 常用 UI 节点详解 在 Godot 4 中,UI 系统基于 Control(控件) 节点构建。所有 UI 节点都继承自 Control,形成一棵完整的 UI 树。与游戏引擎中常见的"Canvas + DOM"模式不同,Godot 的 UI 系统是声明式的——你在场景中搭好节点树,引擎自动完成布局计算。 一、布局系统:Container 家族 Container 是 Godot UI 的 骨架 。它决定了子节点的大小和位...
学习
godot2026-07-09
Godot 4 自动地形系统(AutoTileSet / Terrains)完全指南
前言 在 2D 游戏开发中,地形瓦片(tile)的拼接是一个绕不开的问题。想象一下:你有一片草地、一条河流、一段平台——如果每一块边缘、角落、过渡区域都要手动选择对应的瓦片图,工作量将是巨大的。 自动地形系统 就是为了解决这个问题而生的。 一、什么是自动地形(Autotiling)? 自动地形的核心思想很简单: 你只管画,引擎帮你选对瓦片 。 当你在 TileMap 上绘制地形时,引擎会自动检测每个瓦片的上下左右邻居,然后根据预设的规则...
学习
godot2026-06-25
Godot 中 zindex 和 ysort 的区别总结
在 Godot 2D 游戏开发中,角色、树木、怪物、地面、技能特效、UI 都需要正确的显示顺序。比如角色走到树前面时,角色应该挡住树;角色走到树后面时,树又应该挡住角色。 这种显示顺序主要和两个概念有关: 和 。 其中 用来手动控制图层顺序, 用来根据物体的 Y 坐标自动排序。 一句话理解 是手动分层。 是根据 Y 坐标自动排序。 简单来说: | 属性 | 作用 | 适合场景 | | | | | | | 数值越大,显示越靠前 | 地面、...
学习
godot2026-06-11
Tileset 资源图的标准和规范
一、什么是 Tileset 资源图 Tileset,中文通常叫“图块资源图”或“瓦片图”,是 2D 游戏中非常常见的一种地图资源组织方式。 简单来说,Tileset 就是把很多小图块按照固定尺寸排列在一张图片里。游戏引擎会按照固定的格子大小去切割这张图片,然后把每个小格子当成一个独立的地图块使用。 比如一个 32×32 像素的 Tileset 中,每一个 tile 都是 32×32 像素。地图编辑器或游戏引擎会按照 32×32 的网格,...
学习
godot2026-05-29
用户角色精灵图制作角色的完整流程
在 2D RPG 游戏里,角色通常不是用一张单独图片完成的,而是用一张“角色精灵图”来做。 所谓角色精灵图,通常是一张包含多个动作帧的大图。比如角色向下走有 4 帧,向左走有 4 帧,向右走有 4 帧,向上走有 4 帧。Godot 会根据这些帧不断切换图片,看起来角色就动起来了。 这篇文章主要介绍:拿到一张角色精灵图之后,如何在 Godot 中把它做成一个可以正常移动、播放动画、和地图产生遮挡关系的角色。 一、先理解角色精灵图是什么 角...
学习
godot2026-05-26
Godot 节点系统详细介绍
Godot 里最核心的东西不是“类”,也不是“组件”,而是 节点 Node 。 你可以把 Godot 的节点理解成: 在前端里,一个页面是由很多 DOM 元素组成的; 在 Godot 里,一个游戏场景是由很多 Node 节点组成的。 比如一个玩家角色,可能不是一个单独对象,而是这样的结构: 这里的 是根节点,下面挂着显示图片、播放动画、碰撞检测、摄像机、音效等子节点。 Godot 官方文档也把节点和场景放在一起讲:多个节点组成树状结构后...
学习

评论

请登录后发表评论

去登录
加载评论中...

目录