# Single-line comments are written using hash symbol. """ Multi-line comments are written using triple quoted strings """ # Doc Comments can add a description to classes and fields # which can be viewed in the in-engine docs. ## This class is a demonstration of GDScript # Script file is a class in itself and you can optionally define a name for it. class_name MyClass # Inheritance extends Node2D # Member variables var x = 8 # int var y = 1.2 # float var b = true # bool var s = "Hello World!" # String var a = [1, false, "brown fox"] # Array - similar to list in Python, # it can hold different types # of variables at once. var d = { "key" : "value", 42 : true } # Dictionary holds key-value pairs. var p_arr = PackedStringArray(["Hi", "there", "!"]) # Packed Arrays can # only hold a certain type. # Doc comments can apply to properties ## How many times this object has jumped var jump_count = 0 # Built-in vector types: var v2 = Vector2(1, 2) var v3 = Vector3(1, 2, 3) # Constants const ANSWER_TO_EVERYTHING = 42 const BREAKFAST = "Spam and eggs!" # Enums enum { ZERO, ONE , TWO, THREE } enum NamedEnum { ONE = 1, TWO, THREE } # Exported variables are visible in the inspector. # # Either a type hint (explained later) or a default value are needed in order # for the editor to know what options to give @export var age: int @export var height: float @export var person_name = "Bob" # But both is also acceptable @export var favorite_color: String = "Green" @export var favorite_food := "Pizza" # Functions func foo(): pass # pass keyword is a placeholder for future code func add(first, second): return first + second # Doc Comments on functions ## Increases the Jump Count func jump(): jump_count += 1 # Printing values func printing(): print("GDScript ", "is ", " awesome.") prints("These", "words", "are", "divided", "by", "spaces.") printt("These", "words", "are", "divided", "by", "tabs.") printraw("This gets printed to system console.") # Lambdas var my_lambda = func(): print("hello from lambda!") my_lambda.call() # Math func doing_math(): var first = 8 var second = 4 print(first + second) # 12 print(first - second) # 4 print(first * second) # 32 print(first / second) # 2 print(first % second) # 0 # There are also +=, -=, *=, /=, %= etc., # however no ++ or -- operators. print(pow(first, 2)) # 64 print(sqrt(second)) # 2 printt(PI, TAU, INF, NAN) # built-in constants # Control flow func control_flow(): x = 8 y = 2 # y was originally a float, # but we can change its type to int # using the power of dynamic typing! if x < y: print("x is smaller than y") elif x > y: print("x is bigger than y") else: print("x and y are equal") var a = true var b = false var c = false if a and b or not c: # alternatively you can use &&, || and ! print("This is true!") for i in range(20): # GDScript's range is similar to Python's print(i) # so this will print numbers from 0 to 19 for i in 20: # unlike Python, you can loop over an int directly print(i) # so this will also print numbers from 0 to 19 for i in ["two", 3, 1.0]: # iterating over an array print(i) while x > y: printt(x, y) y += 1 x = 2 y = 10 while x < y: x += 1 if x == 6: continue # 6 won't get printed because of continue statement prints("x is equal to:", x) if x == 7: break # loop will break on 7, so 8, 9 and 10 won't get printed match x: 1: print("Match is similar to switch.") 2: print("However you don't need to put cases before each value.") 3: print("Furthermore each case breaks on default.") break # ERROR! Break statement is unnecessary! 4: print("If you need fallthrough use continue.") continue _: print("Underscore is a default case.") # ternary operator (one line if-else statement) prints("x is", "positive" if x >= 0 else "negative") # Casting func casting_examples(): var i = 42 var f = float(42) # cast using variables constructor var b = i as bool # or using "as" keyword # Override functions # By a convention built-in overridable functions start with an underscore, # but in practice you can override virtually any function. # _init is called when object gets initialized # This is the object's constructor. func _init(): # Initialize object's internal stuff here. pass # _ready gets called when script's node and # its children have entered the scene tree. func _ready(): pass # _process gets called on every frame. func _process(delta): # The delta argument passed to this function is a number of seconds, # which passed between the last frame and the current one. print("Delta time equals: ", delta) # _physics_process gets called on every physics frame. # That means delta should be constant. func _physics_process(delta): # Simple movement using vector addition and multiplication. var direction = Vector2(1, 0) # or Vector2.RIGHT var speed = 100.0 self.global_position += direction * speed * delta # self refers to current class instance # When overriding you can call parent's function using the dot operator # like here: func get_children(): # Do some additional things here. var r = super() # call parent's implementation return r # Inner class class InnerClass: extends Object func hello(): print("Hello from inner class!") func use_inner_class(): var ic = InnerClass.new() ic.hello() ic.free() # use free for memory cleanup extends Node2D var sprite # This variable will hold the reference. # You can get references to other nodes in _ready. func _ready() -> void: # NodePath is useful for accessing nodes. # Create NodePath by passing String to its constructor: var path1 = NodePath("path/to/something") # Or by using NodePath literal: var path2 = ^"path/to/something" # NodePath examples: var path3 = ^"Sprite" # relative path, immediate child of the current node var path4 = ^"Timers/Firerate" # relative path, child of the child var path5 = ^".." # current node's parent var path6 = ^"../Enemy" # current node's sibling var path7 = ^"/root" # absolute path, equivalent to get_tree().get_root() var path8 = ^"/root/Main/Player/Sprite" # absolute path to Player's Sprite var path9 = ^"Timers/Firerate:wait_time" # accessing properties var path10 = ^"Player:position:x" # accessing subproperties # Finally, to get a reference use one of these: sprite = get_node(^"Sprite") as Sprite # always cast to the type you expect sprite = get_node("Sprite") as Sprite # here String gets # implicitly casted to NodePath sprite = get_node(path3) as Sprite sprite = get_node_or_null("Sprite") as Sprite sprite = $Sprite as Sprite func _process(delta): # Now we can reuse the reference in other places. prints("Sprite has global_position of", sprite.global_position) # Use @onready annotation to assign a value to # a variable just before _ready executes. # This is a commonly used syntax sugar. @onready var other_sprite = $Sprite as Sprite # You can export NodePath, so you can assign it within the inspector. @export var nodepath = ^"" @onready var reference = get_node(nodepath) as Node # Or export Node directly @export var other_reference: Node class_name Player extends Node2D var hp = 10 # Doc comments can go on signals too ## Emitted when the player dies signal died() # define signal signal hurt(hp_old, hp_new) # signals can take arguments func apply_damage(dmg): var hp_old = hp hp -= dmg hurt.emit(hp_old, hp) # emit signal and pass arguments if hp <= 0: died.emit() func _ready(): # connect signal "died" to function "_on_death" defined in self died.connect(_on_death) # Alternate way # needed if the target object is not self # died.connect(Callable(self, &"_on_death")) func _on_death(): queue_free() # destroy Player on death extends Node var x: int # define typed variable var y: float = 4.2 var z := 1.0 # infer type based on default value using := operator var a: Array[int] = [1, 2, 3] # Array can also have its type content specified enum NamedEnum { ONE = 1, TWO, THREE } var n: NamedEnum = NamedEnum.ONE # Enums can be used as types as well @onready var node_ref_typed := $Child as Node @export var speed := 50.0 const CONSTANT := "Typed constant." signal example(arg: int) func _ready() -> void: # function returns nothing x = "string" # ERROR! Type can't be changed! a.append("q") # ERROR! Array[int] can't hold strings! return func join(arg1: String, arg2: String) -> String: # function takes two Strings and returns a String return arg1 + arg2 func get_child_at(index: int) -> Node: # function takes an int and returns a Node return get_children()[index]