How to disable collisions detections while maintaining force calculations?

Godot Version

^4.4

Question

Why I want to turn collisions off is because I noticed when moving a bunch of StaticBody3D every frame, it lags things a lot.

So the goal is NOT just turn off every collision_mask down, but rather to completely turn off collisions, globally or locally, for the purpose of optimizing when you temporarily don’t need collisions. But instead of disable the whole physics calculation, reserve the velocity and force.

Collision Shapes have a disabled flag. Is that what you are looking for?

1 Like

You’re not supposed to move STATIC bodies. They’re static. They are supposed to remain in place.

Yes, the lag disappears after setting disabled = true, but that sounds tedious. So I discovered I can turn off my main character RigidBody3D’s collision_mask and collision_layer (I didn’t turn this off before, so it still lags).

So thank you, my question sounds silly, for the solution is so simple.

Yes, you can move them, as long as you don’t expect them to give kinematics correct force when collided.

My problem is that there’s a dynamic RigidBody3D (that goes very far) with a bunch of static StaticBody3D under a parent node Enviornments. To solve floating point precision, I mock their positions by sticking the rigid body to zero, and move the environments instead. If you want to know what I’m trying to make, that is No Man’s Sky


Specifically, I created this simple BigVector3 script to record the position. Just sharing:

class_name BigVector3
## Hello, World!
##
## The value represented by this object is:
## [codeblock]
## value = fraction + integer * PRECISION
## [/codeblock]

# you can actually set it to 1, and it'll be already big enough, about 123308867.883 AU
const PRECISION: float = 100

var fraction := Vector3.ZERO
var integer := Vector3i.ZERO


func _init(fraction := Vector3.ZERO, integer := Vector3i.ZERO) -> void:
	self.fraction = fraction
	self.integer = integer
	normalize()


func get_value() -> Vector3:
	return fraction + integer * PRECISION


func normalize() -> void:
	var counts: Vector3i = (fraction / PRECISION).floor()
	fraction -= PRECISION * counts
	integer += counts


func add(other: BigVector3) -> void:
	fraction += other.fraction
	integer += other.integer
	normalize()


func sub(other: BigVector3) -> void:
	fraction -= other.fraction
	integer -= other.integer
	normalize()


func neg() -> void:
	fraction = Vector3.ONE * PRECISION - fraction
	integer = -Vector3i.ONE - integer

You can play with the precisions here