Skip to main content
Version: Next (dev)

Troubleshooting

Common reasons a visual script does not do what you expect, roughly in the order worth checking.

My script does nothing at all

Is the game actually simulating? OnSimulationStarted and most gameplay logic only run once you run the scene. Placing an object in the viewport is not enough. Initialize and OnActivated do fire in the editor, which is why a script can look half-alive before you press play.

Is the script assigned? Select the object, find its script component, and check the Script Class is set to your asset.

Is there an entry point? A graph with no entry point can never run. Entry points have an execution pin on the right only, and live under Add Event Handler in the palette. See Entry Points and Events.

Is the component active? An inactive component gets Initialize but not OnActivated, OnSimulationStarted or Update. An object also counts as inactive if any of its parents are.

Did the asset transform? Check the asset curator for errors on the script asset. A script that failed to compile does not run.

Part of my graph never runs

Follow the execution pins. A node with an incoming execution pin that is not connected will never execute, no matter what its data pins are wired to. This is the single most common cause.

Trace the grey arrows from your entry point. If the chain stops before the node you care about, that is your answer.

Check which output of a branch is connected. Branch has separate True and False outputs. Wiring only one is normal — but make sure it is the one you meant.

Loops have two outputs. LoopBody runs per iteration; Completed runs once at the end. Work that should happen after the loop must be on Completed, not trailing off the body.

A pin will not connect

Check the colours. Pins are colour-coded by type, and incompatible ones grey out while you drag. See the colour table.

Execution pins only connect to execution pins. The grey arrow-shaped ones are a separate system from the round data pins.

Some conversions need a node. Numbers convert freely and most things convert to text, but pulling a real value out of a Variant needs Variant_ConvertTo. Variants show as pink pins.

One input, many outputs. A data output can feed as many inputs as you like, but an input pin takes a single connection. Connecting a second one replaces the first.

My values are wrong

Unconnected input pins use their property value. If a node has an input pin with nothing wired to it, it uses whatever is typed into the property grid — which is often zero. An input you think is connected but is not will silently behave as zero.

Check for truncation. ToInt truncates rather than rounds, so 0.9 becomes 0.

Colours are linear. MakeRGBA expects linear values, not the 0–255 numbers a colour picker shows.

Movement depends on frame rate. If something moves at different speeds on different machines, you are missing a multiplication by the DeltaTime output of Update.

Debug it by drawing

The fastest way to find out what a script is really doing:

NodeUse for
Draw3DTextShowing a live value next to the object it belongs to
String_FormatLabelling that value so you can tell readouts apart
DrawLineMaking a direction or distance visible
DrawCrossMarking a position
InfoValues that change rarely, where you want a history

Put a Info on the execution line where you suspect flow is not arriving. If it never prints, the problem is upstream. The raycast recipe shows the whole pattern.

Debug drawing is compiled out of shipped builds, so there is no cost to leaving it in during development.

Coroutine problems

My coroutine never resumes. Check the entry point's Coroutine Mode. On Stop Other — the default — a new trigger cancels the run already in progress. If the event fires repeatedly, the path may be restarting before it ever finishes. Switch to Don't Create New to let it complete.

Everything happens at once. Allow Overlap starts a new run per event without stopping the old ones. If a hundred overlapping runs is not what you wanted, pick one of the other modes.

The script kept running after the object was disabled. Coroutines outlive deactivation. Call StopAllCoroutines from OnDeactivated.

The frame hangs. A WhileLoop whose condition never becomes false runs forever within one frame. Add a Yield in the loop body so it spans frames, or fix the condition.

Object and component problems

A lookup returns nothing. TryGetComponentOfBaseType returns nothing when the object has no such component — the "Try" is meaningful. Follow it with IsValid and branch, rather than letting later nodes act on nothing.

A reference went stale. Objects deleted during play invalidate references held across a wait. Re-check with IsValid after any coroutine pause.

Another component was not ready. Initialize runs before other components have necessarily initialised. Move cross-component lookups to OnSimulationStarted, which is guaranteed to run only after every component in the scene has initialised.

Node problems

I cannot find a node from a tutorial. Most nodes are generated from whatever your project loads, so a node may genuinely not exist in your project. See Reading the Palette. Search by name rather than by menu position — palettes differ between projects.

Searching finds nothing. Generated nodes follow strict naming: the function's own name for functions, On<Message> for handlers, Send<Message> for senders. Search rather than browse — the palette groups nodes into folders, and a node is not always in the folder you would expect. Entry points in particular are all in Events, not under the type they belong to.

See Also