Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | nic96 |
With ChatGPT’s help I was able to come up with a solution but I’m wondering if it’s an ideal solution or if there’s a better way of doing it. It would be really great if there was some helper function to get the collision force. I tried using get_contact_impulse
but I was always getting back a Vector3 of (0, 0, 0) which might be because I have a mass of 5000 assigned to my RigidBody3D. Here’s the code I was able to put together that seems to work the way I want it to but I think it’s more complex then it needs to be.
static func compute_damage(state: PhysicsDirectBodyState3D) -> float: # Check if the state object is valid if state == null: return 0.0 ``` # Retrieve the contact count and iterate over each contact var contact_count: int = state.get_contact_count() var collision_force: Vector3 = Vector3.ZERO var collision_torque: Vector3 = Vector3.ZERO for i in range(contact_count): # Retrieve the contact information for each contact var contact_position: Vector3 = state.get_contact_local_position(i) var contact_normal: Vector3 = state.get_contact_local_normal(i) # Compute the collision velocity and mass of the other object var other_body: PhysicsBody3D = state.get_contact_collider_object(i) var other_velocity: Vector3 = other_body.get_linear_velocity() var other_angular_velocity: Vector3 = other_body.get_angular_velocity() var other_mass: float = other_body.get_mass() var other_inertia_tensor: Vector3 = other_body.get_inverse_inertia_tensor().get_scale() if other_inertia_tensor == Vector3.ZERO: other_inertia_tensor = Vector3(1, 1, 1) var relative_velocity: Vector3 = state.get_contact_collider_velocity_at_position(i) - other_velocity var collision_speed: float = relative_velocity.dot(contact_normal) # Compute the impulse using the collision speed and the masses of the colliding objects var impulse: float = (1 + other_body.physics_material_override.bounce) * collision_speed if other_mass > 0: impulse /= state.get_inverse_mass() + 1.0 / other_mass else: impulse /= state.get_inverse_mass() # Compute the collision force and torque for each contact var contact_force: Vector3 = contact_normal * impulse var contact_torque: Vector3 = contact_position.cross(contact_force) # Accumulate the collision forces and torques from all contacts collision_force += contact_force # Compute the collision torque for each contact based on the contact position and contact force, # using the other body's inverse inertia tensor to account for its rotational inertia # and accumulate the torques from all contacts collision_torque += other_inertia_tensor * (contact_position.cross(contact_force) + contact_torque) # Calculate the magnitude of the total collision force and torque var force_magnitude: float = collision_force.length() var torque_magnitude: float = collision_torque.length() # Use the collision force and torque to calculate damage and apply forces to the rigid body var damage: float = force_magnitude / 1000.0 # Adjust this value as needed return damage ```
ChatGPT’s knowledge of Godot 4 is quite limited/outdated but with feeding it enough information it was able help me come up with a solution.