claude-code-arcane 2.2.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +104 -55
  3. package/agents/career/career-strategist.md +88 -0
  4. package/agents/career/cv-reviewer.md +81 -0
  5. package/agents/career/hiring-manager.md +68 -0
  6. package/agents/career/mock-interviewer.md +76 -0
  7. package/agents/freelance/client-screener.md +84 -0
  8. package/agents/freelance/discovery-call.md +65 -0
  9. package/agents/freelance/pipeline-strategist.md +99 -0
  10. package/agents/freelance/proposal-reviewer.md +82 -0
  11. package/agents/game/ue-blueprint-specialist.md +125 -0
  12. package/agents/game/ue-gas-specialist.md +133 -0
  13. package/agents/game/ue-umg-specialist.md +131 -0
  14. package/dist/cli.js +57 -13
  15. package/docs/RELEASE-SETUP.md +1 -1
  16. package/docs/SKILLS-CATALOG.md +67 -4
  17. package/docs/USER-GUIDE.md +77 -72
  18. package/docs/agent-hierarchy.md +21 -1
  19. package/docs/presentations/build_arcane_deck.py +2 -2
  20. package/docs/presentations/build_arcane_deck_12.py +2 -2
  21. package/hooks/detect-unreal.sh +90 -0
  22. package/package.json +2 -2
  23. package/profiles/freelance.yaml +43 -0
  24. package/profiles/job-hunt.yaml +5 -2
  25. package/profiles/unreal-dev.yaml +97 -0
  26. package/rules/drafter-reviewer.md +16 -3
  27. package/rules/freelance-guardrails.md +53 -0
  28. package/rules/gamedev/unreal-code.md +125 -0
  29. package/skills/career-registry/SKILL.md +95 -0
  30. package/skills/career-registry/scripts/career_registry.py +488 -0
  31. package/skills/client-screen/SKILL.md +83 -0
  32. package/skills/client-screen/references/red-flags.md +95 -0
  33. package/skills/cover-letter/SKILL.md +4 -3
  34. package/skills/cv-tailor/SKILL.md +11 -2
  35. package/skills/freelance-deliver/SKILL.md +90 -0
  36. package/skills/freelance-hunt/SKILL.md +126 -0
  37. package/skills/freelance-hunt/references/templates/Connects.md +39 -0
  38. package/skills/freelance-hunt/references/templates/Contrato.md +60 -0
  39. package/skills/freelance-hunt/references/templates/Propuesta.md +66 -0
  40. package/skills/freelance-kickoff/SKILL.md +94 -0
  41. package/skills/freelance-pipeline/SKILL.md +109 -0
  42. package/skills/freelance-pipeline/scripts/import_history.py +425 -0
  43. package/skills/freelance-profile/SKILL.md +93 -0
  44. package/skills/freelance-proposal/SKILL.md +112 -0
  45. package/skills/freelance-scan/SKILL.md +196 -0
  46. package/skills/freelance-scan/references/dedup.md +35 -0
  47. package/skills/freelance-scan/references/platforms.md +167 -0
  48. package/skills/freelance-scan/scripts/freelance_search.py +1077 -0
  49. package/skills/install-mcp/SKILL.md +135 -46
  50. package/skills/install-mcp/references/unreal-operations.md +55 -0
  51. package/skills/interview-prep/SKILL.md +11 -3
  52. package/skills/job-aplicar/SKILL.md +5 -1
  53. package/skills/job-hunt/SKILL.md +17 -0
  54. package/skills/job-outcome/SKILL.md +15 -1
  55. package/skills/job-upskill/SKILL.md +10 -2
  56. package/skills/ue-actor-component-architecture/SKILL.md +509 -0
  57. package/skills/ue-actor-component-architecture/references/actor-lifecycle.md +301 -0
  58. package/skills/ue-actor-component-architecture/references/component-types.md +592 -0
  59. package/skills/ue-ai-navigation/SKILL.md +526 -0
  60. package/skills/ue-ai-navigation/references/behavior-tree-patterns.md +392 -0
  61. package/skills/ue-ai-navigation/references/behavior-tree-workflow.md +107 -0
  62. package/skills/ue-ai-navigation/references/custom-bttask.md +104 -0
  63. package/skills/ue-ai-navigation/references/eqs-reference.md +423 -0
  64. package/skills/ue-animation-system/SKILL.md +521 -0
  65. package/skills/ue-animation-system/references/anim-notify-reference.md +486 -0
  66. package/skills/ue-animation-system/references/locomotion-setup.md +550 -0
  67. package/skills/ue-async-threading/SKILL.md +433 -0
  68. package/skills/ue-async-threading/references/thread-safety-guide.md +213 -0
  69. package/skills/ue-async-threading/references/threading-patterns.md +345 -0
  70. package/skills/ue-audio-system/SKILL.md +527 -0
  71. package/skills/ue-audio-system/references/audio-setup-patterns.md +700 -0
  72. package/skills/ue-blueprints/SKILL.md +134 -0
  73. package/skills/ue-blueprints/references/communication.md +82 -0
  74. package/skills/ue-character-movement/SKILL.md +475 -0
  75. package/skills/ue-character-movement/references/cmc-extension-patterns.md +335 -0
  76. package/skills/ue-character-movement/references/movement-pipeline.md +189 -0
  77. package/skills/ue-cpp-foundations/SKILL.md +533 -0
  78. package/skills/ue-cpp-foundations/references/components-and-gc.md +107 -0
  79. package/skills/ue-cpp-foundations/references/container-patterns.md +544 -0
  80. package/skills/ue-cpp-foundations/references/delegate-patterns.md +497 -0
  81. package/skills/ue-cpp-foundations/references/gameplay-classes-cpp.md +136 -0
  82. package/skills/ue-cpp-foundations/references/property-specifiers.md +306 -0
  83. package/skills/ue-data-assets-tables/SKILL.md +527 -0
  84. package/skills/ue-data-assets-tables/references/asset-loading-patterns.md +306 -0
  85. package/skills/ue-data-assets-tables/references/data-driven-design.md +378 -0
  86. package/skills/ue-editor-tools/SKILL.md +523 -0
  87. package/skills/ue-editor-tools/references/detail-customization-patterns.md +395 -0
  88. package/skills/ue-editor-tools/references/editor-module-setup.md +480 -0
  89. package/skills/ue-game-features/SKILL.md +477 -0
  90. package/skills/ue-game-features/references/experience-system.md +222 -0
  91. package/skills/ue-game-features/references/game-feature-patterns.md +308 -0
  92. package/skills/ue-gameplay-abilities/SKILL.md +518 -0
  93. package/skills/ue-gameplay-abilities/references/ability-task-reference.md +391 -0
  94. package/skills/ue-gameplay-abilities/references/gameplay-effect-reference.md +397 -0
  95. package/skills/ue-gameplay-abilities/references/gas-setup-patterns.md +369 -0
  96. package/skills/ue-gameplay-framework/SKILL.md +466 -0
  97. package/skills/ue-gameplay-framework/references/framework-class-map.md +243 -0
  98. package/skills/ue-input-system/SKILL.md +394 -0
  99. package/skills/ue-input-system/references/cpp-setup.md +131 -0
  100. package/skills/ue-input-system/references/enhanced-input-workflow.md +117 -0
  101. package/skills/ue-input-system/references/input-action-reference.md +731 -0
  102. package/skills/ue-mass-entity/SKILL.md +476 -0
  103. package/skills/ue-mass-entity/references/mass-entity-patterns.md +319 -0
  104. package/skills/ue-mass-entity/references/mass-fragment-reference.md +119 -0
  105. package/skills/ue-materials-rendering/SKILL.md +526 -0
  106. package/skills/ue-materials-rendering/references/material-parameter-reference.md +216 -0
  107. package/skills/ue-materials-rendering/references/post-process-settings.md +383 -0
  108. package/skills/ue-module-build-system/SKILL.md +487 -0
  109. package/skills/ue-module-build-system/references/build-cs-reference.md +418 -0
  110. package/skills/ue-module-build-system/references/common-build-errors.md +381 -0
  111. package/skills/ue-naming-conventions/SKILL.md +142 -0
  112. package/skills/ue-naming-conventions/references/asset-name-modifiers.md +233 -0
  113. package/skills/ue-naming-conventions/references/content-structure.md +83 -0
  114. package/skills/ue-networking-replication/SKILL.md +452 -0
  115. package/skills/ue-networking-replication/references/replication-patterns.md +526 -0
  116. package/skills/ue-networking-replication/references/rpc-decision-guide.md +393 -0
  117. package/skills/ue-niagara-effects/SKILL.md +531 -0
  118. package/skills/ue-niagara-effects/references/niagara-data-interfaces.md +491 -0
  119. package/skills/ue-niagara-effects/references/niagara-parameter-types.md +153 -0
  120. package/skills/ue-niagara-effects/references/niagara-workflow.md +115 -0
  121. package/skills/ue-packaging/SKILL.md +116 -0
  122. package/skills/ue-physics-collision/SKILL.md +423 -0
  123. package/skills/ue-physics-collision/references/collision-channel-setup.md +218 -0
  124. package/skills/ue-physics-collision/references/trace-patterns.md +499 -0
  125. package/skills/ue-procedural-generation/SKILL.md +505 -0
  126. package/skills/ue-procedural-generation/references/pcg-node-reference.md +381 -0
  127. package/skills/ue-procedural-generation/references/procedural-mesh-patterns.md +940 -0
  128. package/skills/ue-project-context/SKILL.md +305 -0
  129. package/skills/ue-sequencer-cinematics/SKILL.md +506 -0
  130. package/skills/ue-sequencer-cinematics/references/sequencer-patterns.md +629 -0
  131. package/skills/ue-serialization-savegames/SKILL.md +524 -0
  132. package/skills/ue-serialization-savegames/references/save-system-architecture.md +705 -0
  133. package/skills/ue-state-trees/SKILL.md +489 -0
  134. package/skills/ue-state-trees/references/state-tree-mass-integration.md +184 -0
  135. package/skills/ue-state-trees/references/state-tree-patterns.md +321 -0
  136. package/skills/ue-testing-debugging/SKILL.md +520 -0
  137. package/skills/ue-testing-debugging/references/automation-test-patterns.md +387 -0
  138. package/skills/ue-testing-debugging/references/profiling-commands.md +357 -0
  139. package/skills/ue-ui-umg-slate/SKILL.md +431 -0
  140. package/skills/ue-ui-umg-slate/references/common-ui-setup.md +484 -0
  141. package/skills/ue-ui-umg-slate/references/widget-types.md +487 -0
  142. package/skills/ue-world-level-streaming/SKILL.md +518 -0
  143. package/skills/ue-world-level-streaming/references/streaming-patterns.md +414 -0
  144. package/templates/gamedev/unreal-project-context.md +107 -0
@@ -0,0 +1,499 @@
1
+ # Trace Patterns Reference
2
+
3
+ Common trace query patterns for gameplay mechanics in Unreal Engine 5. All patterns use the C++ world query API (`UWorld::LineTraceSingleByChannel` etc.) with `FCollisionQueryParams`. For Blueprint-callable wrappers with built-in debug drawing, see `UKismetSystemLibrary`.
4
+
5
+ ---
6
+
7
+ ## Pattern 1: Hitscan Weapon
8
+
9
+ Single line trace from camera or muzzle, returning the first blocking hit. Reports impact point, surface normal, hit actor, and physical surface type for decal/sound selection.
10
+
11
+ ```cpp
12
+ // MyWeaponComponent.h
13
+ UFUNCTION()
14
+ void FireHitscan(const FVector& MuzzleLocation, const FVector& AimDirection, float Range);
15
+
16
+ // MyWeaponComponent.cpp
17
+ void UMyWeaponComponent::FireHitscan(const FVector& MuzzleLocation,
18
+ const FVector& AimDirection,
19
+ float Range)
20
+ {
21
+ const FVector TraceStart = MuzzleLocation;
22
+ const FVector TraceEnd = MuzzleLocation + AimDirection * Range;
23
+
24
+ FCollisionQueryParams Params;
25
+ Params.TraceTag = TEXT("WeaponTrace");
26
+ Params.bTraceComplex = false; // simple hull — sufficient for shooting
27
+ Params.bReturnPhysicalMaterial = true; // needed for surface type
28
+ Params.AddIgnoredActor(GetOwner()); // don't hit self
29
+
30
+ FHitResult Hit;
31
+ const bool bHit = GetWorld()->LineTraceSingleByChannel(
32
+ Hit,
33
+ TraceStart,
34
+ TraceEnd,
35
+ ECC_GameTraceChannel1, // "Weapon" channel
36
+ Params
37
+ );
38
+
39
+ if (bHit)
40
+ {
41
+ // Impact data
42
+ const FVector ImpactPoint = Hit.ImpactPoint;
43
+ const FVector ImpactNormal = Hit.ImpactNormal;
44
+ AActor* HitActor = Hit.GetActor();
45
+
46
+ // Surface type for decal / sound selection
47
+ EPhysicalSurface Surface = SurfaceType_Default;
48
+ if (UPhysicalMaterial* PhysMat = Hit.PhysMaterial.Get())
49
+ {
50
+ Surface = UPhysicalMaterial::DetermineSurfaceType(PhysMat);
51
+ }
52
+
53
+ // Apply damage
54
+ if (HitActor)
55
+ {
56
+ FPointDamageEvent DamageEvent(DamageAmount, Hit, AimDirection, DamageTypeClass);
57
+ HitActor->TakeDamage(DamageAmount, DamageEvent, GetOwner()->GetInstigatorController(), GetOwner());
58
+ }
59
+ }
60
+
61
+ // Debug draw (editor/development only)
62
+ #if ENABLE_DRAW_DEBUG
63
+ DrawDebugLine(GetWorld(), TraceStart, bHit ? Hit.ImpactPoint : TraceEnd,
64
+ FColor::Red, false, 1.f, 0, 1.f);
65
+ if (bHit) DrawDebugSphere(GetWorld(), Hit.ImpactPoint, 5.f, 8, FColor::Green, false, 1.f);
66
+ #endif
67
+ }
68
+ ```
69
+
70
+ ---
71
+
72
+ ## Pattern 2: Melee Attack — Sphere Sweep
73
+
74
+ Sweeps a sphere along an arc for melee hit detection. Captures multiple targets in one call with `SweepMultiByChannel`. Avoids hitting the same actor twice.
75
+
76
+ ```cpp
77
+ void UMeleeComponent::PerformMeleeSwing(const FVector& SwingStart,
78
+ const FVector& SwingEnd,
79
+ float AttackRadius)
80
+ {
81
+ FCollisionShape Sphere = FCollisionShape::MakeSphere(AttackRadius);
82
+
83
+ FCollisionQueryParams Params;
84
+ Params.bTraceComplex = false;
85
+ Params.AddIgnoredActor(GetOwner());
86
+
87
+ TArray<FHitResult> Hits;
88
+ const bool bAnyHit = GetWorld()->SweepMultiByChannel(
89
+ Hits,
90
+ SwingStart,
91
+ SwingEnd,
92
+ FQuat::Identity,
93
+ ECC_Pawn, // "Pawn" channel — hits characters and pawns
94
+ Sphere,
95
+ Params
96
+ );
97
+
98
+ // Deduplicate actors (sweep may return multiple hits per actor)
99
+ TSet<AActor*> DamagedActors;
100
+ for (const FHitResult& Hit : Hits)
101
+ {
102
+ AActor* HitActor = Hit.GetActor();
103
+ if (HitActor && !DamagedActors.Contains(HitActor))
104
+ {
105
+ DamagedActors.Add(HitActor);
106
+ HitActor->TakeDamage(MeleeDamage,
107
+ FDamageEvent(),
108
+ GetOwner()->GetInstigatorController(),
109
+ GetOwner());
110
+ }
111
+ }
112
+
113
+ #if ENABLE_DRAW_DEBUG
114
+ DrawDebugSphere(GetWorld(), SwingEnd, AttackRadius, 12, FColor::Orange, false, 0.5f);
115
+ #endif
116
+ }
117
+ ```
118
+
119
+ ---
120
+
121
+ ## Pattern 3: Interaction / Use — Line Trace from Camera
122
+
123
+ Player looks at an object and presses interact. Uses a trace channel dedicated to interaction so non-interactable geometry is filtered automatically by the Interactable object type's channel response.
124
+
125
+ ```cpp
126
+ // In PlayerController or Character
127
+
128
+ void AMyCharacter::TryInteract()
129
+ {
130
+ APlayerController* PC = Cast<APlayerController>(GetController());
131
+ if (!PC) return;
132
+
133
+ FVector CameraLocation;
134
+ FRotator CameraRotation;
135
+ PC->GetPlayerViewPoint(CameraLocation, CameraRotation);
136
+
137
+ const FVector TraceStart = CameraLocation;
138
+ const FVector TraceEnd = CameraLocation + CameraRotation.Vector() * InteractRange;
139
+
140
+ FCollisionQueryParams Params;
141
+ Params.AddIgnoredActor(this);
142
+
143
+ FHitResult Hit;
144
+ // Use object type query to find only Interactable objects
145
+ FCollisionObjectQueryParams ObjectParams;
146
+ ObjectParams.AddObjectTypesToQuery(ECC_GameTraceChannel3); // "Interactable" type
147
+
148
+ const bool bHit = GetWorld()->LineTraceSingleByObjectType(
149
+ Hit, TraceStart, TraceEnd, ObjectParams, Params
150
+ );
151
+
152
+ if (bHit)
153
+ {
154
+ if (AActor* HitActor = Hit.GetActor())
155
+ {
156
+ if (HitActor->GetClass()->ImplementsInterface(UInteractableInterface::StaticClass()))
157
+ {
158
+ IInteractableInterface::Execute_Interact(HitActor, this);
159
+ }
160
+ }
161
+ }
162
+ }
163
+ ```
164
+
165
+ ---
166
+
167
+ ## Pattern 4: Ground Detection / IsGrounded
168
+
169
+ Character or physics object checks whether it is on the ground. Uses a short downward line trace against WorldStatic and WorldDynamic. Common for jump/fall logic without relying on `CharacterMovementComponent`.
170
+
171
+ ```cpp
172
+ bool UMyMovementComponent::IsGrounded() const
173
+ {
174
+ const FVector Start = GetOwner()->GetActorLocation();
175
+ const FVector End = Start + FVector::DownVector * (GroundCheckDistance + CapsuleHalfHeight);
176
+
177
+ FCollisionQueryParams Params;
178
+ Params.bTraceComplex = false;
179
+ Params.AddIgnoredActor(GetOwner());
180
+
181
+ FHitResult Hit;
182
+ const bool bHit = GetWorld()->LineTraceSingleByChannel(
183
+ Hit,
184
+ Start,
185
+ End,
186
+ ECC_Visibility,
187
+ Params
188
+ );
189
+
190
+ return bHit && Hit.bBlockingHit;
191
+ }
192
+
193
+ // Slope normal — for movement alignment or sliding
194
+ FVector UMyMovementComponent::GetGroundNormal() const
195
+ {
196
+ FHitResult Hit;
197
+ const FVector Start = GetOwner()->GetActorLocation();
198
+ const FVector End = Start - FVector::UpVector * (GroundCheckDistance + CapsuleHalfHeight);
199
+
200
+ FCollisionQueryParams Params;
201
+ Params.bTraceComplex = false;
202
+ Params.AddIgnoredActor(GetOwner());
203
+
204
+ if (GetWorld()->LineTraceSingleByChannel(Hit, Start, End, ECC_Visibility, Params))
205
+ {
206
+ return Hit.ImpactNormal;
207
+ }
208
+ return FVector::UpVector;
209
+ }
210
+ ```
211
+
212
+ ---
213
+
214
+ ## Pattern 5: Explosion Area-of-Effect — Sphere Overlap
215
+
216
+ Instant radial check at detonation point. Finds all Pawns and PhysicsBodies within radius. Applies damage with falloff.
217
+
218
+ ```cpp
219
+ void AExplosiveActor::Detonate(const FVector& ExplosionCenter, float Radius, float MaxDamage)
220
+ {
221
+ FCollisionShape Sphere = FCollisionShape::MakeSphere(Radius);
222
+
223
+ FCollisionObjectQueryParams ObjectParams;
224
+ ObjectParams.AddObjectTypesToQuery(ECC_Pawn);
225
+ ObjectParams.AddObjectTypesToQuery(ECC_PhysicsBody);
226
+ ObjectParams.AddObjectTypesToQuery(ECC_WorldDynamic);
227
+
228
+ FCollisionQueryParams Params;
229
+ Params.AddIgnoredActor(this);
230
+
231
+ TArray<FOverlapResult> Overlaps;
232
+ GetWorld()->OverlapMultiByObjectType(
233
+ Overlaps,
234
+ ExplosionCenter,
235
+ FQuat::Identity,
236
+ ObjectParams,
237
+ Sphere,
238
+ Params
239
+ );
240
+
241
+ TSet<AActor*> DamagedActors;
242
+ for (const FOverlapResult& Result : Overlaps)
243
+ {
244
+ AActor* Actor = Result.GetActor();
245
+ if (!Actor || DamagedActors.Contains(Actor)) continue;
246
+ DamagedActors.Add(Actor);
247
+
248
+ // Line of sight check — don't damage through walls
249
+ FHitResult LOSHit;
250
+ FCollisionQueryParams LOSParams;
251
+ LOSParams.AddIgnoredActor(this);
252
+ LOSParams.AddIgnoredActor(Actor);
253
+
254
+ const FVector ActorCenter = Actor->GetActorLocation();
255
+ const bool bBlocked = GetWorld()->LineTraceSingleByChannel(
256
+ LOSHit, ExplosionCenter, ActorCenter, ECC_Visibility, LOSParams
257
+ );
258
+ if (bBlocked) continue; // wall between explosion and target
259
+
260
+ // Damage falloff (linear)
261
+ const float Distance = FVector::Dist(ExplosionCenter, ActorCenter);
262
+ const float Falloff = FMath::Clamp(1.f - (Distance / Radius), 0.f, 1.f);
263
+ const float Damage = MaxDamage * Falloff;
264
+
265
+ FRadialDamageEvent DmgEvent;
266
+ DmgEvent.Params = FRadialDamageParams(MaxDamage, 0.f, Radius, Radius, 1.f);
267
+ DmgEvent.Origin = ExplosionCenter;
268
+ // FOverlapResult has no ToHitResult() — build FHitResult manually
269
+ FHitResult ComponentHit(Result.GetActor(), Result.GetComponent(), ActorCenter, FVector::ZeroVector);
270
+ DmgEvent.ComponentHits.Add(ComponentHit);
271
+
272
+ Actor->TakeDamage(Damage, DmgEvent, GetInstigatorController(), this);
273
+
274
+ // Radial impulse on physics bodies
275
+ if (UPrimitiveComponent* PrimComp = Result.GetComponent())
276
+ {
277
+ if (PrimComp->IsSimulatingPhysics())
278
+ {
279
+ PrimComp->AddRadialImpulse(ExplosionCenter, Radius, ImpulseStrength,
280
+ RIF_Linear, false);
281
+ }
282
+ }
283
+ }
284
+
285
+ #if ENABLE_DRAW_DEBUG
286
+ DrawDebugSphere(GetWorld(), ExplosionCenter, Radius, 16, FColor::Orange, false, 2.f);
287
+ #endif
288
+ }
289
+ ```
290
+
291
+ ---
292
+
293
+ ## Pattern 6: Camera Line-of-Sight Check
294
+
295
+ Test whether a target actor is visible from the camera position, blocked by world geometry. Common for AI perception fallback or UI visibility indicators.
296
+
297
+ ```cpp
298
+ bool AMyAIController::HasLineOfSightTo(AActor* Target) const
299
+ {
300
+ if (!Target) return false;
301
+
302
+ APawn* ControlledPawn = GetPawn();
303
+ if (!ControlledPawn) return false;
304
+
305
+ const FVector EyeLocation = ControlledPawn->GetPawnViewLocation();
306
+ const FVector TargetLocation = Target->GetActorLocation();
307
+
308
+ FCollisionQueryParams Params;
309
+ Params.bTraceComplex = false;
310
+ Params.AddIgnoredActor(ControlledPawn);
311
+ Params.AddIgnoredActor(Target);
312
+
313
+ FHitResult Hit;
314
+ const bool bBlocked = GetWorld()->LineTraceSingleByChannel(
315
+ Hit,
316
+ EyeLocation,
317
+ TargetLocation,
318
+ ECC_Visibility,
319
+ Params
320
+ );
321
+
322
+ return !bBlocked; // no blocking hit means clear line of sight
323
+ }
324
+ ```
325
+
326
+ ---
327
+
328
+ ## Pattern 7: Capsule Sweep for Character Movement Check
329
+
330
+ Before moving a character or vehicle to a new position, sweep a capsule to detect blocking geometry. Returns the first blocking hit to adjust the path.
331
+
332
+ ```cpp
333
+ bool UMyMovementComponent::CanMoveToLocation(const FVector& TargetLocation) const
334
+ {
335
+ const FVector CurrentLocation = GetOwner()->GetActorLocation();
336
+
337
+ // Capsule matching the character's collision: radius 34, half-height 88 (standard UE character)
338
+ FCollisionShape Capsule = FCollisionShape::MakeCapsule(34.f, 88.f);
339
+
340
+ FCollisionQueryParams Params;
341
+ Params.bTraceComplex = false;
342
+ Params.AddIgnoredActor(GetOwner());
343
+
344
+ FHitResult Hit;
345
+ const bool bHit = GetWorld()->SweepSingleByChannel(
346
+ Hit,
347
+ CurrentLocation,
348
+ TargetLocation,
349
+ FQuat::Identity,
350
+ ECC_Pawn,
351
+ Capsule,
352
+ Params
353
+ );
354
+
355
+ if (bHit)
356
+ {
357
+ // Hit.Distance tells us how far we can actually move
358
+ // Hit.ImpactNormal tells us the blocking surface orientation
359
+ return false;
360
+ }
361
+
362
+ return true;
363
+ }
364
+ ```
365
+
366
+ ---
367
+
368
+ ## Pattern 8: Async Trace for High-Frequency Sensors
369
+
370
+ For sensors that fire every frame on many actors (AI perception, grass interaction, liquid detection), synchronous traces stall the game thread. Use async traces queued this frame and read next frame.
371
+
372
+ ```cpp
373
+ // .h
374
+ FTraceHandle PendingTraceHandle;
375
+ bool bHasPendingTrace = false;
376
+
377
+ // .cpp — in Tick or timer callback
378
+
379
+ void UMySensorComponent::TickComponent(float DeltaTime, ELevelTick TickType,
380
+ FActorComponentTickFunction* TickFunc)
381
+ {
382
+ Super::TickComponent(DeltaTime, TickType, TickFunc);
383
+
384
+ // Read result from last frame's trace
385
+ if (bHasPendingTrace)
386
+ {
387
+ FTraceDatum Datum;
388
+ if (GetWorld()->QueryTraceData(PendingTraceHandle, Datum))
389
+ {
390
+ bHasPendingTrace = false;
391
+ if (Datum.OutHits.Num() > 0 && Datum.OutHits[0].bBlockingHit)
392
+ {
393
+ OnSensorHit(Datum.OutHits[0]);
394
+ }
395
+ }
396
+ }
397
+
398
+ // Queue this frame's trace (result readable next frame)
399
+ if (!bHasPendingTrace)
400
+ {
401
+ FCollisionQueryParams Params;
402
+ Params.AddIgnoredActor(GetOwner());
403
+
404
+ const FVector Start = GetComponentLocation();
405
+ const FVector End = Start + GetForwardVector() * SensorRange;
406
+
407
+ PendingTraceHandle = GetWorld()->AsyncLineTraceByChannel(
408
+ EAsyncTraceType::Single,
409
+ Start,
410
+ End,
411
+ ECC_Visibility,
412
+ Params
413
+ );
414
+ bHasPendingTrace = true;
415
+ }
416
+ }
417
+ ```
418
+
419
+ ---
420
+
421
+ ## FCollisionQueryParams Quick Reference
422
+
423
+ ```cpp
424
+ FCollisionQueryParams Params(
425
+ TEXT("TraceName"), // tag for profiling / debug drawing
426
+ false, // bTraceComplex — true for per-poly, false for simple hull
427
+ GetOwner() // actor to ignore (optional convenience constructor arg)
428
+ );
429
+
430
+ Params.bReturnPhysicalMaterial = true; // populate Hit.PhysMaterial (slight cost)
431
+ Params.bReturnFaceIndex = false; // populate Hit.FaceIndex (expensive, rarely needed)
432
+ Params.bFindInitialOverlaps = true; // report overlapping hits at Start position
433
+ Params.MobilityType = EQueryMobilityType::Any; // Any, Static, Dynamic
434
+
435
+ // Ignore specific actors or components
436
+ Params.AddIgnoredActor(SomeActor);
437
+ Params.AddIgnoredActors(ArrayOfActors);
438
+ Params.AddIgnoredComponent(SomeComponent);
439
+ ```
440
+
441
+ ---
442
+
443
+ ## FCollisionShape Quick Reference
444
+
445
+ All shapes from `CollisionShape.h`:
446
+
447
+ ```cpp
448
+ // Line — default, no volume (same as calling LineTrace functions directly)
449
+ FCollisionShape Line; // default constructor
450
+
451
+ // Sphere
452
+ FCollisionShape Sphere = FCollisionShape::MakeSphere(50.f); // radius in cm
453
+
454
+ // Box (axis-aligned, rotated by the Rotation parameter in sweep calls)
455
+ FCollisionShape Box = FCollisionShape::MakeBox(FVector(50.f, 30.f, 80.f)); // half-extents
456
+
457
+ // Capsule — HalfHeight includes the sphere radius at each end
458
+ FCollisionShape Capsule = FCollisionShape::MakeCapsule(34.f, 88.f);
459
+ // Capsule shaft half-length = HalfHeight - Radius = 88 - 34 = 54 cm
460
+
461
+ // Shape introspection
462
+ bool bSphere = Sphere.IsSphere();
463
+ float Radius = Sphere.GetSphereRadius();
464
+ float CHH = Capsule.GetCapsuleHalfHeight(); // full half-height
465
+ float CAxisHL = Capsule.GetCapsuleAxisHalfLength(); // shaft only (HalfHeight - Radius)
466
+ FVector Ext = Box.GetBox(); // returns half-extents as FVector
467
+ ```
468
+
469
+ ---
470
+
471
+ ## EDrawDebugTrace Reference (UKismetSystemLibrary)
472
+
473
+ ```cpp
474
+ EDrawDebugTrace::None // No debug drawing
475
+ EDrawDebugTrace::ForOneFrame // Draw for one frame only
476
+ EDrawDebugTrace::ForDuration // Draw for specified duration (DrawTime parameter)
477
+ EDrawDebugTrace::Persistent // Draw until explicitly cleared
478
+ ```
479
+
480
+ ---
481
+
482
+ ## Trace Performance Guidelines
483
+
484
+ | Technique | CPU cost | Use case |
485
+ |-----------|----------|----------|
486
+ | `LineTraceSingleByChannel` | Low | Shooting, interaction, simple AOS |
487
+ | `LineTraceMultiByChannel` | Medium | Penetration, multi-target beams |
488
+ | `SweepSingleByChannel` | Medium | Movement, precise melee |
489
+ | `SweepMultiByChannel` | Medium–High | Melee arc, projectile sweeping |
490
+ | `OverlapMultiByObjectType` | Medium | AoE, proximity detection |
491
+ | Complex collision (`bTraceComplex=true`) | High (4–10x) | Only when triangle accuracy needed |
492
+ | Async trace | Low (deferred) | Sensors, AI, effects polling >5 actors per frame |
493
+
494
+ **General rules:**
495
+ - Never run complex collision traces every tick for more than a handful of actors.
496
+ - Prefer `SweepSingle` over `SweepMulti` when only the first hit matters.
497
+ - Use `OverlapMultiByObjectType` for AoE — it is cheaper than multi-sweep for static positions.
498
+ - Group traces using `AsyncLineTraceByChannel` for sensors and background detection.
499
+ - Throttle non-critical traces with timers (5–10 Hz is sufficient for most AI awareness checks).