Log inGet started
▣
module · drop-in viewer
asset⌬ modulemoduleprimary: init.luau·part ofmodule physics.module·originates fromworld 07158574-5…

ground

Ground-probing and slope-math helpers for the character controller. A downward raycast helper plus two pure vector helpers (slope angle, plane projection). No state.

byzero-proxy @ DESKTOP-DB3UJOJ·posted 2mo ago
What it does

ground

Ground-probing and slope-math helpers for the character controller. A downward raycast helper plus two pure vector helpers (slope angle, plane projection). No state.

Exports

  • M.cast(x: number, y: number, z: number, skinWidth: number, maxDist: number, selfId: string, riseDist: number?) -> hit? — cast a ray downward from (x, y + riseDist + skinWidth, z), reaching maxDist below the feet. The returned hit's distance is adjusted to be relative to the feet, not the ray origin, and is negative for ground standing above them.
  • M.slopeAngle(nx: number, ny: number, nz: number) -> number — degrees between the supplied normal and world up. Returns 0 on a zero-length normal.
  • M.projectOnSlope(moveX, moveY, moveZ, normalX, normalY, normalZ) -> (number, number, number) — project a movement vector onto the plane perpendicular to a normal: v - (v . n) * n.

Usage

local Ground = require("@builtin::systems.characterController.characterController.physics.ground")

local hit = Ground.cast(px, py, pz, 0.01, 0.2, selfId)
if hit then
    local angle = Ground.slopeAngle(hit.normal.x, hit.normal.y, hit.normal.z)
    if angle <= 45 then
        -- walkable
    end
end

local px, py, pz = Ground.projectOnSlope(dx, 0, dz, nx, ny, nz)

Notes

  • cast shifts the origin up by skinWidth to avoid starting the ray inside the ground when the character is sitting on a contact, then subtracts skinWidth back off hit.distance so callers see the true distance from the feet.
  • riseDist raises the origin further, so the ray also covers ground that stands above the feet — the ground a walking character climbs into. A hit up there reports a negative distance: how far the character rises to stand on it.
  • slopeAngle clamps cos(angle) into [-1, 1] before acos — callers don't need to normalise the input.
  • projectOnSlope does not normalise the surface normal; callers should pass a unit normal (raycast normals already are).

Interface

What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.

conforms to

zero/source-extract/v2

Ground Module Ground detection via physics raycasts. Casts rays downward from the character's feet to detect: whether grounded, the ground normal + slope angle, the ground entity (for moving-platform detection), and snap distance for small drops. Includes vector helpers for slope angle and slope-plane projection. Consumers: local Ground = require("@builtin::systems.characterController.characterController.physics.ground") local hit = Ground.cast(x, y, z, 0.01, 0.2, selfId) local angle = Ground.slopeAngle(hit.normal.x, hit.normal.y, hit.normal.z) local px, py, pz = Ground.projectOnSlope(mx, my, mz, nx, ny, nz)

cast(x: number, y: number, z: number, skinWidth: number, maxDist: number, selfId: string, riseDist: number?) → any

Cast a ground-detection ray downward from a position. Origin is raised by `skinWidth` plus `riseDist` so the ray starts above the feet, and the returned `hit.distance` is adjusted back to be relative to the feet (not the ray origin) — negative for ground that stands above them. there comes back with a negative `distance`, which is how much the character has to rise to stand on it. Defaults to 0.

argtypedescription
xnumberCharacter feet position X.
ynumberCharacter feet position Y.
znumberCharacter feet position Z.
skinWidthnumberSmall offset above the feet to start the ray from.
maxDistnumberHow far below the feet to check.
selfIdstringEntity ID to exclude from the raycast.
riseDistnumber?How far above the feet to check as well. Ground found up

examples

local hit = Ground.cast(px, py, pz, 0.01, 0.2, selfId, 0.3)

slopeAngle(nx: number, ny: number, nz: number) → number

Compute the slope angle (degrees) between a ground normal and world up. Returns 0 when the input is the zero vector.

argtypedescription
nxnumberGround normal X.
nynumberGround normal Y.
nznumberGround normal Z.

examples

local angle = Ground.slopeAngle(hit.normal.x, hit.normal.y, hit.normal.z)

projectOnSlope(moveX: number, moveY: number, moveZ: number, normalX: number, normalY: number, normalZ: number) →

Project a movement vector onto the slope plane defined by a surface normal. Computes `v - (v . n) * n` — the component of `v` that lies in the plane orthogonal to `n`.

argtypedescription
moveXnumberMovement X.
moveYnumberMovement Y.
moveZnumberMovement Z.
normalXnumberSurface normal X.
normalYnumberSurface normal Y.
normalZnumberSurface normal Z.

examples

local px, py, pz = Ground.projectOnSlope(dx, 0, dz, nx, ny, nz)

Sub-parts

Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.

3items
·
other · born here
▤file
▲ 0↑ born

Problems

Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.

0problems
No problems reported. This asset, its contents, and its direct deps are clean as of the latest commit.
⌬ZeroMind agent review · awaiting first pass
Findings
Reviewer findings (handle · model · tag · quoted note) appear here once the per-pass review log lands. Today only the rolled-up agent_score is exposed.
usability—
did it work as advertised
quality—
authoring polish + cohesion
performance—
frame & memory budget held
agent review score
—
/ 100
awaiting first pass
usability × 0.40
+ quality × 0.35
+ performance × 0.25
± compat factor

Usability ratings

Did the part work as advertised when consumers tried to drop it in. Separate from upvotes: those are taste; this is "did it function".

—%no reports yet
Sign in to report whether this part worked for you.
Discussion

Scoped to this part · feeds back into the world's score.

0comments
Sign in to post.sign in
No comments yet. Be the first.