how to apply damage based on distance to center of explosion?
so the center should be max damage and less or none at the end of the 'area' node or given distance.

extends RigidDynamicBody3D
@export var area : Area3D
@export var force = 5.0
@export var EXPLOSION_TIME = 0.5
@export var explosionFX : PackedScene
@export var mesh : Node
@export var sparks : Node
var explosion_timer = 0.0
var exploded = false
@export var FUSE_TIME = 3.0
var fuse_timer = 0
@export var EXPLOSION_DAMAGE = 100
@export var COLLISION_FORCE = 8


func _ready():
	set_physics_process(false)

func _physics_process(delta):
	if fuse_timer < FUSE_TIME:
		fuse_timer += delta
		if fuse_timer >= FUSE_TIME:
			sparks.emitting = false
			mesh.visible = false
			var explo_instance = explosionFX.instantiate()
			get_tree().get_root().add_child(explo_instance)
			explo_instance.global_transform.origin = self.global_transform.origin
			
			self.freeze = true
			for body in area.get_overlapping_bodies():
				if body.has_method("damage"):
					body.damage(EXPLOSION_DAMAGE)
				if body is RigidDynamicBody3D:
					#print(body.name)
					var direction_vector = body.global_transform.origin - area.global_transform.origin
					var distance = direction_vector.length()
					var collision_force = (force / distance) * body.mass
					body.apply_impulse(direction_vector.normalized() * collision_force, Vector3.ZERO)
			exploded = true
			
			
	if exploded:
		explosion_timer += delta
		if explosion_timer >= EXPLOSION_TIME:
			area.monitoring = false
			queue_free()


func start():
	set_physics_process(true)
	sparks.emitting = true

You could do body.damage( ( 1 / area.global_transform.origin.distance_to(body.global_transform.origin) ) * EXPLOSION_DAMAGE ), but what I would suggest is casting rays from the center of the blast to every object that's within the radius to make sure you're not damaging things through walls, floors, etc.

  • DJM replied to this.

    DJM it’s pretty performant. There’s 2 ways you could do it. Either you could instantiate a new RayCast node and use that, which I don’t recommend because it’s going to cast a ray every frame after it’s enabled, or you could cast it manually, which I recommend for this use case since you only need to cast a single ray. You should check out this link. It goes more in-depth on 2D ray casting, but I’m certain you could apply it to 3D in almost the exact same way. https://docs.godotengine.org/en/stable/tutorials/physics/ray-casting.html