Quick answer: Collision Presets often override individual channel responses. Set Collision Presets to Custom on components where you want per-channel responses, then edit the channel responses directly. Object channels classify objects; Trace channels classify queries — use the right one for each.
Here is how to fix Unreal collision channel not blocking correctly. You create a custom channel called “Bullets” for gunfire traces. You set your glass wall to Block on Bullets so line traces break it. The bullets pass through instead. You check the glass component’s settings — Bullets response is set to Block. But the component is using a Collision Preset that overrides Bullets. Presets vs direct channel responses is where most collision confusion lives.
The Symptom
A collider with a specific channel response does not actually respond that way. Possible observations:
- Block response behaves like Overlap
- Line trace finds objects it should not find
- Pawn walks through a wall marked Block Pawn
- Custom channel settings appear correct in Inspector but ignored at runtime
What Causes This
Collision Preset overriding. A Collision Preset (OverlapAllDynamic, BlockAll, etc.) sets channel responses in a predefined pattern. Individual channel response edits are ignored unless you switch the preset to “Custom.” In the Inspector, the response fields appear editable even when the preset overrides them.
Object Channel vs Trace Channel. Object Channels classify what something IS (Pawn, Vehicle, PhysicsBody, your custom “Enemy”). Trace Channels classify what a query IS (Visibility, Camera, your custom “Bullet”). An object declared as Object Type Bullet but queried via Trace Channel Bullet is a mismatch.
Channels not declared in DefaultEngine.ini. Custom channels are stored in DefaultEngine.ini under [/Script/Engine.CollisionProfile]. If you added channels on one machine but the file did not commit, other team members have different channel mappings — same channel index, different names.
Default response too permissive. A new channel’s default response is Block. If you wanted Overlap by default, every component needs explicit Overlap — easy to miss some.
Wrong ECC index in C++. ECC_GameTraceChannel1 is the first custom channel. Channels are position-based. Adding a new channel can shift indexes if not in careful order. C++ code referencing hardcoded ECC_GameTraceChannel3 may now reference a different channel.
The Fix
Step 1: Use Custom preset to expose channel responses. Select the component. In Collision section:
- Collision Presets: set to Custom
- Object Type: pick what this object IS (e.g. WorldStatic for walls)
- Collision Responses: edit per channel (Block / Overlap / Ignore)
With Custom preset, channel responses below are actually used. With any other preset, responses shown are the preset’s and your edits may be ignored.
Step 2: Create custom collision presets. For common configurations, create named presets instead of manually setting Custom on every component:
- Edit > Project Settings > Engine > Collision
- Preset section: New
- Name: “GlassWall”
- Collision Enabled: Query and Physics
- Object Type: WorldStatic
- Responses: Block on Bullets, Overlap on Visibility, Block on WorldStatic, etc.
Components using the “GlassWall” preset all share this configuration. Edit the preset to update all at once.
Step 3: Use the correct channel type in traces.
// For a trace against custom Trace Channel (Bullets)
FHitResult Hit;
FVector Start = GetActorLocation();
FVector End = Start + GetActorForwardVector() * 10000;
// ECC_GameTraceChannel1 = first custom Trace Channel
GetWorld()->LineTraceSingleByChannel(Hit, Start, End, ECC_GameTraceChannel1);
// For query against Object Type (enemies)
TArray<AActor*> FoundEnemies;
UKismetSystemLibrary::SphereOverlapActors(
this, GetActorLocation(), 500,
{UEngineTypes::ConvertToObjectType(ECC_GameTraceChannel1)},
AEnemy::StaticClass(), TArray<AActor*>(), FoundEnemies);
Line traces use Trace Channels. Overlap queries use Object Types. Do not mix.
Step 4: Commit DefaultEngine.ini. Custom channel definitions live in:
[/Script/Engine.CollisionProfile]
+DefaultChannelResponses=(Channel=ECC_GameTraceChannel1,
DefaultResponse=ECR_Block,bTraceType=True,bStaticObject=False,Name="Bullets")
+Profiles=(Name="GlassWall",...)
Commit this file. Check that git diff includes it when adding channels.
Using SetCollisionResponseToChannel in Code
To change collision at runtime:
MyComponent->SetCollisionResponseToChannel(
ECC_Pawn, ECR_Overlap);
MyComponent->SetCollisionResponseToAllChannels(ECR_Ignore);
MyComponent->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
Runtime changes override the preset. Useful for temporary state (ghost mode, phase-through).
Debugging Collision
Console: show Collision makes collision shapes visible. Hovering over a component in the outliner shows its channel responses in the Details panel. For trace debugging, stat Collision shows per-channel query counts.
For Blueprint-friendly debugging, use the Line Trace For Objects (Debug Trace Type = For Duration) which draws the trace path for 3 seconds in the viewport. You see exactly where traces go and what they hit.
“Collision is powerful and explicit. Set Preset to Custom, configure channels intentionally, document your scheme. Unreal collision stops being a mystery.”
Related Issues
For replication issues, see Unreal Actor Replication Not Working. For input issues, Enhanced Input Action Not Firing covers related setup patterns.
Custom preset exposes responses. Object Type classifies actors. Trace Channel classifies queries. Know the difference.