1. 문제 상황

 

  • 현상
    • 여러 AudioSource가 동시에 재생될 때 전체 음량이 비정상적으로 증가함.
    • 사운드 클리핑(찢어지는 소리) 발생.
    • 기존 AudioSource의 즉각적인 중단으로 인해 부자연스러운 사운드 전환 발생.
  • 리소스 관리 문제
    • 제한된 AudioSource 수(7개)로 인해 새로운 사운드 재생 불가.
    • 우선순위가 높은 사운드가 들어와도 즉시 재생 불가능.

2. 해결 방안

 

1) 이중 풀링 시스템 구현

  • 구현 내용
    • **주요 재생용 풀(7개)**과 **여유분 풀(3개)**로 분리.
    • 여유분 풀을 통해 페이드 아웃 중에도 새로운 사운드 재생 가능.
private const int MAIN_SFX_SOURCES = 7;    // 주요 재생용 AudioSource 개수
private const int RESERVED_SOURCES = 3;   // 여유분 AudioSource 개수

private readonly Queue<AudioSource> sfxSourcePool = new Queue<AudioSource>();
private readonly Queue<AudioSource> reservedSourcePool = new Queue<AudioSource>();
  • 개선 효과
    • 자연스러운 사운드 전환 가능.
    • 제한된 AudioSource로도 동적 사운드 처리 가능.

2) 자연스러운 사운드 전환

 

  • 구현 내용
    • 0.3초 동안 선형 페이드 아웃 적용하여 급격한 소리 중단 방지.
    • 페이드 아웃 후 새 사운드를 연결.
private IEnumerator FadeOutAndReplace(AudioSource source, int newPriority)
{
    float startVolume = source.volume;    // 현재 볼륨 저장
    float elapsedTime = 0f;

    while (elapsedTime < FADE_OUT_DURATION)
    {
        elapsedTime += Time.deltaTime;
        source.volume = Mathf.Lerp(startVolume, 0f, elapsedTime / FADE_OUT_DURATION); // 선형 감쇠
        yield return null; // 다음 프레임까지 대기
    }

    source.Stop();  // 재생 중단
    source.priority = newPriority;  // 우선순위 업데이트
}
  • 개선 효과
    • 끊김 없는 사운드 전환.
    • 클리핑 현상 제거 및 전체 음량 안정화.

3) 우선순위 기반 관리 시스템

 

  • 구현 내용
    • 3단계 캐스케이딩 체크 시스템 구현:
      1. 주요 풀에서 사용 가능한 AudioSource 확인.
      2. 여유분 풀에서 사용 가능한 AudioSource 확인.
      3. 현재 재생 중인 AudioSource 중 우선순위가 낮은 항목 교체.
private AudioSource GetAvailableAudioSource(int priority)
{
    // 1. 주요 풀에서 사용 가능한 AudioSource 확인
    if (sfxSourcePool.Count > 0)
    {
        return sfxSourcePool.Dequeue();
    }

    // 2. 여유분 풀에서 사용 가능한 AudioSource 확인
    if (reservedSourcePool.Count > 0)
    {
        return reservedSourcePool.Dequeue();
    }

    // 3. 현재 활성화된 AudioSource 중 낮은 우선순위 교체
    AudioSource lowestPrioritySource = activeSfxSources
        .Where(s => s.priority > priority)  // 현재 우선순위보다 낮은 항목 검색
        .OrderByDescending(s => s.priority) // 우선순위가 높은 순서대로 정렬
        .FirstOrDefault();                  // 가장 낮은 우선순위 항목 선택

    if (lowestPrioritySource != null)
    {
        StartCoroutine(FadeOutAndReplace(lowestPrioritySource, priority)); // 페이드 아웃 후 재생
    }

    return lowestPrioritySource;
}
  • 개선 효과
    • 우선순위가 높은 사운드의 즉시 재생 보장.
    • 비효율적인 사운드 관리 해소.

3. 개선 효과 요약

 

항목 개선 전 개선 후
음질 음량 폭주, 사운드 클리핑 발생 자연스러운 사운드 전환 및 안정화
리소스 관리 AudioSource 부족 문제 발생 효율적인 리소스 관리 및 재활용
사용자 경험 불안정한 음향 재생 우선순위 높은 사운드 재생 보장

 


4. 결과

 

  • 음질 개선: 페이드 아웃으로 자연스러운 사운드 전환.
  • 리소스 최적화: 10개의 AudioSource로 효율적 관리.
  • 사용자 경험 향상: 끊김 없는 사운드 재생으로 몰입도 증가.