Getting Started: Creating a Physics World. - erayzesen/godot-quarkphysics GitHub Wiki
To start a physics simulation, you need to add a QWorldNode object to the root of your scene tree. You can do this by pressing Ctrl + A or by clicking the (+) button in the scene tree panel and selecting QWorldNode. In another way, you can do this with code.
# In the root node of the scene
var my_world= QWorldNode.new()
add_child(my_world)
# Another way
# get_tree().get_current_scene().add_child(my_world)
There can only be one QWorldNode object in the scene tree. QWorldNode is responsible for controlling, maintaining, and terminating the entire physics world.
How to Start a QuarkPhysics Simulation in Godot?
When your game starts, any QBodyNode object added to the scene will first search for a QWorldNode at the root of the scene tree. Once it finds one, it registers itself to that world and becomes a part of it.
Note: You can rename your QWorldNode object, but this will make it more costly for QBodyNode objects to locate it. If it's not crucial for your setup, we recommend keeping its name as "QWorldNode", just as it is when created from the editor.
Similarly, when a QBodyNode is removed from the scene, it notifies the QWorldNode it belongs to and leaves the physics world. When your game closes or the scene is deleted, the QWorldNode automatically removes all the nodes it is responsible for before destroying itself.
How to Control the Physics World with QWorldNode?
The QWorldNode provides methods like add_body_node() and remove_body_node() to stay consistent with the original API. However, we do not recommend using them unless absolutely necessary. Instead, you should follow Godot's workflow:
- To add a QuarkPhysics node, simply place it anywhere in the scene tree.
- To remove a QuarkPhysics node, use queue_free() or remove it from the scene.
This plugin is designed to integrate smoothly with Godot's standard workflow. However, for objects whose names end in Object (such as QJointObject
), you must use the QWorldNode methods to add and remove them.
In addition, the QWorldNode inspector panel allows you to adjust various simulation parameters such as:
-
Iteration Count -
iteration_count
Determines how many times per frame the physics world will iterate to resolve constraints and collisions. Higher values improve simulation quality but increase performance cost. The default value is 4. -
Gravity -
gravity
Defines the gravity force vector applied to objects in the physics world. By default, it is set to Vector2(0.0, 0.2), meaning each object receives a downward force of 0.2 pixels per frame, accelerating due to velocity integration. -
Enable Sleeping -
enable_sleeping
When enabled, QBodyNode objects that remain stationary can be put to sleep to improve performance. Sleeping objects do not participate in collision tests, velocity integration, or constraints. They will wake up if an external force is applied. This option is enabled by default. If disabled, QBodyNode objects will never enter sleep mode. -
Time Scale -
time_scale
Sets the default time scale for the physics world. All movements and constraints of QBodyNode objects will be affected by this scale. The default value is 1.0. -
Enable BroadPhase -
enable_broadphase
Determines whether the BroadPhase optimization method (Sweep & Prune) is used for performance improvements. If disabled, the engine will use Brute-Force, where every object is directly tested against every other object using AABB checks. The default setting is enabled, and disabling it is not recommended. -
Enable Spatial Hashing -
enable_spatial_hashing
Replaces the built-in Sweep & Prune method with a Spatial Hashing technique specifically implemented as a BroadPhase optimization for QuarkPhysics. This method divides the scene into cells and only checks for collisions within the same cells. The default setting is disabled, and it will remain so until it is optimized further to outperform the built-in Sweep & Prune method. -
Spatial Hashing Size -
spatial_hashing_size
If Spatial Hashing is enabled, this option sets the size of the hashing cells. The default value is 128 pixels. -
Debug Renderer -
debug_renderer
Controls whether colliders and other physics-related visuals are displayed when the scene starts, helping with debugging. The default setting is enabled. It can be disabled if not needed, as the debug renderer is relatively expensive and may impact performance. -
Enable Debug Mouse Interactions -
enable_debug_mouse_interactions
Determines whether physics objects can be grabbed and dragged with the mouse during runtime. This feature is mainly used for debugging and development purposes. The default setting is enabled.
Accessing QWorldNode from a QBodyNode
In QuarkPhysics, objects follow a hierarchical ownership structure:
Every QBody belongs to a QWorld. Every QMesh belongs to a QBody. This structure is also maintained in the Godot plugin. If you want to access the QWorldNode that a QBodyNode belongs to, simply use:
var my_world = my_qbody_node.get_world_node()
How Can I Access QBodyNode Objects in a QWorldNode?
Sometimes, you may create a deeply nested structure of QBodyNode objects within the scene tree, making it difficult to access each one individually. Instead, you can use the QWorldNode to retrieve all QBodyNode objects in the scene, even if they are stacked inside different nodes.
The following code snippet disables all QBodyNode objects in the scene by setting their enabled property to false:
for i in range(my_world.get_body_count()):
var body = my_world.get_body_at(i)
body.enabled = false
Accessing, Removing, and Adding QuarkPhysics Objects via QWorldNode
The QWorldNode is not just responsible for managing QBodyNode objects. It also handles other objects that cannot be added to the scene tree, such as:
- QJointObject (used for creating constraints between bodies)
- QRaycastObject (used for raycasting)
- QSpringObject (used for spring-based constraints)
These objects are managed similarly, and QWorldNode provides methods to add, remove, and access them efficiently.
Adding Objects: The following code demonstrates how to add these objects to the world:
#Example: Adding a Joint Object
var my_joint=QJointObject.new()
my_joint.configure(rigid_body_a,rigid_body_a.global_position,rigid_body_b.global_position,rigid_body_b)
my_world.add_joint(my_joint)
#Example: Adding a Spring Object
var my_spring=QSpringObject.new()
my_spring.configure(particle_a,particle_b,100.0,false)
my_world.add_spring(my_spring)
#Example: Adding a Raycast Object
var my_raycast=QRaycastObject.new()
my_raycast.configure(Vector2(100,100),Vector2(32,32),true,1 )
my_world.add_raycast(my_raycast)
Removing Objects To remove these objects from the world, use the following code:
# Example: Removing a joint
world.remove_joint(my_joint)
# Example: Removing a raycast object
world.remove_raycast(my_raycast)
# Example: Removing a spring object
world.remove_spring(my_spring)
Accessing Objects You can retrieve these objects from the QWorldNode and manipulate them as needed:
# Example: Iterating over all joints in the world
for i in range(world.get_joint_count()):
var joint = world.get_joint_at(i)
joint.set_rigidity( 0.5 )
# Example: Iterating over all raycast objects
for i in range(world.get_raycast_count()):
var raycast = world.get_raycast_at(i)
raycast.set_enabled(false)
# Example: Iterating over all spring objects
for i in range(world.get_spring_count()):
var spring = world.get_spring_at(i)
spring.set_rigidity(0.1)
For a detailed explanation of all methods and properties of QWorldNode, please refer to the QWorldNode documentation
page