This provides all functions that QGodot offers.
This is a main singleton that handles functionality of QGodot.
This section contains all of functions related to querying system.
This give an array of nodes matching specified main node class names and all node paths.
There are few syntaxes and features to learn more in this snippet. Take a look at below:
onready var units := QGodot.query(
"KinematicBody",
[
"Status",
]
)
onready var mobs := QGodot.query(
"KinematicBody",
[
"Status",
"Loot",
]
)
onready var horses := QGodot.query(
"KinematicBody",
[
"Status",
"Loot",
"horse", # group name inclusion.
]
)
onready var wild_horses := QGodot.query(
"KinematicBody",
[
"Status",
"Loot",
"-Inventory", # '-' node path exclusion.
"horse",
]
)
onready var tamed_horses := QGodot.query(
"KinematicBody",
[
"Status",
"Loot",
"Inventory",
"horse",
]
)
onready var other_players := QGodot.query(
Player, # If defined class is a custom class, use defined 'class_name' or 'Script' type of class instances instead.
[
"Status",
"Inventory",
"-local_player", # group name exclusion
]
)
This function works the same way as query()
but instead gives a Query
instance instead of an array of nodes.
bind_query(main_node: String|Script, sub_node_paths: Array[String], target_or_script: Object, method_or_shared: String|Object)
This works the same way as query()
but will bind a callback to target function in the specified instance. When a new node is entered the scene tree, this will fire up and gives all nodes specified in the query in function parameters.
func _ready():
QGodot.bind_query(
"StaticBody2D",
[
"Sprite",
"CollsionShape2D",
"wall", # This is godot group, will not be included in the callback parameter.
],
self,
"_static_body_entered"
)
func _static_body_entered(main_node: StaticBody, sprite: Sprite, col: CollisionShape2D) -> void: # first parameter will always be main node, and any of node groups won't be included (in this case, 'wall').
print("%s entered!" % main_node.name)
sprite.texture = preload("res://icon.png")
Alternatively, you can also bind the query with instantiable Script
that has base type of Node
. This will increase performance by instantiating node that controls the main node instead.
class PropCarMovementSystem extends Node:
var shared: Node
var car: KinematicBody
var wheels := []
func _init(main_node, wheel_0, wheel_1, wheel_2, wheel_3):
car = main_node
wheels.push_back(wheel_0)
wheels.push_back(wheel_1)
wheels.push_back(wheel_2)
wheels.push_back(wheel_3)
func _process():
car.global_translation.z -= 0.1
for wheel in wheels:
wheel.rotation.x += 0.1
func _ready():
QGodot.bind_query(
"KinematicBody",
[
"Wheels/Wheel0",
"Wheels/Wheel1",
"Wheels/Wheel2",
"Wheels/Wheel3",
],
PropCarMovementSystem, # use instantiable script instead of instance.
self # binds with this instance.
)
Performs querying on specified node after its tree structure and grouping alternation.
horse.add_child("Inventory")
horse.add_to_group("uncontrollable")
QGodot.refresh_query_on_node(horse)
Perform a cleanup (all created queries). Should be used before changing between scenes.
QGodot.flush()
get_tree().change_scene("res://scn/scn_battle_result.tscn")
This section contains functionalites related to QGodot's integrated global signals.
Create an awaiter for the target signal. You must yield()
for the completed
signal. Note that return value must only have one parameter or the awaiter will fail!.
var input = yield(QGodot.to_signal("input_prompted"), "completed")
Then, to emit a signal:
QGodot.signal_emit("input_prompted", [ 1234 ])
Emits a signal. If the signal doesn't exist, create a new one and connects all awaiting lists to the signal.
CAUTION: DO NOT USE SAME SIGNAL NAME BUT WITH DIFFERENT PARAMETER LENGTH, OR IT WILL RESULT IN UNSUCCESSFUL SIGNAL CREATION AND EMISSION. flush()
WILL NOT HELP.
QGodot.signal_emit("unit_killed", [killer, target])
Perform signal connection. If the signal doesn't exist, await until the signal is created then connect to it.
func _ready():
QGodot.signal_connect("unit_killed", self, "_unit_killed")
func _unit_killed(killer: Spatial, target: Spatial) -> void:
print("%s killed %s!" % [killer.name, target.name])
Disconnects a singal from target function. If the signal doesn't exist, remove from await list.
QGodot.signal_disconnect("unit_killed", self, "_unit_killed")
Lists that contain other functionalies in QGodot.
This determines if this 'process' frame is on second frame. Mainly is used for half-querying process and is very useful if you wanted to sync with half-querying or just wanted to reduce amount of processing in certain nodes.
CAUTION: DO NOT USE THIS WITH PHYSICS PROCESSES, OR IT COULD PRODUCE UNEXPECTED RESULTS!
extends KinematicBody2D
class_name Player
func _process(delta):
if QGodot.is_second_frame:
return
# Do something else
Shorthand for get_tree().get_nodes_in_group()
but will take the first found node.
An object that holds list of nodes and ways to handle them.
This contains all nodes in this query, assigned with names of main nodes.
NOTE: If there is more than one main node with same name, the mechanism will be MESSED UP. Make sure that all nodes have unique names.
onready var players := QGodot.get_query("KinematicBody", ["Inventory"])
onready var world := QGodot.get_first_node("world") # Player container.
# Assuming that data is received and passed as Dictionary (mostly is from JSON)
func _data_received(data: Dictionary) -> void:
var id = data["id"]
var player: KinematicBody
if not id in players.by_name:
## New player.
player = preload("res://obj/player.tscn").instance()
player.translation = Vector3(data["x"], data["y"], data["z"])
player.name = id
world.add_child(player)
return
## Player already exists.
var binds := players.by_name[id]
player = binds["self"]
player.translation = Vector3(data["x"], data["y"], data["z"])
Iterate to all nodes in the query.
onready var prop_cars := QGodot.get_query(
"StaticBody",
[
"Wheels/Wheel0",
"Wheels/Wheel1",
"Wheels/Wheel2",
"Wheels/Wheel3"
]
)
func _process(delta):
for binds in prop_cars.iterate():
binds["self"].global_translation.z += 0.1
binds["Wheels/Wheel0"].rotation.x += 0.1
binds["Wheels/Wheel1"].rotation.x += 0.1
binds["Wheels/Wheel2"].rotation.x += 0.1
binds["Wheels/Wheel3"].rotation.x += 0.1
However, if this is only one function you use, consider using QGodot.query()
to directly obtain array for iteration.
onready va prop_cars := QGodot.query( # just use '.query()' to obtain an array.
"StaticBody",
[
"Wheels/Wheel0",
"Wheels/Wheel1",
"Wheels/Wheel2",
"Wheels/Wheel3"
]
)
func _process(delta):
for binds in prop_cars: # No need for '.iterate()'.
binds["self"].global_translation.z += 0.1
binds["Wheels/Wheel0"].rotation.x += 0.1
binds["Wheels/Wheel1"].rotation.x += 0.1
binds["Wheels/Wheel2"].rotation.x += 0.1
binds["Wheels/Wheel3"].rotation.x += 0.1
This will split query into half and iterate only one part of it, swap to another half next frame and the cycle continues on.
onready var prop_cars := QGodot.get_query(
"StaticBody",
[
"Wheels/Wheel0",
"Wheels/Wheel1",
"Wheels/Wheel2",
"Wheels/Wheel3"
]
)
func _process(delta):
for binds in prop_cars.half_iterate():
binds["self"].global_translation.z += 0.1
binds["Wheels/Wheel0"].rotation.x += 0.1
binds["Wheels/Wheel1"].rotation.x += 0.1
binds["Wheels/Wheel2"].rotation.x += 0.1
binds["Wheels/Wheel3"].rotation.x += 0.1
Get number of nodes in the query.
This class introduces shorter way to write code by omitting QGodot
singleton calls from code. Simply extend any system classes with QGodot.System
. Now QGodot
singleton calls can be omitted.
However, due to weakness of GDScript in Godot 3.x, I have to make change on is_second_frame
to become function. Which means, instead of QGodot.is_second_frame
, you need to use is_second_frame()
instead
extends QGodot.System
# 'QGodot.query' gets shortened to just 'query'
onready var owned_horses := query("KinematicBody2D", ["Inventory", "horse"])
func _ready() -> void:
# 'QGodot.to_signal' gets shortened to just 'to_signal'
yield(to_signal("game_loaded"), "completed")
print("Game is fully loaded!")
func _process(_delta: float) -> void:
# Only API reference that has been changed, you must call it as function instead
# 'QGodot.is_second_frame' -> 'is_second_frame()'
if is_second_frame():
print("This is second frame.")