Creating and Using QRigidBodyNode - erayzesen/godot-quarkphysics GitHub Wiki

Rigid bodies are essential components in games. In QuarkPhysics, the usage structure of rigid bodies is not much different from other physics engines or Godot's built-in physics system. To simulate rigid bodies, a QMeshNode object with a single radius particle or a QMeshNode object with more than three particles and a polygon formed by them are sufficient. Contrary to what is commonly thought, rigid bodies in QuarkPhysics are not softened body objects trying to be stiffened.

What are the Advantages?

Although the usage structure and basic dynamics of rigid bodies in QuarkPhysics are similar to traditional physics engines, the simulation approach is quite different, being position-based, and it offers several advantages. Firstly, we do not have abstracted speeds or force units. For example, a force applied to a rigid body in the x vector simply tells it to move by an x-pixel vector. Then, our velocity integrator (Verlet integrator) generates implicit velocity and acceleration based on this displacement information. In other words, to move a rigid body 10 pixels to the right in QuarkPhysics, you only apply a force of 10 pixels. This gives you a feeling of control similar to the simple approaches used in older 2d games.

How to Create a QRigidBodyNode Object?

You can create a QRigidBodyNode object by adding it to the scene tree just like any other node. If you add child nodes such as QMeshRectNode, QMeshPolygonNode, QMeshCircleNode, or custom-designed QMeshAdvancedNode under it, your QRigidBodyNode will be ready to work in the basic sense. You can also make the necessary adjustments via the Inspector. Additionally, it is possible to add it via code.

var my_rigid_body=QRigidBodyNode.new()
my_rigid_body.global_position=Vector2(500,500)
add_child(my_rigid_body)

var my_mesh=QMeshRectNode.new()
my_mesh.rectangle_size=Vector2(128,128)
my_rigid_body.add_child(my_mesh)


How can I Change the Position and Rotation of a QRigidBodyNode Object?

Controlling rigid bodies while developing game logic has always been a nuisance without disrupting the simulation. However, in QuarkPhysics, there are several alternatives available to control an object without disturbing the simulation.

Quick Approaches


# SAFE METHODS TO APPLY EVERY FRAME

#It changes the position of the QRigidBody and the body collides with the world. 
my_rigid_body.set_body_position_and_collide( Vector2(128,256), false ) 

#It adds a new force to the total force of the QRigidBody for the next frame.
my_rigid_body.add_force(Vector2(0,12))

#It adds a new angular force to the total force of the QRigidBody for the next frame. 
my_rigid_body.add_angular_force( 0.05 )

# UNSAFE METHODS TO APPLY EVERY FRAME
# These methods set the position of the QRigidBody directly.
my_rigid_body.set_body_position ( Vector(128,256), true )
my_rigid_body.add_body_position ( Vector(16,32) )

# These methods set the rotation of the QRigidBody directly. 
my_rigid_body.set_body_rotation (0.1, false)
my_rigid_body.add_body_rotation(0.1) 
my_rigid_body.set_body_rotation_degree(60.0, false) 

More Comprehensive and Flexible Approaches For this, we use the pre_step event signal of the QBodyNode objects. Any changes you make within this event are made before the object enters iterations involving collision and constraints and are reliable.

func _ready() -> void:
  # Connecting the `pre_step` signal of the QBodyNode
  connect("pre_step",on_pre_step)
func on_pre_step() :
  # # You can change the position and rotation directly.
  #Add 10 pixel to right direction per frame to QRigidBody
  set_body_position (get_body_position()+Vector2.RIGHT*10.0, false )
  add_body_position( Vector2.RIGHT*10.0 )

  # Add 1 degree of angular velocity per frame directly
  set_body_rotation (get_body_rotation()+ (PI/180.0) )
  set_body_rotation_degree (get_body_rotation_degree()+1.0 )
  add_body_rotation( (PI/180.0) )
  add_body_rotation_degree(1.0)

  # You can apply a forces directly  
  # Apply a 10-pixel force to the right direction per frame to the QRigidBodyNode
  apply_force( Vector2.RIGHT*10)
  # Apply a 1-degree angular force per frame to the QRigidBodyNode
  apply_angular_force( PI/180)



QRigidBodyNode and the Position and Rotation Relationship with Godot's Node2D

Simply put, QRigidBodyNode objects update the position, global_position, rotation, and global_rotation properties inherited from Node2D in every frame of the simulation. This means you cannot assign position and rotation directly to these objects through Node2D properties. However, you can still use these Node2D position and rotation properties to get the updated positions and rotations of the physics objects.

QRigidBodyNode Settings in the Inspector

Fixed Rotation - fixed_rotation: With this setting, the rotation of the rigid body never changes during the simulation and remains fixed.

Kinematic - kinematic: This setting determines whether the object behaves kinematically. Kinematic objects do not respond to physical interactions such as gravity or velocity integrators. Additionally, they do not react to collisions with other dynamic objects; instead, they only react to collisions with dynamic objects during the collision itself.

Kinematic Collisions - kinematic_collisions: By default, a kinematic rigid body does not react to collisions with other kinematic rigid bodies. If the object is set to kinematic and kinematic_collisions is set to true, it will be affected by collisions with other kinematic objects.


To learn more about all the methods and properties of QRigidBodyNode, refer to the QRigidBodyNode page.