군집시스템(using Cursor) - 2

강성원·2025년 11월 5일

TIL 경험하고 배운 것

목록 보기
83/84

[프로젝트명] Boids_with_AI

TL;DR:

  • Naive O(n²) 방식으로 동작하던 Boids에 Grid(셀 기반) 최적화를 시도했으나, 실력 미흡으로 원상복구 시킴.
  • 멀리 벗어난 오브젝트를 텔레포트 시키는 방식(래핑)을 제거하고, 중앙으로 부드럽게 끌어오는(boundary steering) 방식으로 교체.
  • 현재 상태: 분리/정렬/응집 + boundary steering 적용, Gizmo로 감지 반경 시각화.

작업된 것

  • BoidsManager / Boid 기본 구현
    • 분리·정렬·응집, Slerp 보간, 회전/이동
    • O(n²) 로직의 이웃 갱신, 감지 반경 Gizmo
  • 구체 범위 래핑
    • 원점 반대편으로 텔레포트시키는 1차 적용

적용했다가 되돌린 것

  • 3차원 격자 구역을 나누어 이웃 탐색 최적화를 목표했으나, 기존 방식으로 복원
    • 요약: 실제 씬/환경에서 측정한 성능 이득이 기대 이하였음.
    • 구체 현상: 많은 양의 Boid에서 메서드를 호출하는 횟수가 눈에띄게 줄지 않아서 오버헤드가 많이 발생했음.

추가한 것

  • 텔레포트 제거 → 중심 끌어당김으로 교체
    • 추가 이유: 순간 이동은 시각적으로 부자연스러움
    • 방법: BoidsManager에 centerPosition 추가, Boid에 boundaryWeightCalculateBoundarySteering() 추가, CombineSteering에 합산
      => 중심으로부터 일정 거리 이상 벗어나면 중심으로 들어오는 방향을 추가해준다.
    • 효과: 경계를 벗어난 Boid가 부드럽게 중심으로 방향 전환,
      튀는 느낌 제거됨

스니펫

// 중심으로 향하는 방향 계산
private Vector3 CalculateBoundarySteering()
{
    ,,,예외처리,,,

	// 중심으로부터 거리 측정
    Vector3 toCenter = centerPosition - transform.position;
    float distanceToCenter = toCenter.magnitude;
    if (distanceToCenter <= boundaryRadius) return Vector3.zero;

	// 조종 벡터 값 계산
    Vector3 desiredDir = toCenter.normalized;
    Vector3 desiredVel = desiredDir * maxSpeed;
    Vector3 steering = desiredVel - currentDirection * maxSpeed;

    if (steering.magnitude > maxForce)
    {
        steering = steering.normalized * maxForce;
    }

    float t = Mathf.Clamp01((distanceToCenter - boundaryRadius) / boundaryRadius);
    steering *= (boundaryWeight * t);
    return steering;
}

배운 점 / 다음 계획

  • Grid 방식으로 바꾸는 최적화는 충분히 검증을 거쳤어야 했다.
  • 다음은 뭘 할까..아마 잠정 중단?
profile
개발은삼순이발

0개의 댓글