raycastAll method

  1. @override
List<RaycastResult<ShapeHitbox>> raycastAll(
  1. Vector2 origin, {
  2. required int numberOfRays,
  3. double startAngle = 0,
  4. double sweepAngle = tau,
  5. double? maxDistance,
  6. List<Ray2>? rays,
  7. bool hitboxFilter(
    1. ShapeHitbox candidate
    )?,
  8. List<ShapeHitbox>? ignoreHitboxes,
  9. List<RaycastResult<ShapeHitbox>>? out,
})
override

Casts rays uniformly between startAngle to startAngle+sweepAngle from the given origin and returns all hitboxes and intersection points the rays hit. numberOfRays is the number of rays that should be casted.

maxDistance can be provided to limit the raycasts to only return hits within this distance from the ray origin.

If the rays argument is provided its Ray2s are populated with the rays needed to perform the operation. If there are less objects in rays than the operation requires, the missing Ray2 objects will be created and added to rays.

You can provide a hitboxFilter callback to define which hitboxes to consider and which to ignore. This callback will be called with every prospective hitbox, and only if the callback returns true will the hitbox be considered. Otherwise, the ray will go straight through it. One common use case is ignoring the component that is shooting the ray.

If you have a list of hitboxes to ignore in advance, you can provide them via the ignoreHitboxes argument.

If out is provided the RaycastResults in that list be modified and returned with the result. If there are less objects in out than the result requires, the missing RaycastResult objects will be created.

Implementation

@override
List<RaycastResult<ShapeHitbox>> raycastAll(
  Vector2 origin, {
  required int numberOfRays,
  double startAngle = 0,
  double sweepAngle = tau,
  double? maxDistance,
  List<Ray2>? rays,
  bool Function(ShapeHitbox candidate)? hitboxFilter,
  List<ShapeHitbox>? ignoreHitboxes,
  List<RaycastResult<ShapeHitbox>>? out,
}) {
  final isFullCircle = (sweepAngle % tau).abs() < 0.0001;
  final angle = sweepAngle / (numberOfRays + (isFullCircle ? 0 : -1));
  final results = <RaycastResult<ShapeHitbox>>[];
  final direction = Vector2(1, 0);
  for (var i = 0; i < numberOfRays; i++) {
    Ray2 ray;
    if (i < (rays?.length ?? 0)) {
      ray = rays![i];
    } else {
      ray = Ray2.zero();
      rays?.add(ray);
    }
    ray.origin.setFrom(origin);
    direction
      ..setValues(0, -1)
      ..rotate(startAngle - angle * i);
    ray.direction = direction;

    RaycastResult<ShapeHitbox>? result;
    if (i < (out?.length ?? 0)) {
      result = out![i];
    } else {
      result = RaycastResult();
      out?.add(result);
    }
    result = raycast(
      ray,
      maxDistance: maxDistance,
      hitboxFilter: hitboxFilter,
      ignoreHitboxes: ignoreHitboxes,
      out: result,
    );

    if (result != null) {
      results.add(result);
    }
  }
  return results;
}