GDScript Spickzettel
Zuletzt aktualisiert
Grundlagen und Ausgabe
Ein Skript erweitert einen Node-Typ, und Godot ruft seine Funktionen für dich auf.
| Operation | Syntax |
|---|---|
| Skript an einen Node-Typ hängen | extends Node |
| Code, der beim Start des Nodes läuft | func _ready() -> void:
print("Hello, World!") |
| Werte ohne Trennzeichen ausgeben | print("HP: ", hp) |
| Werte durch Leerzeichen getrennt ausgeben | prints("a", "b", 3) |
| Kommentar | # This is a comment |
| Dokumentationskommentar | ## Shown in the editor's help |
| Mehrzeiliger String | var text := """Line one
Line two""" |
| Fehler melden | push_error("Health is negative") |
| Warnung melden | push_warning("Old save file") |
Variablen, Konstanten und Typen
Typen sind optional. Füge sie für Editor-Prüfungen, Autovervollständigung und schnelleren Code hinzu.
| Operation | Syntax |
|---|---|
| Variable (dynamischer Typ) | var score = 0 |
| Variable mit statischem Typ | var speed: float = 200.0 |
| Statischen Typ ableiten | var lives := 3 |
| Konstante | const MAX_HP = 100 |
| Enum | enum State { IDLE, RUN, JUMP } |
| Enum-Wert verwenden | var state: State = State.IDLE |
| Vektor- und Farbwerte | var pos := Vector2(10, 20)
var tint := Color(1, 0, 0) |
| Leere Objektreferenz | var target: Node = null |
| In Text, int oder float umwandeln | str(42), int("42"), float("3.5") |
| Float zu int (schneidet Nachkommastellen ab) | int(3.9) # 3 |
| Typ prüfen | value is int, node is Sprite2D |
| In einen Typ casten | var sprite := node as Sprite2D |
Operatoren
Bekannte Mathematik, dazu englische Wörter für Logik.
| Operation | Syntax |
|---|---|
| Addieren, subtrahieren, multiplizieren, dividieren | a + b, a - b, a * b, a / b |
| Ganzzahldivision (int / int) | 7 / 2 # 3 |
| Rest | 7 % 3, fmod(7.5, 2.0) |
| Potenz | 2 ** 10 # 1024 |
| Zusammengesetzte Zuweisung | x += 1, x -= 1, x *= 2, x /= 2 |
| Vergleich | ==, !=, <, >, <=, >= |
| Logik | a and b, a or b, not a |
| Logik (Symbolschreibweise) | a && b, a || b, !a |
| Inline-if | var label := "win" if score > 10 else "lose" |
| Enthalten in einer Sammlung | "sword" in inventory |
| Bitweise | a & b, a | b, a ^ b, ~a, a << 1, a >> 1 |
Kontrollfluss
Blöcke werden wie in Python durch Einrückung bestimmt. Godot rückt standardmäßig mit Tabs ein.
| Operation | Syntax |
|---|---|
| If, elif, else | if hp <= 0:
die()
elif hp < 20:
print("Low HP")
else:
print("OK") |
| Einzeiliges if | if hp <= 0: die() |
| Über einen Bereich iterieren | for i in range(5):
print(i) # 0 to 4 |
| Bereich mit Start, Ende und Schrittweite | for i in range(10, 0, -2):
print(i) # 10, 8, 6, 4, 2 |
| n-mal wiederholen | for i in 3:
print(i) # 0, 1, 2 |
| Über ein Array iterieren | for item in items:
print(item) |
| Typisierte Schleifenvariable (Godot 4.2+) | for n: String in names:
print(n.to_upper()) |
| While-Schleife | while hp > 0:
hp -= 10 |
| Schleife verlassen oder Durchlauf überspringen | break, continue |
| Platzhalter für leeren Block | pass |
Mustervergleich (match)
match führt den ersten Zweig aus, dessen Muster passt. Es gibt kein Fallthrough.
| Operation | Syntax |
|---|---|
| Werte vergleichen | match state:
State.IDLE:
print("idle")
State.RUN:
print("run") |
| Mehrere Werte in einem Zweig | match key:
"w", "up":
move_up() |
| Standardzweig (Wildcard) | match n:
0:
print("zero")
_:
print("other") |
| Wert an einen Namen binden | match cmd:
"quit":
get_tree().quit()
var other:
print("Unknown: ", other) |
| Array-Muster | match pos:
[0, 0]:
print("origin")
[var x, 0]:
print("on the x axis at ", x) |
| Array mit beliebigem Rest | match args:
["move", ..]:
print("move command") |
| Dictionary-Muster | match item:
{"type": "coin", "value": var v}:
gold += v |
| Bedingung mit when (Godot 4.4+) | match score:
var s when s >= 90:
print("A")
var s when s >= 75:
print("B")
_:
print("C") |
Funktionen und Lambdas
Funktionen sind auch Werte: Du kannst sie speichern, übergeben und Argumente an sie binden.
| Operation | Syntax |
|---|---|
| Typisierte Parameter und Rückgabe | func add(a: int, b: int) -> int:
return a + b |
| Kein Rückgabewert | func reset() -> void:
score = 0 |
| Standardargument | func greet(who := "player") -> void:
print("Hi, ", who) |
| Statische Funktion | static func double(x: int) -> int:
return x * 2 |
| Einzeiliges Lambda | var square := func(x): return x * x |
| Callable aufrufen | square.call(4) # 16 |
| Funktion als Wert | var on_done := reset
on_done.call() |
| Argumente binden | var add_ten := add.bind(10)
print(add_ten.call(5)) # 15 |
| Mehrzeiliges Lambda | var greet_all := func(names: Array) -> void:
for n in names:
print("Hi, ", n) |
| Auf einen Timer warten | await get_tree().create_timer(1.0).timeout |
| Auf eine Coroutine warten | var data = await fetch_data() |
Strings
String-Methoden geben einen neuen String zurück und ändern nie das Original.
| Operation | Syntax |
|---|---|
| Mit % formatieren | "%s has %d HP" % [name, hp] |
| Zwei Nachkommastellen | "%.2f" % 3.14159 # "3.14" |
| Mit benannten Platzhaltern formatieren | "{a} vs {b}".format({"a": 1, "b": 2}) |
| Mit + verketten | "Score: " + str(score) |
| Länge | text.length() |
| Groß- oder Kleinschreibung | text.to_upper(), text.to_lower() |
| In Teile zerlegen | "a,b,c".split(",") # ["a", "b", "c"] |
| Teile zusammenfügen | ", ".join(["a", "b", "c"]) |
| Leerraum entfernen | " hi ".strip_edges() # "hi" |
| Text ersetzen | text.replace("cat", "dog") |
| Position finden | text.find("lo") # -1 if missing |
| Beginnt oder endet mit | text.begins_with("Hi"), text.ends_with("!") |
| Teilstring | text.substr(0, 5) |
| Enthält | "ell" in "Hello" # true |
Arrays
Arrays wachsen und schrumpfen. Ein typisiertes Array akzeptiert nur seinen Elementtyp.
| Operation | Syntax |
|---|---|
| Array-Literal (gemischte Typen) | var items = [1, "two", 3.0] |
| Typisiertes Array | var scores: Array[int] = [10, 20, 30] |
| Per Index lesen (negativ zählt vom Ende) | scores[0], scores[-1] |
| Am Ende anhängen | scores.append(40), scores.push_back(40) |
| An einem Index einfügen | scores.insert(0, 5) |
| Letztes Element entfernen und zurückgeben | var last = scores.pop_back() |
| Nach Wert oder Index entfernen | scores.erase(20), scores.remove_at(0) |
| Enthält, Index von | scores.has(30), scores.find(30) |
| Länge, Leer-Prüfung | scores.size(), scores.is_empty() |
| Sortieren | scores.sort() |
| Mit eigener Regel sortieren | enemies.sort_custom(func(a, b): return a.hp < b.hp) |
| Map | scores.map(func(x): return x * 2) |
| Filter | scores.filter(func(x): return x > 15) |
| Reduce | scores.reduce(func(acc, x): return acc + x, 0) |
| Slice (Ende exklusiv) | scores.slice(1, 3) |
Dictionaries
Schlüssel-Wert-Paare. Schlüssel können jeden Typ haben, am häufigsten sind Strings.
| Operation | Syntax |
|---|---|
| Dictionary-Literal | var stats = {"hp": 100, "mp": 30} |
| Typisiertes Dictionary (Godot 4.4+) | var prices: Dictionary[String, int] = {"sword": 50} |
| Schlüssel lesen oder schreiben | stats["hp"], stats["xp"] = 50 |
| Mit Standardwert lesen | stats.get("luck", 0) |
| Schlüssel vorhanden | stats.has("hp"), "hp" in stats |
| Schlüssel entfernen | stats.erase("mp") |
| Schlüssel und Werte | stats.keys(), stats.values() |
| Anzahl der Einträge | stats.size() |
| Anderes Dictionary zusammenführen (true überschreibt) | stats.merge({"luck": 5}), stats.merge(bonus, true) |
| Über Schlüssel iterieren | for key in stats:
print(key, " = ", stats[key]) |
Klassen und Annotationen
Jedes Skript ist eine Klasse. Annotationen beginnen mit @.
| Operation | Syntax |
|---|---|
| Der Klasse einen globalen Namen geben | class_name Player
extends CharacterBody2D |
| Konstruktor | func _init(start_hp := 100) -> void:
hp = start_hp |
| Instanz erstellen | var p := Player.new() |
| Innere Klasse | class Item:
var name := ""
var price := 0 |
| Elternversion dieser Methode aufrufen | func _ready() -> void:
super()
print("child ready") |
| Andere Elternmethode aufrufen | super.take_damage(10) |
| Statische Variable (Godot 4.1+) | static var count := 0 |
| Im Inspector anzeigen | @export var speed := 300.0 |
| Mit Schieberegler-Bereich anzeigen | @export_range(0, 100) var volume := 50 |
| Kind-Node holen, sobald bereit | @onready var sprite: Sprite2D = $Sprite2D |
| Setter und Getter | var hp := 100:
set(value):
hp = clampi(value, 0, 100)
get:
return hp |
| Skript im Editor ausführen | @tool |
Signale
Signale sind vollwertige Objekte: Deklariere sie und emittiere, verbinde und erwarte sie dann direkt.
| Operation | Syntax |
|---|---|
| Signal deklarieren | signal died |
| Signal mit typisierten Argumenten | signal health_changed(old_hp: int, new_hp: int) |
| Emittieren | died.emit() |
| Mit Argumenten emittieren | health_changed.emit(100, 80) |
| Mit einer Methode verbinden | player.died.connect(_on_player_died) |
| Ein Lambda verbinden | button.pressed.connect(func(): print("Clicked")) |
| Zusätzliche Argumente übergeben | button.pressed.connect(_on_pressed.bind("start")) |
| Nur einmal auslösen | timer.timeout.connect(_on_timeout, CONNECT_ONE_SHOT) |
| Trennen | player.died.disconnect(_on_player_died) |
| Verbindung prüfen | player.died.is_connected(_on_player_died) |
| Auf ein Signal warten | await player.died |
Nodes und Lebenszyklus
Die Callbacks, die Godot auf deinem Node aufruft, und die Aufrufe, die du am Szenenbaum machst.
| Operation | Syntax |
|---|---|
| Objekt erstellt (vor dem Baum) | func _init() -> void:
print("created") |
| Node und seine Kinder sind bereit | func _ready() -> void:
print("ready") |
| Jeder Frame | func _process(delta: float) -> void:
position.x += 100.0 * delta |
| Jeder Physik-Tick | func _physics_process(delta: float) -> void:
velocity.y += 980.0 * delta
move_and_slide() |
| Eingabe, die die UI nicht genutzt hat | func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("jump"):
jump() |
| Node per Pfad holen | get_node("Sprite2D"), $Sprite2D |
| Pfad mit Leerzeichen, eindeutiger Name | $"UI/Health Bar", %HealthBar |
| Eingabeaktion prüfen | Input.is_action_pressed("move_right") |
| Szene instanziieren | var enemy := preload("res://enemy.tscn").instantiate()
add_child(enemy) |
| Node sicher löschen | queue_free() |
| Eltern und Kinder | get_parent(), get_children() |
| Szene wechseln | get_tree().change_scene_to_file("res://main.tscn") |
Die GDScript-Syntax, die du beim Bauen eines Godot-Spiels brauchst, auf einer Seite. Dieser GDScript-Spickzettel ist eine Schnellreferenz für Godot 4: Variablen und statische Typen, Operatoren, Kontrollfluss und match, Funktionen und Lambdas, Strings, Arrays und Dictionaries, Klassen, Signale sowie die Node-Callbacks, die Godot in jedem Frame ausführt.
Alles hier ist Godot-4-Syntax, du siehst also @export, @onready, died.emit() und await statt der Formen aus Godot 3. Kopiere, was du brauchst, in dein Skript, oder probiere die Sprach-Snippets live im GDScript-Playground aus: Setz sie in _ready() und führe sie im Browser aus, ganz ohne Godot-Installation.
GDScript-Spickzettel FAQ
Ist dieser GDScript-Spickzettel kostenlos?
Ist dieser Spickzettel für Godot 4 oder Godot 3?
@export und @onready statt der Schlüsselwörter export und onready, died.emit() und died.connect(callable) statt emit_signal("died") und connect mit Strings, await statt yield und super() statt .method(). Zeilen mit 4.1+, 4.2+ oder 4.4+ brauchen mindestens diese Godot-Version.Was ist der Unterschied zwischen = und := in GDScript?
var x = 5 erzeugt eine dynamische Variable, die später jeden Typ aufnehmen kann. var x := 5 leitet den Typ aus dem Wert ab (hier int) und legt ihn fest, sodass eine spätere Zuweisung eines Strings ein Fehler ist. var x: int = 5 gibt den Typ explizit an. Statische Typen bringen dir Fehler im Editor, bessere Autovervollständigung und schnelleren Code.Wie funktionieren Signale in GDScript?
signal died, sende es mit died.emit() und reagiere in einem anderen Node darauf mit player.died.connect(_on_player_died). Du kannst statt einer Methode ein Lambda verbinden, zusätzliche Argumente mit .bind() binden oder eine Funktion mit await player.died pausieren, bis das Signal ausgelöst wird.Ist GDScript wie Python?
for ... in, if/elif/else sowie englische Wörter wie and, or und not. Aber GDScript ist eine eigene Sprache, gebaut für Godot. Es hat optionale statische Typen, Signale, Annotationen wie @export und direkten Zugriff auf Nodes mit $.Kann ich GDScript online üben?
_ready() einmal läuft. Wenn du Struktur willst, führt dich Coddys kostenloser interaktiver GDScript-Kurs Schritt für Schritt von Variablen und Funktionen bis zu Klassen und Signalen.