Programming: Is the blast radius affected by objects?

A bomb explodes and everyone within its radius dies, but if you're behind a wall, you shouldn't take any damage. Unfortunately, I have no idea how to program this. I'm using Godot with C#/GDScript (I use both).

Do you have any idea how to implement something like this?

Thanks for helpful answers

(1 votes)
Loading...

Similar Posts

Subscribe
Notify of
6 Answers
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
BeamerBen
1 year ago

General logic should look

  1. Place what is hit in the right circle
  2. Check for each object whether a wall is in the way
  3. Call an event or otherwise somehow refresh the state on the hit objects where nothing is in the way.

Note that you do not make unnecessary checks here per frame and instead you should use zb events or something temporary.

Your question should actually be whether it is 2d/3d.

My time with Godot and Unity is unfortunately too long since I can say this now, but in the Doku to collision you will surely find a solution for the individual steps.

Alternatively, you could also define safe zones on the map if, in the setting, the bomb has an influence almost everywhere on the map, but there is no information. However, if my second proposal for a solution were to be found, it would be very important for the scenario. This is suitable if there are only little safe zones and otherwise so many objects that such line of sight checks would be intense to performance.

BeamerBen
1 year ago
Reply to  ILoveCode

Sure, but my first proposal would be technically better for a few objects. And probably easier to implement.

Such a check as you need to be written in is reasonable, but in a 3D room you would probably have so many checks so that it works properly and if you do too little checks you have difficult to debugging bugs. In a 2D room, the whole is simpler, but I don’t really see an advantage, except for a lot of objects. So usually you should keep the number of such checks as low as possible.

So I would rather make a check per (relevant) object. You just have less trouble.

BeamerBen
1 year ago

Well, you’re doing a Ray Cast to any relevant object.

Instead of hundreds of raycasts in all directions, you’ll make exactly one raycast for every object in the vicinity, namely to the object. And then you’ll see what this Raycast is doing, whether there’s a wall in the way or not.

Here in the Godot Doku: https://docs.godotengine.org/en/stable/classes/class_physicsdirectspacestate2d.html#class-physicsdirectspacestate2d

Here ChatGPT generated example code (if you don’t have to fix yourself, only serves as an example of how this could work, ChatGPT also likes to make mistakes and thinks methods, I haven’t checked now):

extends Node2D

var radius = 100.0
var collision_mask = 1 << 0 # Adjust based on the layers your objects are in

func _ready():
   get_objects_in_radius()

func get_objects_in_radius():
   var center_position = self.global_position
   var space_state = get_world_2d().direct_space_state
   var query_parameters = Physics2DShapeQueryParameters.new()
   var shape = CircleShape2D.new()
   shape.radius = radius
   query_parameters.set_shape(shape)
   query_parameters.transform = Transform2D(0, center_position)
   query_parameters.collision_mask = collision_mask
   var results = space_state.intersect_shape(query_parameters)

   for result in results:
       if result.collider is YourTargetType and has_line_of_sight(center_position, result.collider.global_position):
           result.collider.trigger_event() # Assuming `trigger_event` is the method you want to call

func has_line_of_sight(start_pos, end_pos):
   var space_state = get_world_2d().direct_space_state
   var result = space_state.intersect_ray(start_pos, end_pos, [], collision_mask)
   return result.empty() # Returns true if no collision was found along the ray

# YourTargetType class needs to have this method
# func trigger_event():
#   # Code to trigger the event