Line Trace For Objects / Multi Line Trace For Objects¶
At a glance
Lives in: Blueprint API / Collision -
Target: Kismet System Library -
Filters by: an array of collision Object Types such as Pawn,
WorldDynamic, or a custom object type -
Returns: the single version returns a Boolean plus one FHitResult;
the multi version returns a Boolean plus an array of FHitResult values -
Fails by: returning false with no useful hit, silently -
Official docs: Line Trace For Objects
and Multi Line Trace For Objects
The one-minute version¶
Line Trace For Objectsasks: what is the first query-collidable component along this line whose Object Type is in my list?Multi Line Trace For Objectsreturns all hits along the segment that match one of those Object Types. Unlike a multi trace by channel, it is not the "overlaps until the first blocking response" query.- Object Type belongs to each Primitive Component. An Actor can own several components with different object types, and a multi trace can therefore produce more than one hit for one Actor.
- An object trace does not ask whether a component blocks
Visibility,Camera, or another Trace Channel. It selects by the component's Object Type. - That means an object trace for
Pawncan ignore an unselectedWorldStaticwall and find a Pawn behind it. Use a channel/profile query when blockers and line of sight are part of the question. - The Object Types pin must contain at least one type. An empty array matches
nothing and returns
false/empty. - These nodes only report collision. They do not apply damage, interact, de-duplicate actors, or replicate the result.
What it actually does¶
A Primitive Component has one collision Object Type. Common built-in types
include WorldStatic, WorldDynamic, Pawn, PhysicsBody, and Vehicle.
Projects can add custom object types in Project Settings -> Collision.
The object-trace nodes convert the Blueprint Object Types array into a collision
object mask, build query options, and raycast from Start to End:
pseudocode of the engine behavior - not engine source
function LineTraceForObjects(World, Start, End, ObjectTypes, Options):
ObjectMask = collision channels represented by ObjectTypes
Params = query params from TraceComplex, ActorsToIgnore, and IgnoreSelf
Hit = World.LineTraceSingleByObjectType(Start, End, ObjectMask, Params)
draw debug line if requested
return Hit.found, Hit
function MultiLineTraceForObjects(World, Start, End, ObjectTypes, Options):
ObjectMask = collision channels represented by ObjectTypes
Params = query params from Options
Hits = World.LineTraceMultiByObjectType(Start, End, ObjectMask, Params)
draw debug line if requested
return Hits is not empty, Hits
The line has no thickness and no persistent existence. It is one physics-scene query performed when execution reaches the node.
Object Type vs Trace Channel¶
This is the reason both node families exist.
Object query: "what kind of collision object is it?"¶
Line Trace For Objects
Object Types = [Pawn, PhysicsBody]
The query includes components whose Collision Object Type is Pawn or
PhysicsBody. It does not choose a Visibility/Camera response column.
Channel query: "how does it answer this question?"¶
Line Trace By Channel
Trace Channel = Visibility
The query checks every candidate component's response to the Visibility
Trace Channel: Block, Overlap, or Ignore.
| Gameplay question | Better first filter | Why |
|---|---|---|
| "Find the first Pawn or Physics Body, regardless of other object categories." | Object Types | The categories themselves define inclusion. |
| "What blocks the player's interaction ray?" | Trace Channel such as Visibility or custom Interact |
Walls and targets can all answer one query consistently. |
| "What blocks this weapon shot?" | Custom weapon Trace Channel/profile | Occluders and damageable targets both need deliberate responses. |
| "List every selected object category along this scanner beam." | Multi For Objects | It gathers matching object types along the segment. |
Object Type and Trace Channel are both collision channels internally, but they play different roles in the editor. Each component chooses one Object Type and has a response to every query/movement channel.
The wall-behind-target trap¶
Suppose a line crosses these components:
Start ---- [WorldStatic wall] ---- [Pawn target] ---- End
With Object Types [Pawn], the wall is outside the object mask. The object
query can report the Pawn even though the wall would block movement and a
Visibility trace.
That is correct for the question "which Pawns lie on this ray?" It is wrong for the question "which Pawn can I shoot or see?"
Safer first-game options:
- Use a custom Trace Channel such as
Weaponand configure walls and valid targets to Block it. - Trace by channel to the first occluder, then inspect/filter that Hit Actor or Hit Component.
- For a scanner that intentionally sees through walls, keep the object trace and make that rule explicit.
Do not add a class check after an object trace and assume that retroactively created line of sight. The collision filter already decided what the ray could pass through.
What exactly comes back¶
Single Line Trace For Objects¶
Outputs:
- Return Value:
trueif the query found a matching hit;falseotherwise; - Out Hit: one
FHitResultdescribing the first matching hit encountered.
On false, execution continues and Out Hit is still a struct value, but it
does not contain a target you should use. Branch before Break Hit Result.
Line Trace For Objects
-> Branch Return Value
true -> Break Hit Result -> validate/filter Hit Actor
false -> no matching object type along this segment
Multi Line Trace For Objects¶
Outputs:
- Return Value:
trueif at least one matching hit was found; - Out Hits: an array of
FHitResultvalues for matching components along the segment; empty on no hit.
Epic's object-trace contract differs from channel multi traces: Multi For Objects gathers the selected Object Types along the line instead of stopping under the channel rule "overlap responses up to and including the first Block."
Each result still carries Time and Distance. If gameplay needs a guaranteed
nearest-first choice, select the minimum Distance/Time or sort explicitly rather
than hiding that requirement behind array index assumptions.
One Actor may appear several times because several owned components or bodies
matched. De-duplicate by Hit Actor when gameplay should happen once per actor:
HitActors = empty Set<Actor>
For Each Out Hits
-> Break Hit Result
-> Is Valid (Hit Actor)
-> if Hit Actor not in HitActors
add to HitActors
apply gameplay once
Object Types belong to components¶
The Object Types array does not filter Actor classes. It filters collision components.
An Actor might have:
BP_Character
CapsuleComponent Object Type = Pawn
SkeletalMeshComponent Object Type = Pawn (or another configured type)
InteractionSphere Object Type = WorldDynamic
A trace for Pawn can hit the capsule/mesh but skip the interaction sphere. A
trace for WorldDynamic can do the reverse. Hit Actor can be the same Actor
for several matching component records.
After collision filtering, inspect Hit Component, class, tags, interfaces,
owner/team state, or already-hit state as the gameplay requires. Object Type is
a broad collision category, not proof that every Pawn is an enemy or every
WorldDynamic object is interactable.
Building the Object Types array¶
In Blueprint, drag from Object Types and use Make Array, then add each desired
Object Type:
Make Array<Object Type Query>
[0] Pawn
[1] PhysicsBody
-> Line Trace For Objects.Object Types
Custom object types are defined under Project Settings -> Engine -> Collision. After adding one, give relevant collision components/presets that Object Type and verify existing assets use the intended setup.
Do not confuse:
- Object Type
Pawnwith the C++/Blueprint classPawn; - Object Type
WorldDynamicwith Mobility = Movable; - a custom Object Type with an Actor Tag or Gameplay Tag carrying the same text.
They are separate systems. A Static Mesh Component can be movable while using an object type chosen for your gameplay collision design.
Start, End, and self-ignore¶
Object traces use the same endpoint math as other line traces:
Start = Camera World Location
End = Start + Camera Forward Vector * Range
Ignore Self adds the Actor associated with the Blueprint world context to the
ignore set when that context provides one. Actors to Ignore adds explicit
Actor references.
For a weapon Actor, self may be the weapon rather than its owning Pawn. Build the ignore list deliberately:
Actors to Ignore:
self weapon
Get Owner (shooter)
Get Instigator (if configured)
Ignored actors are removed before Object Type matching. If the desired target is accidentally in a reused ignore array, the trace silently misses it.
Trace Complex and query collision¶
A matching Object Type is necessary but not sufficient.
- The component needs collision enabled for queries (
Query OnlyorQuery and Physics, as appropriate).Physics Onlydoes not make it traceable. - The component needs usable simple or complex collision for the selected
Trace Complexmode and asset setup. - Trace Complex = false asks against simple collision shapes.
- Trace Complex = true asks against complex/triangle collision where the component and asset support it.
Complex collision can provide precise triangle surfaces but usually costs more and can differ from the simplified shape used for movement. Choose based on the gameplay question, not because "complex" sounds more accurate.
An Object Type match does not turn query collision on and does not create collision geometry for a visual-only mesh.
When it fails (and what failure does)¶
No hit produces false; the multi array is empty and the single Out Hit is not
a target to consume.
Common causes:
- Object Types is empty. There is no category to match.
- The desired component has another Object Type. You expected the Actor's class or tag to imply collision category.
- Query collision is disabled. The object can render or simulate physics while this query cannot see it.
- Start/End are wrong. Zero length, wrong camera, wrong forward vector, or too-short range makes the line miss.
- The target is ignored.
Actors to IgnoreandIgnore Selfare hard filters. - Simple vs complex collision does not match the asset setup. The line is testing a different representation than expected.
- The ray is too thin. A nearby target can be visually close to the line without mathematically crossing it; use a sphere/capsule/box trace when the question needs thickness.
- You expected Trace Channel behavior. A
Visibilityresponse cannot help a node that has no Visibility channel input.
Failure does not print a warning, try every Object Type, extend the range, switch to complex collision, or run a fallback trace.
The pattern everyone actually uses¶
Single selected-category query¶
Input Scan
-> Camera Start/End
-> Line Trace For Objects
Object Types = [PhysicsBody]
Ignore Self = true
-> Branch Return Value
-> Break Hit Result
-> Is Valid (Hit Component)
-> inspect/apply scanner behavior
Multi scanner with once-per-actor filtering¶
Multi Line Trace For Objects
Object Types = [Pawn, PhysicsBody]
-> Branch Return Value
-> For Each Out Hits
-> Break Hit Result
-> add unique Hit Actor to Results set
-> sort/select by explicit distance or priority
The C++ twin, for the curious (our own example code):
void ATrainingScanner::Scan(const FVector& Start, const FVector& End)
{
FCollisionObjectQueryParams ObjectTypes;
ObjectTypes.AddObjectTypesToQuery(ECC_Pawn);
ObjectTypes.AddObjectTypesToQuery(ECC_PhysicsBody);
FCollisionQueryParams Params(SCENE_QUERY_STAT(TrainingScan), false);
Params.AddIgnoredActor(this);
TArray<FHitResult> Hits;
GetWorld()->LineTraceMultiByObjectType(
Hits, Start, End, ObjectTypes, Params);
for (const FHitResult& Hit : Hits)
{
HandleCandidate(Hit.GetActor(), Hit.GetComponent(), Hit.Distance);
}
}
Draw Debug Type and cost¶
Draw Debug Type visualizes the attempted line and hits. Its colors and
duration do not affect query filtering or results.
Use For One Frame for a trace run every frame and For Duration for a
button-pressed trace you need time to inspect. Turn persistent debug drawing
off after diagnosis so old lines do not look like current results.
Line traces are focused physics queries, but cost scales with how often they run, collision complexity, and how many multi hits you process. Do not put a multi trace on every Actor's Tick by habit. Use input/events, timers at a meaningful rate, overlap state, or a manager when the gameplay does not need a per-frame ray.
Multiplayer¶
The trace runs only in the local world that executes it. The node does not replicate its Boolean or hit results.
- Run trusted weapon damage, pickup grants, or objective rules on the server.
- Clients can run cosmetic/predictive traces for responsive highlighting and effects, but the server still validates authoritative gameplay.
- Collision/relevancy and replicated transforms can differ briefly across machines, so identical Start/End and Object Types do not promise identical local arrays at every instant.
Replicate the approved gameplay result or resulting state, not a raw per-frame multi-hit array by default.
What these nodes do not do¶
- They do not use an Actor class, Actor Tag, Component Tag, or Gameplay Tag as the initial filter.
- They do not ask for a response to
Visibility,Camera, or another Trace Channel. - They do not guarantee walls outside the selected Object Types will occlude a selected target.
- They do not add thickness; use sphere/capsule/box object traces for that.
- They do not apply damage, interact, sort by gameplay priority, or de-duplicate Actor results.
- They do not leave a detector in the world or maintain overlap state.
- They do not replicate or establish network authority.
Lookalikes - which one do I want?¶
| Node | Use when | Watch out |
|---|---|---|
| Line Trace For Objects | You need the first hit belonging to one of several Object Types. | Unselected blockers do not answer a channel/visibility question. |
| Multi Line Trace For Objects | You need every matching selected type along the segment. | De-duplicate actors/components and choose order explicitly. |
| Line Trace By Channel | Components should answer one Trace Channel and the first Block should stop the ray. | The target must have the intended response to that channel. |
| Multi Line Trace By Channel | You need overlap responses up to and including the first channel Block. | Its stopping contract differs from Multi For Objects. |
| Line Trace By Profile | A named collision profile should define the query. | Inspect the profile rather than assuming its name explains every response. |
| Sphere / Capsule / Box Trace For Objects | The selected-type query needs forgiving thickness. | Shape size changes when and what it touches. |
| Sphere / Box / Capsule Overlap Actors | You need a fresh volume query at one location, not a swept line. | No Start-to-End path. |
| Get Overlapping Actors | A component already maintains current overlap state. | It reads tracked occupancy; it does not trace a new segment. |
Rule of thumb: object trace for categories, channel trace for responses and occlusion, shape trace for thickness, and overlap query for occupancy.
Going deeper¶
- Line Trace By Channel - the response-channel version and its first-block contract.
- Break Hit Result - status, distance, actor, component, and contact fields returned by each hit.
- Sphere Trace, Capsule Trace, and Multi Trace basics - adding thickness and understanding channel multi results.
- Collision presets, channels, and responses - Object Type, Trace Channel, Block/Overlap/Ignore, and Query collision setup.
- Get Overlapping Actors / Components / Is Overlapping Actor - current maintained overlap state instead of a one-shot ray.
- Line Trace vs projectile vs overlap weapon hits - choosing the detection model before the filter.
- Official docs: Line Trace For Objects, Multi Line Trace For Objects, Using a Multi Line Trace by Object, Traces Overview, and UKismetSystemLibrary::LineTraceSingleForObjects.
- Engine source (requires engine access - we do not reproduce it here):
Blueprint wrappers
UKismetSystemLibrary::LineTraceSingleForObjectsandUKismetSystemLibrary::LineTraceMultiForObjectsinEngine/Source/Runtime/Engine/Private/KismetSystemLibrary.cpp; world object queries inEngine/Source/Runtime/Engine/Private/Collision/WorldCollision.cpp.