Skip to main content
Version: Next (dev)

Raycast and Debug Draw

Cast a ray downward every frame, draw it on screen, and do something different depending on whether it hit. This recipe covers the two things you will want as soon as a script stops behaving: seeing what it is doing, and branching on a result.

Thirteen nodes, and it is worth building once even if you never ship it.

What you need in the scene

The graph

The execution line runs left to right:

Update [exec] -> DrawLine [exec]
DrawLine [exec] -> Raycast [exec]
Raycast [exec] -> Draw3DText [exec]
Draw3DText [exec] -> Branch [exec]
Branch [True] -> DrawCross [exec]
DrawCross [exec] -> SendMsgSetColor [exec]

The data feeding it:

GetGlobalPosition [Result] -> Raycast [Start]
GetGlobalPosition [Result] -> DrawLine [Start]
GetGlobalPosition [Result] -> Add [A]
Make [Result] -> Raycast [Direction]
Make [Result] -> Add [B]
Add [Result] -> DrawLine [End]

Raycast [Result] -> Branch [Condition]
Raycast [Result] -> String_Format [Params[0]]
Raycast [HitPosition] -> DrawCross [Position]

String_Format [Result] -> Draw3DText [Text]
Add [Result] -> Draw3DText [Position]

Node configuration:

NodeSettingValue
RaycastDirection(0, 0, -1) — straight down
RaycastShape TypesStatic | Dynamic
String_FormatTextHit: {0}

How it works

Update runs the whole graph once per frame. It is the entry point to reach for when a script needs to check something continuously rather than react to an event.

Make — the one in the Vec3 folder, since several types have a Make node — builds the ray direction as a value node. Its three inputs are set as constants in the property grid, giving (0, 0, -1) — straight down, since Z is up. Add adds that same vector to the object's position to work out where the ray ends, which is what DrawLine needs to draw it.

Raycast returns two things worth wiring:

  • Result — a boolean, true if the ray hit something.
  • HitPosition — where it hit, only meaningful when Result is true.

Branch takes that boolean and splits the execution line. Only the True output is connected here, so the cross and the colour message happen on a hit and nothing happens otherwise.

Note that Result is used twice at once: once to branch on, and once as a value formatted into on-screen text by String_Format. A data output can feed as many inputs as you like.

The debugging pattern to steal

Even if you never need a raycast, this is how you find out what a script is doing:

  • Draw3DText — print a value in the world, next to the object it belongs to. Combine with String_Format to label it, so you can tell several readouts apart.
  • DrawLine — make an invisible direction or distance visible.
  • DrawCross — mark a point in space, such as a hit position or a spawn point.
  • Info — when a value changes rarely and you want a history rather than a live readout.

Drawing every frame from Update is normal for these. They cost nothing in a shipped build because debug rendering is compiled out.

Adapting it

  • Aim the ray somewhere else — change the Make constants, or feed it GetGlobalDirForwards to cast along the object's facing.
  • Control the range — scale the direction vector with Multiply before it reaches both the raycast and the Add.
  • React to a miss — connect the Branch False output as well.
  • Hit only certain things — narrow the raycast's Shape Types, or use its collision layer setting.

Source

PlasmaEngine2/Data/UnitTests/GameEngineTest/VisualScript/Data/PhysicsScript.plVisualScriptClassAsset

See Also