$npx -y skills add quodsoler/unreal-engine-skills --skill ue-physics-collisionUse when implementing collision detection, trace queries, physics simulation, or physical interactions in Unreal Engine. Triggers on: 'collision', 'trace', 'LineTrace', 'line trace', 'overlap', 'physics', 'hit result', 'sweep', 'collision channel', 'physics body', 'Chaos', 'raytr
| 1 | # UE Physics & Collision |
| 2 | |
| 3 | You are an expert in Unreal Engine's physics and collision systems, including collision channels, trace queries, collision events, physics bodies, and the Chaos physics engine. |
| 4 | |
| 5 | --- |
| 6 | |
| 7 | ## Step 1: Read Project Context |
| 8 | |
| 9 | Read `.agents/ue-project-context.md` to confirm: |
| 10 | - UE version (Chaos is the default physics backend from UE 5.0; PhysX was deprecated) |
| 11 | - Which modules need `"PhysicsCore"` and `"Engine"` in their `Build.cs` |
| 12 | - Whether the project uses skeletal meshes with physics assets, or primarily static mesh collision |
| 13 | - Dedicated server targets (affects whether physics simulation should run server-side) |
| 14 | |
| 15 | --- |
| 16 | |
| 17 | ## Step 2: Identify the Need |
| 18 | |
| 19 | Ask which area applies if not stated: |
| 20 | 1. **Collision setup** — channels, profiles, responses on components |
| 21 | 2. **Trace queries** — line traces, sweeps, overlap queries for gameplay logic |
| 22 | 3. **Collision events** — OnComponentHit, OnBeginOverlap, OnEndOverlap delegates |
| 23 | 4. **Physics simulation** — rigid body sim, forces, impulses, damping, constraints |
| 24 | 5. **Physical materials** — friction, restitution, surface type detection |
| 25 | |
| 26 | --- |
| 27 | |
| 28 | ## Collision Channels & Profiles |
| 29 | |
| 30 | ### ECollisionChannel — built-in channels |
| 31 | |
| 32 | ```cpp |
| 33 | ECC_WorldStatic, ECC_WorldDynamic, ECC_Pawn, ECC_PhysicsBody, |
| 34 | ECC_Vehicle, ECC_Destructible // object channels (what an object IS) |
| 35 | ECC_Visibility, ECC_Camera // trace channels (used for queries) |
| 36 | // Custom: ECC_GameTraceChannel1..ECC_GameTraceChannel18 |
| 37 | ``` |
| 38 | |
| 39 | **Responses**: `ECR_Ignore` / `ECR_Overlap` (events, no block) / `ECR_Block` (physical block + events). |
| 40 | |
| 41 | **Built-in profiles**: `BlockAll`, `BlockAllDynamic`, `OverlapAll`, `OverlapAllDynamic`, `Pawn`, `PhysicsActor`, `NoCollision`. |
| 42 | |
| 43 | ### Setting Collision in C++ |
| 44 | |
| 45 | ```cpp |
| 46 | MyMesh->SetCollisionProfileName(TEXT("BlockAll")); // preferred — sets all at once |
| 47 | MyMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); |
| 48 | // ECollisionEnabled: NoCollision | QueryOnly | PhysicsOnly | QueryAndPhysics |
| 49 | MyMesh->SetCollisionObjectType(ECC_PhysicsBody); |
| 50 | MyMesh->SetCollisionResponseToAllChannels(ECR_Block); |
| 51 | MyMesh->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap); |
| 52 | MyMesh->SetCollisionResponseToChannel(ECC_Camera, ECR_Ignore); |
| 53 | ``` |
| 54 | |
| 55 | ### Object Type Channels vs Trace Channels |
| 56 | |
| 57 | **Object type channels** describe what an actor IS (Pawn, WorldDynamic, Vehicle). Every component has exactly one object type. **Trace channels** are used for queries — they define what a trace is LOOKING FOR (Visibility, Camera, Weapon). This distinction determines which query function to use: `ByObjectType` matches the target's object type channel; `ByChannel` uses the querier's trace channel and checks responses. Most gameplay traces use trace channels (`ECC_Visibility`, custom `Weapon`); overlap queries for "find all pawns" use object type (`ECC_Pawn`). |
| 58 | |
| 59 | ### Custom Channels — DefaultEngine.ini |
| 60 | |
| 61 | ```ini |
| 62 | [/Script/Engine.CollisionProfile] |
| 63 | +DefaultChannelResponses=(Channel=ECC_GameTraceChannel1,DefaultResponse=ECR_Block,bTraceType=True,bStaticObject=False,Name="Weapon") |
| 64 | +DefaultChannelResponses=(Channel=ECC_GameTraceChannel2,DefaultResponse=ECR_Block,bTraceType=False,bStaticObject=False,Name="Interactable") |
| 65 | +Profiles=(Name="Interactable",CollisionEnabled=QueryAndPhysics,ObjectTypeName="Interactable",CustomResponses=((Channel="Weapon",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Block))) |
| 66 | ``` |
| 67 | |
| 68 | `bTraceType=True` = trace channel; `bTraceType=False` = object type channel. They use separate query functions. |
| 69 | |
| 70 | See `references/collision-channel-setup.md` for full profile examples. |
| 71 | |
| 72 | --- |
| 73 | |
| 74 | ## Trace Queries |
| 75 | |
| 76 | ### FCollisionQueryParams |
| 77 | |
| 78 | ```cpp |
| 79 | FCollisionQueryParams Params; |
| 80 | Params.TraceTag = TEXT("WeaponTrace"); // for profiling/debug |
| 81 | Params.bTraceComplex = false; // false=simple hull (fast); true=per-poly (expensive) |
| 82 | Params.bReturnPhysicalMaterial = true; // populates Hit.PhysMaterial |
| 83 | Params.bReturnFaceIndex = false; // expensive, only when needed |
| 84 | Params.AddIgnoredActor(this); |
| 85 | Params.AddIgnoredComponent(MyComp); |
| 86 | ``` |
| 87 | |
| 88 | ### World-Level Trace Functions (C++) — from `WorldCollision.h` via `UWorld` |
| 89 | |
| 90 | ```cpp |
| 91 | FHitResult Hit; |
| 92 | // By trace channel |
| 93 | GetWorld()->LineTraceSingleByChannel(Hit, Start, End, ECC_Visibility, Params); |
| 94 | GetWorld()->LineTraceMultiByChannel(Hits, Start, End, ECC_Visibility, Params); |
| 95 | // By object type |
| 96 | FCollisionObjectQueryParams ObjParams(ECC_PhysicsBody); |
| 97 | ObjParams.AddObjectTypesToQuery(ECC_WorldDynamic); |
| 98 | GetWorld()->LineTraceSingleByObjectType(Hit, Start, End, ObjParams, Params); |
| 99 | // By profile |
| 100 | GetWorld()->LineT |