Talos docs

PickOptions

Since 0.6

Options for {@link WorldQuery.pick}.

Plain text

Signature

export interface PickOptions {
  /** Sweep a sphere of this radius instead of a thin ray, metres — easier to aim at something small. Default 0. */
  radius?: number
  /** Whether a trigger volume stops the pick. Default **false**, unlike `raycast`: a pick sees through volumes. */
  triggers?: boolean
  /** What the pick passes through — the picker, whose own collider a ray from its eye starts inside. */
  exclude?: EntityHandle | string | (EntityHandle | string)[]
  /** A body heavier than this, kg, answers null. */
  maxMass?: number
  /** Only an entity with this tag answers; anything else in the way answers null. */
  tag?: string
}

Import: import type { PickOptions } from "@argus/api"

Members

MemberSignatureDescription
radiusradius?: numberSweep a sphere of this radius instead of a thin ray, metres — easier to aim at something small. Default 0.
triggerstriggers?: booleanWhether a trigger volume stops the pick. Default false, unlike raycast: a pick sees through volumes.
excludeexclude?: EntityHandle | string | (EntityHandle | string)[]What the pick passes through — the picker, whose own collider a ray from its eye starts inside.
maxMassmaxMass?: numberA body heavier than this, kg, answers null.
tagtag?: stringOnly an entity with this tag answers; anything else in the way answers null.

Example

The tested fixture packages/critic/fixtures/play/door-and-key/key-pickup.ts.

import type { Behavior, Ctx } from "@argus/api"

/**
 * The key: collected when the player reaches it.
 *
 * Two ways in, so the fixture works on every engine build: the trigger volume on this
 * entity fires `onTrigger` when the physics layer reports the player overlapping it, and a
 * proximity check each tick catches the case where a controller has no body to overlap
 * with. Either way the outcome is one `key-collected` event and the key leaving the level.
 */
interface State {
  collected: boolean
}

interface Props {
  /** Metres within which the player counts as touching the key. Default 1.2. */
  radius?: number
}

function collect(ctx: Ctx<State, Props>, by: string): void {
  if (ctx.state.collected) return
  ctx.state.collected = true
  ctx.events.emit("key-collected", { key: ctx.entity.id, tag: "key", by })
  ctx.log("key collected", { by })
  // Out of the level rather than despawned: nothing else needs to know it existed.
  ctx.entity.translate([0, -100, 0])
}

export default {
  init(ctx) {
    ctx.state.collected = false
  },
  update(ctx) {
    if (ctx.state.collected) return
    const radius = typeof ctx.props.radius === "number" ? ctx.props.radius : 1.2
    const near = ctx.world.query({ tag: "player", near: ctx.entity, radius })
    if (near.length > 0) collect(ctx, near[0]!.id)
  },
  onTrigger(ctx, trigger) {
    if (trigger.entering && trigger.other.hasTag("player")) collect(ctx, trigger.other.id)
  },
} satisfies Behavior<State, Props>