My bullet ballistics code has some problem, help please

Godot Version

4.7

Question

My weapon ballistics code dont working right.
I wanted to make "realistically(trying)" custom bullet mechanics with area3d and physicsserver3d raycasts for best performance. But it dont working properly. I am newbie, if anyone help I appreciate:)

I think, issue from momentum/kinetic_energy.

my code:

extends Area3D

const airdensity: float = 1.223
const world_gravity: Vector3 = Vector3(0, 9.81, 0)


@export_group("projectile Description")
@export var projectile_name: String
@export var projectile_mass: float
@export var projectile_diameter: float
@export var start_velocity: float
@export var ballistic_coefficient: float

var drag_coefficient_curve: Curve = preload("res://Weapons/DragCoefficient.tres")
var current_velocity: Vector3 = Vector3.ZERO
@onready var projectile_area: float = PI * pow(projectile_diameter * 0.5, 2)
var old_collison: RID

func _ready() -> void:
	current_velocity = self.global_basis.z * start_velocity

func _process(delta: float) -> void:
	drive_projectile(delta)

func detect_collisons(start_pos: Vector3, end_pos: Vector3) -> Dictionary:
	var space_state: PhysicsDirectSpaceState3D = get_world_3d().direct_space_state
	var query: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.create(start_pos, end_pos)
	return space_state.intersect_ray(query)

func check_thickness(collison_point: Vector3, velocity_normal: Vector3, original_collider: RID) -> float:
	var exclude_list: Array[RID] = []
	var thickness: float = 0.0
	var start_inside_pos: Vector3 = collison_point + (velocity_normal * 400)
	var space_state: PhysicsDirectSpaceState3D = get_world_3d().direct_space_state
	var query: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.create(start_inside_pos, collison_point)
	query.hit_back_faces = true
	for i: int in range(20):
		query.exclude = exclude_list
		var inside_ray_data: Dictionary = space_state.intersect_ray(query)
		if inside_ray_data.is_empty():
			break
		if inside_ray_data["rid"] == original_collider:
			thickness = collison_point.distance_to(inside_ray_data["position"])
			break
		else:
			exclude_list.append(inside_ray_data["rid"])
	return thickness

func apply_drag_force(delta: float) -> void:
	var projectile_drag: float = 0.5 * drag_coefficient_curve.sample(1) * projectile_area * current_velocity.length_squared() * airdensity
	var drag_acc: float = projectile_drag / projectile_mass
	current_velocity -= (drag_acc * current_velocity.normalized() * delta)

func drive_projectile(delta: float) -> void:
	var old_pos: Vector3 = self.global_position
	apply_drag_force(delta)
	current_velocity += world_gravity * delta
	self.look_at((self.global_position + -current_velocity), Vector3.UP, false)
	self.global_position += -current_velocity * delta
	var detected_collison: Dictionary = detect_collisons(old_pos, self.global_position)
	if not detected_collison.is_empty():
		if not old_collison.is_valid() or old_collison != detected_collison["rid"]:
			var projectile_momentum: float = ( current_velocity.length() * projectile_mass )
			var projectile_energy: float = ( 0.5 * projectile_mass * current_velocity.length_squared() )
			var loss_momentum: float = 0.0
			var loss_energy: float = 0.0
			if detected_collison["collider"].has_meta("mat"):
				if detected_collison["collider"].get_meta("mat") is Resource:
					var current_meta: Resource = detected_collison["collider"].get_meta("mat")
					loss_energy = current_meta.pascal_yield_strength * projectile_area * check_thickness(detected_collison["position"], current_velocity, detected_collison["rid"])
					if loss_energy < projectile_energy:
						old_collison = detected_collison["rid"]
						var new_energy: float = projectile_energy - loss_energy
						var new_momentum: float = sqrt(2 * projectile_mass * new_energy)
						loss_momentum = projectile_momentum - new_momentum
						current_velocity = (new_momentum / projectile_mass) * current_velocity.normalized()
						print(str(loss_momentum))
						if detected_collison["collider"] is RigidBody3D:
							detected_collison["collider"].apply_impulse(loss_momentum * current_velocity.normalized(), detected_collison["position"] - detected_collison["collider"].global_position)
					else:
						print(str(projectile_momentum))
						if detected_collison["collider"] is RigidBody3D:
							detected_collison["collider"].apply_impulse(projectile_momentum * current_velocity.normalized(), detected_collison["position"] - detected_collison["collider"].global_position)
						self.queue_free()
			else:
				print("Node ", str(detected_collison["collider"]), " Not Has Material Res!!!!")

func _on_timer_timeout() -> void:
	self.queue_free()

Describe how does it work vs how do you expect it to work?

I forgot to update that page.
I fixed the problem:)

You haven’t posted the solution so rather than check your post as the solution, either explain the problem and how to fix it, then mark that post as the solution.

Or ask that the whole thread be deleted so people don’t lose time with it if and when it comes up in searches, as right now it’s pretty useless with a big code blob and no clear problem or solution.

Thanks :folded_hands:t5: