Advertisement
doggphin

Physics.gd

Jul 22nd, 2022 (edited)
1,220
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. extends Node3D
  2.  
  3.  
  4. var space_state : PhysicsDirectSpaceState3D
  5. var default_layer_mask : int = 429467295
  6. var sphere_shape : SphereShape3D = SphereShape3D.new()
  7. var capsule_shape : CapsuleShape3D = CapsuleShape3D.new()
  8.  
  9.  
  10. func _ready():
  11.     process_priority = -100
  12.  
  13.  
  14. func _physics_process(_delta):
  15.     space_state = get_world_3d().direct_space_state
  16.  
  17. # Works, can have problems if include_overlap==false and called while shape is touching collider where cast_motion()
  18. # thinks a collision should happen at cast_motion_data[1] but get_rest_info() at cast_motion_data[1] doesn't record it
  19. func shape_cast(shape: Shape3D, shape_transform: Transform3D, destination: Vector3, out_results: Dictionary = {}, include_overlap: bool = false, layer_mask: int = default_layer_mask, collide_areas:bool = true, collide_bodies:bool = true) -> bool:
  20.     var query : PhysicsShapeQueryParameters3D = PhysicsShapeQueryParameters3D.new()
  21.     query.collide_with_areas = collide_areas
  22.     query.collide_with_bodies = collide_bodies
  23.     query.shape = shape
  24.     query.collision_mask = layer_mask
  25.     query.transform = shape_transform
  26.     if include_overlap:
  27.         var hit_data : Dictionary = space_state.get_rest_info(query)
  28.         if hit_data.size() != 0:
  29.             out_results["point"] = hit_data["point"]
  30.             out_results["normal"] = hit_data["normal"]
  31.             out_results["safe_distance"] = 0
  32.             out_results["hit_distance"] = 0
  33.             return true
  34.     query.motion = destination - shape_transform.origin
  35.     var cast_motion_data : Array = space_state.cast_motion(query)
  36.     var cast_collided : bool = !(cast_motion_data[0] == 1 && cast_motion_data[1] == 1)
  37.     if cast_collided:
  38.         query.transform.origin += query.motion * cast_motion_data[1]
  39.         var hit_data : Dictionary = space_state.get_rest_info(query)
  40.         if hit_data.size() != 0:
  41.             out_results["point"] = hit_data["point"]
  42.             out_results["normal"] = hit_data["normal"]
  43.             out_results["safe_distance"] = cast_motion_data[0]
  44.             out_results["hit_distance"] = cast_motion_data[1]
  45.             return true
  46.         else:
  47.             print("cast_motion() predicted a hit but get_rest_info() didn't pick it up.")
  48.             return false
  49.     return false
  50.  
  51. # Works
  52. func sphere_cast(origin: Vector3, destination: Vector3, radius: float, out_results: Dictionary = {}, include_overlap: bool = false, layer_mask: int = default_layer_mask, collide_areas: bool = true, collide_bodies: bool = true) -> bool:
  53.     sphere_shape.radius = radius
  54.     var shape_transform : Transform3D = Transform3D.IDENTITY
  55.     shape_transform.origin = origin
  56.     return shape_cast(sphere_shape, shape_transform, destination, out_results, include_overlap, layer_mask, collide_areas, collide_bodies)
  57.  
  58. # Works
  59. func sphere_cast_direction(origin: Vector3, direction: Vector3, distance: float, radius: float, out_results: Dictionary = {}, include_overlap: bool = false, layer_mask: int = default_layer_mask, collide_areas: bool = true, collide_bodies: bool = true) -> bool:
  60.     return sphere_cast(origin, origin + (direction * distance), radius, out_results, include_overlap, layer_mask, collide_areas, collide_bodies)
  61.  
  62. # Works
  63. func capsule_cast(point1: Vector3, point2: Vector3, radius: float, direction: Vector3, distance: float, out_results: Dictionary = {}, include_overlap: bool = false, layer_mask: int = default_layer_mask, collide_areas: bool = true, collide_bodies: bool = true) -> bool:
  64.     var point1_to_point2 = point2 - point1
  65.     var point1_to_point2_length : float = (point1_to_point2).length()
  66.     capsule_shape.height = point1_to_point2_length + radius * 2
  67.     var shape_transform : Transform3D = Transform3D.IDENTITY
  68.     shape_transform.origin = point1 + (point1_to_point2 * 0.5)
  69.     shape_transform.basis = Basis(Quaternion(Vector3.UP, point1_to_point2 / point1_to_point2_length))
  70.     return shape_cast(capsule_shape, shape_transform, shape_transform.origin + (direction.normalized() * distance), out_results, include_overlap, layer_mask, collide_areas, collide_bodies)
  71.  
  72.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement