Skip to content

Commit

Permalink
docs: Update raycast docs
Browse files Browse the repository at this point in the history
  • Loading branch information
eonarheim committed May 9, 2024
1 parent 42933d0 commit 90dfd8d
Showing 1 changed file with 106 additions and 0 deletions.
106 changes: 106 additions & 0 deletions site/docs/09-math/07-ray.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,112 @@ section: Math

[[Ray]]'s are a useful tool for testing if geometry intersects a line of sight with [[Collider.rayCast]]. You can think of them as a point in space with a direction.

Examples where ray casting can be useful
* Custom physics implementations (platformers, slopes, etc)
* Line of sight AI
* Proximity detection

:::warning

If you start a raycast from inside an [[Actor]] it will hit that Actor first unless you explicitly exclude it. See Raycast Options below.

:::

## Scene Testing

It is possible to test against all actors in a [[Scene]] at once.

```typescript

// given a scene reference
const game = new ex.Engine({...});
game.start();


const ray = new ex.Ray(ex.vec(100, 100), ex.Vector.Right);
game.currentScene.physics.rayCast(ray, {...});

// or in a custom scene
class MyScene extends ex.Scene {

someRayTestMethod() {

const ray = new ex.Ray(ex.vec(100, 100), ex.Vector.Right);
this.physics.rayCast(ray, {...});
}
}

```

## Scene Raycast Options

Excalibur's raycast can be optionally configured in a variety of ways. By default if no options are provided to the `rayCast(ray, ...)` the options will be

```typescript
const hits = scene.physics.rayCast(ray, {
searchAllColliders: true,
collisionGroup: CollisionGroup.All,
collisionMask: CollisionGroup.All.mask,
ignoreCollisionGroupAll: false,
maxDistance: Infinity,
filter: null,
})
```

### Search All Colliders

By default the raycast will not stop after the first hit is found, if you'd like to only get the first hit set `searchAllColliders: false`

### Max Distance

Distance is in terms of pixels, this is the maximum length along the ray to search for colliders.

### Hit Filtering

Using the `filter` option you can do complex filtering logic to reject or accept potential hits.

```typescript
scene.physics.rayCast(ray, {
filter: (potentialHit: RayCastHit) => {
// return true to accept the hit
// return false to reject the hit
return true;
}
})
```

### Collision Mask

The collision mask it a bit mask with a 1 in the place for each collision group category you'd like to consider in the raycast. For example this is useful if all your enemies share a collision group category. See [collision group documentation](/docs/collisiongroups/) for more information.

You may want to pair this with `ignoreCollisionGroupAll: true` to avoid default actors which collide with everything including specific rayCast masks.

```typescript
const playerGroup = new ex.CollisionGroup('player', 0b0001, ~0b0001);
const enemyGroup = new ex.CollisionGroup('enemy', 0b0010, ~0b0010);
...

// this raycast will only actors with the 1 in the second place, so enemyGroup
const enemyHits = scene.physics.rayCast(ray, {
collisionMask: 0b0010;
});

// this raycast will only actors with the 1 in the first and second place, so playerGroup and enemyGroup
const playerAndEnemyHits = scene.physics.rayCast(ray, {
collisionMask: 0b0011;
});
```

### Collision Group

The `collisionGroup` searches for actors that match a specific collision group.

You may want to pair this with `ignoreCollisionGroupAll: true` to avoid default actors which collide with everything including specific rayCast groups.

## Specific Actor Geometry Testing

If you have a specific actor or geometry that you know you will test against, all [[Collider]] types implement `rayCast(ray, [maxDistance])`.

```typescript
const actor = new ex.Actor({
pos: ex.vec(200, 100),
Expand Down

0 comments on commit 90dfd8d

Please sign in to comment.