빠른 비교
csharp
NativeArray<RaycastCommand> commands = new(count, Allocator.TempJob);
NativeArray<RaycastHit> hits = new(count, Allocator.TempJob);
JobHandle handle = RaycastCommand.ScheduleBatch(commands, hits, 1);갈리는 기준
- 물리 쿼리 최적화는 보통 세 단계로 생각하면 됩니다. 먼저 일반
Physics.Raycast나Overlap으로 충분한지 보고, 그다음 GC가 문제면 NonAlloc 버전으로, 마지막으로 메인 스레드 CPU가 문제면RaycastCommand를 고려합니다. - 쿼리 수가 적고 코드가 단순한 상황에서는 일반 API가 가장 읽기 쉽습니다. 여기서부터 바로 Job System으로 가면 복잡도만 커질 수 있습니다.
- 결과 배열 할당이 반복돼 GC가 튄다면
OverlapSphereNonAlloc처럼 buffer를 재사용하는 방식이 먼저 효과를 냅니다. 이 단계는 비교적 저비용으로 얻는 이득이 큽니다. - 한 프레임에 수백~수천 개의 시야 판정, 센서, AI 스캔을 처리한다면
RaycastCommand로 배치해 메인 스레드 부담을 나누는 선택이 가치가 있습니다. - 그래서 중요한 질문은 "
RaycastCommand가 멋져 보이는가"가 아니라 "지금 병목이 GC인가, 메인 스레드 CPU인가, 아니면 물리 쿼리 수 자체가 적은가"입니다.
선택 기준
| 선택지 | 잘 맞는 상황 |
|---|---|
일반 Physics.Raycast | 쿼리 수가 적고 코드 단순성이 중요할 때 |
| NonAlloc 쿼리 | GC 할당이 먼저 문제일 때 |
RaycastCommand | 대량 쿼리로 메인 스레드 CPU가 문제일 때 |
| buffer 재사용 | 결과 배열 할당을 줄이고 싶을 때 |
| profiler 판단 | 쿼리 수, allocation, main thread 비용을 같이 본다 |
| 결과를 같은 프레임 안에 즉시 모두 소비해야 할 때 | Complete() 대기 비용까지 포함해 이득인지 먼저 확인 |
주의할 점
RaycastCommand는 소량 쿼리나 즉시 결과가 필요한 흐름에 도입하면 Schedule -> Complete -> Dispose 비용만 늘어날 수 있습니다. 먼저 NonAlloc으로 GC를 줄이고, 그래도 메인 스레드 CPU가 병목이면 RaycastCommand를 검토하세요.
csharp
// ❌ 쿼리 5개인데 RaycastCommand 도입 — 복잡도만 증가
NativeArray<RaycastCommand> cmds = new(5, Allocator.TempJob);
NativeArray<RaycastHit> hits = new(5, Allocator.TempJob);
// ... setup, Schedule, Complete, Dispose — 소량에 과한 구조
// ✅ 단계별 선택
// 1단계: 일반 API (소량, 코드 단순)
if (Physics.Raycast(origin, dir, out RaycastHit hit, maxDist, mask)) { ... }
// 2단계: NonAlloc (GC가 문제일 때)
int count = Physics.OverlapSphereNonAlloc(pos, radius, _buffer);
// 3단계: RaycastCommand (수백~수천 쿼리, 메인 스레드 CPU 병목)
JobHandle handle = RaycastCommand.ScheduleBatch(commands, results, 1);
handle.Complete();참고 링크
3 sources