Unity 인게임 버그 자동 탐지: Agentic AI와 지형 충돌 레이캐스트 최적화

Agentic AI가 플레이 로그와 재현 가능한 게임 상태를 수집·분류·검증하는 구조를 설계하고 Unity C# 레이캐스트로 캐릭터 지형 충돌을 안정적으로 판정하는 구현과 최적화 기준을 정리합니다.

✓ 복사 완료!
챕터자동화 테스트 & 회귀 검증
난이도중급
상태● 검토 완료
대상 엔진
Unity
최종 업데이트
Unity 인게임 버그 자동 탐지: Agentic AI와 지형 충돌 레이캐스트 최적화

핵심 요약

Agentic AI 기반 인게임 버그 자동 탐지는 AI가 오류를 단독으로 ‘판정’하게 하는 기능이 아니라 텔레메트리 수집 → 이상 징후 후보화 → 재현 시나리오 실행 → 증거 첨부 → 이슈 등록을 제한된 도구 호출로 연결하는 자동화 파이프라인이다. 캐릭터 지형 충돌은 발바닥 기준 다중 Raycast로 지면 거리와 법선을 측정하고 레이어 마스크·비할당 API·갱신 주기 제어를 적용하면 정확도와 성능을 함께 확보할 수 있다.

Agentic AI 기반 인게임 버그 자동 탐지란?

일반적인 오류 수집은 예외 로그, 크래시, 성능 수치처럼 이미 발생한 결과를 서버에 전송하는 데 집중한다. 반면 Agentic AI는 관측 데이터를 바탕으로 다음 행동을 순서대로 수행한다.

  1. 플레이 세션의 입력, 위치, 상태 전이, 프레임 시간, 물리 이벤트를 수집한다.
  2. 규칙과 통계 기준으로 비정상 후보를 찾는다.
  3. 승인된 테스트 도구로 후보 시나리오를 재실행한다.
  4. 재현 성공 여부와 로그, 스크린샷, 상태 스냅샷을 묶어 이슈 초안을 만든다.

핵심은 LLM에 게임 클라이언트의 임의 실행 권한을 주지 않는 것이다. AI는 FindSuspectSessions, ReplayScenario, CaptureEvidence, CreateIssueDraft처럼 입력과 출력이 고정된 도구만 호출해야 한다. 최종 이슈 등록과 코드 변경은 사람 또는 별도 승인 규칙이 담당한다.

구성 요소입력출력클라이언트 구현 관점
텔레메트리입력·좌표·상태·성능세션 이벤트이벤트 스키마와 샘플링
탐지기이벤트 스트림버그 후보규칙, 임계값, 이상치 점수
에이전트후보와 도구 결과재현·증거 요청허용 도구와 호출 횟수 제한
재현 러너시드·입력 시퀀스성공/실패, 상태 스냅샷결정성, 테스트 빌드
이슈 초안증거 묶음사람이 검토할 보고서개인 정보 제거, 링크 제공

인게임 버그 자동 탐지는 왜 재현 가능한 상태가 중요한가?

‘벽에 끼었다’는 플레이어 신고만으로는 수정 우선순위와 원인을 판단하기 어렵다. 같은 입력을 넣었을 때 같은 결과에 가까워지도록 상태를 기록해야 자동 검증이 가능하다.

최소한 다음 필드를 이벤트에 포함한다.

  • sessionId: 분석 단위가 되는 플레이 세션 ID
  • buildVersion: 빌드와 콘텐츠 버전
  • sceneId, spawnId: 맵과 시작 지점
  • simulationTick: 렌더 프레임과 분리된 시뮬레이션 틱
  • inputFrame: 이동축, 점프, 상호작용 등 정규화된 입력
  • position, velocity, grounded: 이동 판정에 필요한 상태
  • randomSeed: 난수 영향을 받는 게임이라면 필요한 시드
  • raycastHit: 충돌체 ID, 거리, 법선, 레이어

모든 프레임을 전송할 필요는 없다. 기본 상태는 5~10Hz로 샘플링하고 아래와 같은 트리거가 발생하면 전후 구간을 고밀도로 보존하는 방식이 효율적이다.

public bool ShouldCaptureHighDetail(PlayerTelemetry t)
{
    bool fellThroughGround = !t.Grounded && t.VerticalVelocity < -15f;
    bool stuck = t.Speed < 0.05f && t.MoveInputMagnitude > 0.7f;
    bool physicsSpike = t.PhysicsStepMs > 10f;

    return fellThroughGround || stuck || physicsSpike;
}

캐릭터 이동 상태와 레이캐스트 결과를 시간 순서로 기록하는 텔레메트리 예시

Agentic AI는 버그 후보를 어떻게 검증할까?

자동 탐지는 ‘의심’과 ‘확정’을 분리할 때 신뢰할 수 있다. 예를 들어 0.7초 이상 이동 입력이 유지되는데 실제 속도가 거의 0이고 앞쪽 충돌 레이캐스트가 지속적으로 막힘을 보고한다면 끼임 후보로 분류할 수 있다. 그러나 이것만으로 버그라고 단정하면 정상적인 문 앞 대기나 컷신까지 오탐이 된다.

Step 1. 규칙 기반으로 후보를 좁힌다

처음에는 설명 가능한 규칙을 우선 적용한다. AI는 이 규칙의 결과와 관련 세션을 요약하는 역할을 맡는다.

public static bool IsStuckCandidate(
    float movingInput,
    float horizontalSpeed,
    float blockedSeconds,
    bool isInCutscene)
{
    return !isInCutscene
        && movingInput >= 0.7f
        && horizontalSpeed <= 0.05f
        && blockedSeconds >= 0.7f;
}

Step 2. 에이전트가 제한된 도구로 재현한다

에이전트는 후보를 받으면 원본 세션의 빌드 버전, 씬, 난수 시드, 입력 구간을 사용해 테스트 환경에서 재생한다. 한 세션당 재시도 횟수와 최대 실행 시간을 제한해 비용 폭증과 무한 반복을 막는다.

ReplayScenario(
  buildVersion,
  sceneId,
  randomSeed,
  inputFrames,
  maxAttempts = 3,
  timeoutSeconds = 30
)

Step 3. 증거가 있을 때만 이슈 초안을 생성한다

재현 결과에는 충돌체 식별자, 캐릭터 transform, 레이캐스트 거리, 스택 트레이스, 전후 10초의 이벤트를 포함한다. 재현 실패는 ‘미재현’으로 남기고 자동으로 결함 확정 상태로 올리지 않는다.

flowchart LR
    A[클라이언트 텔레메트리] --> B[규칙 기반 후보 탐지]
    B --> C[Agentic AI 요약 및 도구 선택]
    C --> D[격리된 재현 러너]
    D -->|재현 성공| E[증거 첨부 이슈 초안]
    D -->|재현 실패| F[후보 보류 및 추가 데이터 요청]
    E --> G[개발자 검토]

Unity에서 캐릭터 지형 충돌 레이캐스트는 어떻게 구현할까?

캐릭터가 지면에 닿았는지 확인하는 가장 단순한 방법은 발밑에서 아래 방향으로 Raycast를 쏘는 것이다. 다만 중앙 한 점만 검사하면 능선, 계단 모서리, 경사진 플랫폼에서 접지 상태가 흔들릴 수 있다.

캡슐형 캐릭터라면 발바닥 중심과 좌우 보조점에서 아래로 검사하고 가장 가까운 유효 지면을 선택한다. 경사 제한은 법선과 위쪽 벡터의 내적으로 판정할 수 있다.

아래 예제는 캡슐의 direction이 Y축이고 오브젝트가 기울거나 스케일되지 않은 경우를 가정한다. 다른 방향이나 Transform 스케일을 쓰는 프로젝트에서는 월드 공간 캡슐 치수에 맞춰 원점을 계산해야 한다.

θ=cos⁡−1(clamp⁡(n⋅u,−1,1))\theta = \cos^{-1}(\operatorname{clamp}(\mathbf{n}\cdot\mathbf{u}, -1, 1))

여기서 n\mathbf{n}은 충돌 표면 법선, u\mathbf{u}는 월드 상단 방향, θ\theta는 지면 경사각이다. theta <= maxSlopeAngle일 때만 이동 가능한 지면으로 취급한다.

using UnityEngine;

public sealed class GroundProbe : MonoBehaviour
{
    [SerializeField] private CapsuleCollider capsule;
    [SerializeField] private LayerMask groundMask;
    [SerializeField] private float probeStartOffset = 0.08f;
    [SerializeField] private float probeDistance = 0.25f;
    [SerializeField] private float maxSlopeAngle = 50f;

    public bool IsGrounded { get; private set; }
    public RaycastHit GroundHit { get; private set; }

    private void FixedUpdate()
    {
        GroundHit = default;
        IsGrounded = TryFindGround(out RaycastHit hit);
        if (IsGrounded)
        {
            GroundHit = hit;
        }
    }

    private bool TryFindGround(out RaycastHit closestHit)
    {
        closestHit = default;
        bool found = false;
        float closestDistance = float.MaxValue;

        Vector3 center = transform.TransformPoint(capsule.center);
        float footY = center.y - (capsule.height * 0.5f);
        Vector3 footCenter = new Vector3(center.x, footY, center.z);
        Vector3 right = transform.right * (capsule.radius * 0.65f);

        Vector3[] origins =
        {
            footCenter + Vector3.up * probeStartOffset,
            footCenter + right + Vector3.up * probeStartOffset,
            footCenter - right + Vector3.up * probeStartOffset
        };

        foreach (Vector3 origin in origins)
        {
            if (!Physics.Raycast(
                    origin,
                    Vector3.down,
                    out RaycastHit hit,
                    probeDistance,
                    groundMask,
                    QueryTriggerInteraction.Ignore))
            {
                continue;
            }

            float slopeAngle = Vector3.Angle(hit.normal, Vector3.up);
            if (slopeAngle > maxSlopeAngle || hit.distance >= closestDistance)
            {
                continue;
            }

            closestDistance = hit.distance;
            closestHit = hit;
            found = true;
        }

        return found;
    }
}

이 예제의 groundMask에는 Terrain과 이동 가능한 플랫폼 레이어만 넣는다. 플레이어 자신의 콜라이더, 트리거 전용 콜라이더, 카메라 충돌체까지 검사 대상에 포함하면 접지 결과가 왜곡될 수 있다.

캡슐 캐릭터 발바닥의 중앙과 좌우 지점에서 아래 방향 레이캐스트를 수행하는 모습

단일 Raycast와 SphereCast 중 무엇을 선택해야 할까?

방식장점주의점적합한 경우
단일 Raycast비용이 낮고 구현이 단순함모서리에서 접지 누락 가능평탄한 지형, 보조 검사
다중 Raycast비용 대비 안정성이 좋음원점 설계가 필요함일반적인 캡슐 캐릭터
SphereCast넓은 접지 면적을 반영시작 지점 겹침과 반지름 튜닝 주의빠른 이동, 작은 단차가 많은 맵
CapsuleCast캐릭터 외형에 가까운 검사더 많은 물리 비용이동 전 충돌 예측

지면 접지 판정은 다중 Raycast 또는 SphereCast를 쓰고 실제 이동 전 벽 충돌 예측은 CapsuleCast를 쓰는 식으로 역할을 나누는 편이 이해하기 쉽다. 한 가지 쿼리로 모든 물리 문제를 해결하려 하면 경사, 계단, 움직이는 발판, 네트워크 보정에서 예외가 늘어난다.

레이캐스트 연산은 어떻게 최적화할까?

물리 쿼리는 호출 횟수, 검사 거리, 충돌 레이어 수의 영향을 받는다. 먼저 프로파일러에서 Physics.Raycast 자체보다 고정 업데이트 횟수, 한 프레임의 캐릭터 수, 잘못된 레이어 구성이 병목인지 확인한다.

Step 1. 검사 대상을 줄인다

  • LayerMask로 Terrain, Ground, MovingPlatform처럼 실제 지면만 대상으로 제한한다.
  • QueryTriggerInteraction.Ignore로 트리거 콜라이더를 제외한다.
  • probeDistance는 점프 높이가 아니라 발바닥과 지면 사이에서 허용할 오차 범위에 맞춘다.

Step 2. 호출 시점을 제어한다

접지 상태가 물리 계산에 사용된다면 FixedUpdate에서 갱신한다. 지면과 멀리 떨어진 공중 상태에서는 매 틱 검사하지 않고 낙하 속도나 예상 착지 시간에 따라 검사 간격을 넓힐 수 있다. 단, 착지 직전에는 다시 매 물리 틱 검사해야 입력 반응이 늦어지지 않는다.

Step 3. 대규모 NPC에는 배치 쿼리를 사용한다

수십~수백 개 NPC가 동시에 지면을 검사한다면 개별 Physics.Raycast 호출만으로도 관리 비용이 커질 수 있다. Unity의 Job System 환경에서는 RaycastCommand.ScheduleBatch로 명령을 모아 배치 처리하는 방식을 검토한다. 이 경우 결과 접근 시점과 JobHandle.Complete() 호출 위치를 명확히 관리해야 하며 메인 스레드에서 즉시 결과가 필요한 플레이어 캐릭터에는 단순 쿼리가 더 적합할 수 있다.

자동 탐지 데이터에 레이캐스트 결과를 무엇까지 남겨야 할까?

버그 분석에 필요한 것은 모든 광선의 원시 데이터가 아니라 원인 추적에 필요한 최소 증거다. 다음처럼 접지 상태가 바뀌거나 끼임 후보가 감지될 때만 상세 결과를 기록한다.

public readonly struct GroundProbeEvent
{
    public readonly int ColliderInstanceId;
    public readonly int Layer;
    public readonly float Distance;
    public readonly Vector3 Point;
    public readonly Vector3 Normal;
    public readonly bool Grounded;

    public GroundProbeEvent(RaycastHit hit, bool grounded)
    {
        ColliderInstanceId = hit.collider ? hit.collider.GetInstanceID() : 0;
        Layer = hit.collider ? hit.collider.gameObject.layer : -1;
        Distance = hit.distance;
        Point = hit.point;
        Normal = hit.normal;
        Grounded = grounded;
    }
}

GetInstanceID()는 같은 실행 세션 안에서 분석용 상관관계에는 쓸 수 있지만 빌드나 실행을 넘는 영구 식별자로 쓰면 안 된다. 재현 환경에서 동일 충돌체를 찾으려면 씬 오브젝트의 안정적인 콘텐츠 ID 또는 베이크된 콜라이더 ID를 별도로 기록한다.

자주 묻는 질문 (FAQ)

Agentic AI가 버그를 자동으로 수정하게 해도 될까?

운영 빌드에서 자동 수정 권한을 주는 것은 권장하지 않는다. 에이전트는 후보 탐지, 재현, 증거 정리, 이슈 초안까지 담당하고 수정·배포는 코드 리뷰와 CI 검증을 거치는 편이 안전하다.

Raycast가 지면을 가끔 놓치는 가장 흔한 이유는 무엇인가?

광선 시작점이 콜라이더 내부에 있거나 검사 거리가 부족하거나 지면 레이어가 마스크에 빠졌거나 중앙 한 점만 검사하는 경우가 흔하다. Scene 뷰에서 광선 원점과 최대 거리를 시각화해 먼저 확인한다.

접지 판정에 Update와 FixedUpdate 중 무엇을 써야 할까?

Rigidbody나 물리 기반 이동의 판정값은 FixedUpdate에서 계산하는 것이 기본이다. 카메라나 애니메이션 표시에는 가장 최근의 접지 결과를 Update에서 읽어 사용하면 된다.

정리

Agentic AI는 모호한 플레이 로그를 재현 가능한 버그 증거로 바꾸는 조정자이며 신뢰성은 제한된 도구 권한과 결정적인 재현 데이터에서 나온다. 클라이언트에서는 지면 접지의 원점, 레이어, 경사각, 호출 빈도를 명확히 설계하고 그 결과를 필요한 순간에만 텔레메트리로 남기면 충돌 버그를 더 빠르게 찾고 수정할 수 있다.