test_raycasting.gd 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. extends Test
  2. const OPTION_TEST_CASE_HIT_FROM_INSIDE = "Test case/Hit from inside"
  3. var _hit_from_inside = false
  4. var _do_raycasts = false
  5. func _ready():
  6. var options = $Options
  7. options.add_menu_item(OPTION_TEST_CASE_HIT_FROM_INSIDE, true, false)
  8. options.option_changed.connect(self._on_option_changed)
  9. await start_timer(0.5).timeout
  10. if is_timer_canceled():
  11. return
  12. _do_raycasts = true
  13. func _physics_process(delta):
  14. super._physics_process(delta)
  15. if not _do_raycasts:
  16. return
  17. _do_raycasts = false
  18. Log.print_log("* Start Raycasting...")
  19. clear_drawn_nodes()
  20. for node in $Shapes.get_children():
  21. var body = node as PhysicsBody2D
  22. var space_state = body.get_world_2d().direct_space_state
  23. var body_name = String(body.name).substr("RigidBody".length())
  24. Log.print_log("* Testing: %s" % body_name)
  25. var center = body.position
  26. # Raycast entering from the top.
  27. var res = _add_raycast(space_state, center - Vector2(0, 100), center)
  28. Log.print_log("Raycast in: %s" % ("HIT" if res else "NO HIT"))
  29. # Raycast exiting from inside.
  30. center.x -= 20
  31. res = _add_raycast(space_state, center, center + Vector2(0, 200))
  32. Log.print_log("Raycast out: %s" % ("HIT" if res else "NO HIT"))
  33. # Raycast all inside.
  34. center.x += 40
  35. res = _add_raycast(space_state, center, center + Vector2(0, 40))
  36. Log.print_log("Raycast inside: %s" % ("HIT" if res else "NO HIT"))
  37. if body_name.begins_with("Concave"):
  38. # Raycast inside an internal face.
  39. center.x += 20
  40. res = _add_raycast(space_state, center, center + Vector2(0, 40))
  41. Log.print_log("Raycast inside face: %s" % ("HIT" if res else "NO HIT"))
  42. func _on_option_changed(option, checked):
  43. match option:
  44. OPTION_TEST_CASE_HIT_FROM_INSIDE:
  45. _hit_from_inside = checked
  46. _do_raycasts = true
  47. func _add_raycast(space_state, pos_start, pos_end):
  48. var params = PhysicsRayQueryParameters2D.new()
  49. params.from = pos_start
  50. params.to = pos_end
  51. params.hit_from_inside = _hit_from_inside
  52. var result = space_state.intersect_ray(params)
  53. var color
  54. if result:
  55. color = Color.GREEN.darkened(0.2)
  56. else:
  57. color = Color.RED.darkened(0.5)
  58. # Draw raycast line.
  59. add_line(pos_start, pos_end, color)
  60. # Draw raycast arrow.
  61. add_line(pos_end, pos_end + Vector2(-5, -10), color)
  62. add_line(pos_end, pos_end + Vector2(5, -10), color)
  63. if result:
  64. # Draw raycast hit pos.
  65. var hit_pos = result.position
  66. add_circle(hit_pos, 4.0, Color.YELLOW)
  67. # Draw raycast hit normal.
  68. add_line(hit_pos, hit_pos + result.normal * 16.0, Color.YELLOW)
  69. return result