GDScript

核心

全局

_GDScript

_GDScript 类:

{
	PI: 3.14159265358979,
	TAU: 6.28318530717959
	INF: inf,
	NAN: nan,
	
	Color8(r8: int, g8: int, b8: int, a8: int = 255) -> Color,
	assert(condition: bool, message: String = "") -> void,
	char(char: int) -> String,
	convert(what: Variant, type: int) -> Variant,
	dict_to_inst(dictionary: Dictionary) -> Object,
	get_stack() -> Array,
	inst_to_dict(instance: Object) -> Dictionary,
	is_instance_of(value: Variant, type: Variant) -> bool,
	len(variable: Variant) -> int,
	load(path: String) -> Resource,
	preload(path: String) -> Resource,
vararg func print_debug() -> void,
	print_stack() -> void,
vararg func range() -> Array,
	type_exists(type: StringName) -> bool,
}
_GlobalScope

_GlobalScope 类包含一些 枚举类对象方法

{
	Side: enum
	Corner: enum
	Orientation: enum
	ClockDirection: enum
	HorizontalAlignment: enum
	VerticalAlignment: enum
	InlineAlignment: enum
	EulerOrder: enum
	Key: enum
	KeyModifierMask: enum
	MouseButton: enum
	MouseButtonMask: enum
	JoyButton: enum
	JoyAxis: enum
	MIDIMessage: enum
	Error: enum
	PropertyHint: enum
	PropertyUsageFlags: enum
	MethodFlags: enum
	Variant.Type: enum
	Variant.Operator: enum
	Side: enum
	Corner: enum
	Orientation: enum
	ClockDirection: enum
	HorizontalAlignment: enum
	VerticalAlignment: enum
	InlineAlignment: enum
	EulerOrder: enum
	Key: enum
	KeyModifierMask: enum
	MouseButton: enum
	MouseButtonMask: enum
	JoyButton: enum
	JoyAxis: enum
	MIDIMessage: enum
	Error: enum
	PropertyHint: enum
	PropertyUsageFlags: enum
	MethodFlags: enum
	
	AudioServer: AudioServer
	CameraServer: CameraServer
	ClassDB: ClassDB
	DisplayServer: DisplayServer
	EditorInterface: EditorInterface
	Engine: Engine
	EngineDebugger: EngineDebugger
	GDExtensionManager: GDExtensionManager
	Geometry2D: Geometry2D
	Geometry3D: Geometry3D
	GodotSharp: GodotSharp
	IP: IP
	Input: Input
	InputMap: InputMap
	JavaClassWrapper: JavaClassWrapper
	JavaScriptBridge: JavaScriptBridge
	Marshalls: Marshalls
	NavigationMeshGenerator: NavigationMeshGenerator
	NavigationServer2D: NavigationServer2D
	NavigationServer3D: NavigationServer3D
	OS: OS
	Performance: Performance
	PhysicsServer2D: PhysicsServer2D
	PhysicsServer2DManager: PhysicsServer2DManager
	PhysicsServer3D: PhysicsServer3D
	PhysicsServer3DManager: PhysicsServer3DManager
	ProjectSettings: ProjectSettings
	RenderingServer: RenderingServer
	ResourceLoader: ResourceLoader
	ResourceSaver: ResourceSaver
	ResourceUID: ResourceUID
	TextServerManager: TextServerManager
	ThemeDB: ThemeDB
	Time: Time
	TranslationServer: TranslationServer
	WorkerThreadPool: WorkerThreadPool
	XRServer: XRServer
	
	print() -> void,
	randi() -> int,
	
	abs(x: Variant) -> Variant,
	absf(x: float) -> float,
	absi(x: int) -> int,
	acos(x: float) -> float,
	acosh(x: float) -> float,
	angle_difference(from: float, to: float) -> float,
	asin(x: float) -> float,
	asinh(x: float) -> float,
	atan(x: float) -> float,
	atan2(y: float, x: float) -> float,
	atanh(x: float) -> float,
	bezier_derivative(start: float, control_1: float, control_2: float, end: float, t: float) -> float,
	bezier_interpolate(start: float, control_1: float, control_2: float, end: float, t: float) -> float,
	bytes_to_var(bytes: PackedByteArray) -> Variant,
	bytes_to_var_with_objects(bytes: PackedByteArray) -> Variant,
	ceil(x: Variant) -> Variant,
	ceilf(x: float) -> float,
	ceili(x: float) -> int,
	clamp(value: Variant, min: Variant, max: Variant) -> Variant,
	clampf(value: float, min: float, max: float) -> float,
	clampi(value: int, min: int, max: int) -> int,
	cos(angle_rad: float) -> float,
	cosh(x: float) -> float,
	cubic_interpolate(from: float, to: float, pre: float, post: float, weight: float) -> float,
	cubic_interpolate_angle(from: float, to: float, pre: float, post: float, weight: float) -> float,
	cubic_interpolate_angle_in_time(from: float, to: float, pre: float, post: float, weight: float, to_t: float, pre_t: float, post_t: float) -> float,
	cubic_interpolate_in_time(from: float, to: float, pre: float, post: float, weight: float, to_t: float, pre_t: float, post_t: float) -> float,
	db_to_linear(db: float) -> float,
	deg_to_rad(deg: float) -> float,
	ease(x: float, curve: float) -> float,
	error_string(error: int) -> String,
	exp(x: float) -> float,
	floor(x: Variant) -> Variant,
	floorf(x: float) -> float,
	floori(x: float) -> int,
	fmod(x: float, y: float) -> float,
	fposmod(x: float, y: float) -> float,
	hash(variable: Variant) -> int,
	instance_from_id(instance_id: int) -> Object,
	inverse_lerp(from: float, to: float, weight: float) -> float,
	is_equal_approx(a: float, b: float) -> bool,
	is_finite(x: float) -> bool,
	is_inf(x: float) -> bool,
	is_instance_id_valid(id: int) -> bool,
	is_instance_valid(instance: Variant) -> bool,
	is_nan(x: float) -> bool,
	is_same(a: Variant, b: Variant) -> bool,
	is_zero_approx(x: float) -> bool,
	lerp(from: Variant, to: Variant, weight: Variant) -> Variant,
	lerp_angle(from: float, to: float, weight: float) -> float,
	lerpf(from: float, to: float, weight: float) -> float,
	linear_to_db(lin: float) -> float,
	log(x: float) -> float,
	max() -> Variant,
	maxf(a: float, b: float) -> float,
	maxi(a: int, b: int) -> int,
	min() -> Variant,
	minf(a: float, b: float) -> float,
	mini(a: int, b: int) -> int,
	move_toward(from: float, to: float, delta: float) -> float,
	nearest_po2(value: int) -> int,
	pingpong(value: float, length: float) -> float,
	posmod(x: int, y: int) -> int,
	pow(base: float, exp: float) -> float,
	print_rich() -> void,
	print_verbose() -> void,
	printerr() -> void,
	printraw() -> void,
	prints() -> void,
	printt() -> void,
	push_error() -> void,
	push_warning() -> void,
	rad_to_deg(rad: float) -> float,
	rand_from_seed(seed: int) -> PackedInt64Array,
	randf() -> float,
	randf_range(from: float, to: float) -> float,
	randfn(mean: float, deviation: float) -> float,
	randi_range(from: int, to: int) -> int,
	randomize() -> void,
	remap(value: float, istart: float, istop: float, ostart: float, ostop: float) -> float,
	rid_allocate_id() -> int,
	rid_from_int64(base: int) -> RID,
	rotate_toward(from: float, to: float, delta: float) -> float,
	round(x: Variant) -> Variant,
	roundf(x: float) -> float,
	roundi(x: float) -> int,
	seed(base: int) -> void,
	sign(x: Variant) -> Variant,
	signf(x: float) -> float,
	signi(x: int) -> int,
	sin(angle_rad: float) -> float,
	sinh(x: float) -> float,
	smoothstep(from: float, to: float, x: float) -> float,
	snapped(x: Variant, step: Variant) -> Variant,
	snappedf(x: float, step: float) -> float,
	snappedi(x: float, step: int) -> int,
	sqrt(x: float) -> float,
	step_decimals(x: float) -> int,
	str() -> String,
	str_to_var(string: String) -> Variant,
	tan(angle_rad: float) -> float,
	tanh(x: float) -> float,
	type_convert(variant: Variant, type: int) -> Variant,
	type_string(type: int) -> String,
	typeof(variable: Variant) -> int,
	var_to_bytes(variable: Variant) -> PackedByteArray,
	var_to_bytes_with_objects(variable: Variant) -> PackedByteArray,
	var_to_str(variable: Variant) -> String,
	weakref(obj: Variant) -> Variant,
	wrap(value: Variant, min: Variant, max: Variant) -> Variant,
	wrapf(value: float, min: float, max: float) -> float,
	wrapi(value: int, min: int, max: int) -> int,
}

注释 => @export, @export_category()

节点

  • Node3D, CanvasItem < Node < Object
  • Node2D, Control < CanvasItem
    注:Node2D 用于 2d,Node3D 用于 3d,Control 用于 UI
  • Sprite3D < GeometryInstance3D < VisualInstance3D < Node3D
  • Sprite2D, AnimatedSprite2D, Camera2D < Node2D
  • CollisionObject2D, CollisionShape2D, CollisionPolygon2D < Node2D
  • PhysicsBody2D, Area2D < CollisionObject2D
  • CharacterBody2D, RigidBody2D < PhysicsBody2D
  • Label < Control
    注:CollisionObject2D 需要子节点 CollisionShape2DCollisionPolygon2D 来描述其形状
    注2:AnimatedSprite2Dsprite_frames 应为一个 SpriteFrames 实例

Object 类:

{
	_init() -> void,
	emit_signal(signal: StringName) -> int,
}

Node < Object 类:

{
	_ready() -> void,
	// 每一帧都会调用一次
	// @delta -> 自上一帧以来经过的时间(s)
	_process(delta: float) -> void,
	// 按下按键时调用
	_unhandled_input(event: InputEvent) -> void,
	
	// 设置是否启用 _process() 钩子
	set_process(enable: bool) -> void,
	// _process() 钩子是否已启用
	is_processing() -> bool,
	
	// 注:`$node_path` 是 get_path('node_path') 的语法糖
	get_node(path: NodePath) -> Node,
	
	// 
	queue_free() -> void,
	// 获取场景树
	get_tree() -> SceneTree,
	// 添加子节点
	add_child(node: Node, force_readable_name: bool = false, internal: int = 0) -> void,
	// 添加兄弟节点
	add_sibling(sibling: Node, force_readable_name: bool = false) -> void,
}

CanvasItem < Node 类:

{
	visible: bool,
	
	get_viewport_rect() -> Rect2,
	
	show() -> void,
	hide() -> void,
}

Node2D < CanvasItem 类:

{
	// 节点的位置向量
	position: Vector2,
	// 顺时针旋转角(一个 PI 为一周)
	rotation: float,
}

注:Node2D 的属性是响应式的,即与前端行为绑定

碰撞对象

CollisionObject2D 类:

{
	collision_layer: int,
	collision_mask: int,
	collision_priority: float,
}

RigidBody2D < PhysicsBody2D < CollisionObject2D 类:

{
	mass: float,
	gravity_scale: float,
	// 线速度(pixels/帧)
	linear_velocity: Vector2,
}
碰撞体积
精灵

AnimatedSprite2D < Node2D 类:

{
	area_entered(area: Area2D): signal,
	area_exited(area: Area2D): signal,
	// RigidBody2D 等实例碰撞
	body_entered(body: Node2D): signal,
	body_exited(body: Node2D): signal,
	area_shape_entered(area_rid: RID, area: Area2D, area_shape_index: int, local_shape_index: int): signal,
	area_shape_exited(area_rid: RID, area: Area2D, area_shape_index: int, local_shape_index: int): signal,
	body_shape_entered(body_rid: RID, body: Node2D, body_shape_index: int, local_shape_index: int): signal,
	body_shape_exited(body_rid: RID, body: Node2D, body_shape_index: int, local_shape_index: int): signal,
	
	sprite_frames: SpriteFrames,
}
ui

CanvasItem, CanvasLayer < Node

CanvasLayer 类:

{
	
}

Control < CanvasItem 类:

{
	set_anchors_preset(preset: int, keep_offsets: bool = false) -> void,
	size: Vector2,
}

Label < Control 类:

{
	text: String,
	horizontal_alignment: int,
	vertical_alignment: int,
	autowrap_mode: int,
}

BaseButton < Control 类:

{
	// 按钮快捷键(可触发 pressed 信号)
	shortcut: Shortcut,
}

Button < BaseButton 类:

{
	text: String,
}

ColorRect < Control 类:

{
	color: Color
}

TextureRect < Control 类:

常见

Path2D < Node2D 类:

{
	curve: Curve2D
}

PathFollow2D < Node2D 类:

{
	h_offset: float,
	v_offset: float,
	loop: bool,
	progress: float,
	// 当前实例在 Path2D 父级中的相对坐标,范围在 0..1 内
	progress_ratio: float,
	rotates: bool,
}

注:Path2D 实例必须是 PathFollow2D 实例的才能发挥作用

Timer < Node 类:

{
	// 超时的信号
	timeout: Signal,
	
	process_callback: int,
	wait_time: float,
	one_shot: bool,
	autostart: bool,
	
	paused: bool,
	time_left: float,
}

AudioStreamPlayer < Node 类:

资源类

  • Resource < RefCounted < Object
  • PhysicsMaterial, SpriteFrames, InputEvent, Curve2D < Resource

PhysicsMaterial < Resource 类:

{
	absorbent: bool,
	bounce: float,
	friction: float,
	rough: bool
}

Curve2D < Resource 类:

{
	bake_interval: float,
	point_count: int
}

PackedScene < Resource 类:

{
	
}

JSON 类:

{
	// 渲染 json
	static stringify(data: Variant, indent: String = "", sort_keys: bool = true, full_precision: bool = false) -> Stri1ng,
	// 解析 json
	static parse_string(json_string: String) -> Variant,
}

Texture2D < Texture < Resource

设备输入

Shortcut < Resource 类:

{
	events: Array,
}

InputEvent < Resource 类:

{
	device: int,
}

InputEventAction < InputEvent

触摸事件 => InputEventScreenTouch, InputEventScreenDrag

变量类型

Variant
=> 例子:var my_variant = something

String, Color, Array

信号

signal 关键字用于定义信号

Signal 类:

{
	// 将当前信号连接到一个方法
	connect(callable: Callable, flags: int = 0) -> int,
	// 取消一个连接
	disconnect(callable: Callable) -> void,
	// 触发信号
	emit() -> void,
}
向量

Vector2 类:

{
	x: float,
	y: float,
	
	// 得到旋转变换后端向量
	rotated(angle: float): Vector2,
	// 得到单位向量
	normalized() -> Vector2,
	is_normalized() -> bool,
}
几何

Rect2 类:

{
	size: Vector2
}

编辑器

其他对象

SceneTree < MainLoop < Object 类:

{
	create_timer(time_sec: float, process_always: bool = true, process_in_physics: bool = false, ignore_time_scale: bool = false) -> SceneTreeTimer,
	// 对某个分组内的节点均执行某个方法
	call_group(group: StringName, method: StringName) -> void,
}

SceneTreeTimer < RefCounted < Object 类:

{
	timeout: signal,
}

FileAccess < RefCounted 类:

{
	
}

实践

Node2D 实例的旋转前进

  • Node -> _process()
  • Node2D -> rotation, position
  • Vector2 -> UP, rotated()
  • _GDScript -> PI
extends Sprite2D

var angle_speed = PI
var forward_speed = 400

func _process(delta: float) -> void:
	rotation += delta * angle_speed
	position += delta * Vector2.UP.rotated(rotation) * forward_speed

根据方向键进行移动

  • Node -> _process()
  • _GlobalScope -> Input
  • Input -> is_action_pressed()

例子1 => “汽车式”移动:

var angle_speed = PI
var forward_speed = 400

func _process(delta: float) -> void:
	if Input.is_action_pressed('ui_left'):
		rotation -= delta * angle_speed
	if Input.is_action_pressed('ui_right'):
		rotation += delta * angle_speed
	if Input.is_action_pressed('ui_up'):
		position += delta * Vector2.UP.rotated(rotation) * forward_speed  
	if Input.is_action_pressed('ui_down'):  
	    position += delta * Vector2.DOWN.rotated(rotation) * forward_speed
	
	# 防止越界
	position = position.clamp(Vector2.LEFT, get_viewport_rect().size)

注:项目->项目设置->输入映射 可用配置与按键的映射

其他可用的模块:

  • Node -> _unhandled_input()
  • InputEvent

例子2 => “四相邻”移动:

func _process(delta: float) -> void:
	var vec: Vector2 = Vector2.ZERO
	if Input.is_action_pressed('ui_left'):
		vec += Vector2.LEFT
	elif Input.is_action_pressed('ui_right'):
		vec += Vector2.RIGHT
	elif Input.is_action_pressed('ui_up'):
		vec += Vector2.UP
	elif Input.is_action_pressed('ui_down'):
		vec += Vector2.DOWN
	
	position += delta * vec * 400

例子3 => 全方向移动(恒速/非恒速):

func _process(delta: float) -> void:
	var vec: Vector2 = Vector2.ZERO
	
	if Input.is_action_pressed('ui_left'):
		vec += Vector2.LEFT
	if Input.is_action_pressed('ui_right'):
		vec += Vector2.RIGHT
	if Input.is_action_pressed('ui_up'):
		vec += Vector2.UP
	if Input.is_action_pressed('ui_down'):
		vec += Vector2.DOWN
	
	# 非恒速
	position += delta * vec * 400
	# 恒速
	position += delta * vec.normalized() * 400

信号

例子(静态声明信号) => 场景的节点内发送信号:

// example.tscn
[node name="ExampleButton" type="Button" parent="."]
[node name="ExampleSprite2D" type="Sprite2D" parent="."]

[connection signal="pressed" from="ExampleButton" to="ExampleSprite2D" method="ExampleSignalHandler"]

ExampleButton 按下按钮后,ExampleSprite2D 将调用 ExampleSignalHandler()

例子2(静态声明信号):从 godot 编辑器 右侧的 节点 面板中设置信号接收端

例子3(动态声明信号):

extends Sprite2D

func _ready() -> void:
	var timer: Timer = get_node('MyTimer')
	timer.timeout.connect(_on_timer_timeout)
	
func _on_timer_timeout():
	visible = not visible

注:Timer 实例需要 autostart = true

例子4:

signal my_signal

func _init():
    my_signal.connect(my_method)

# ...
func my_func():
	my_signal.emit()
	# 或者
	emit_signal('my_signal')

first 2d——Dodge the Creeps

素材:dodge_the_creeps_2d_assets.zip
congratulations:完成该 demo 时写下了 800 行文档

项目->项目设置->常规->显示->窗口 将屏幕窗口大小改为 480x720
=> 将 拉伸->模式 设为 canvas_items,将 拉伸->比例 设为 keep

涉及的场景 => Main -> Player, Mob, HUD

Player =>

first3d——Squash the Creep

代码规范