크래프톤 정글 TIL : 1124

lazyArtisan·2024년 11월 24일
0

정글 TIL

목록 보기
147/147

🎮 Frog on Lotus


빌드 뽑아봤는데 크기가 이상함

  • UI 캔버스로 구현했던 검정 반투명 필터와 글씨들이 전부 작게 보임
  • 화면에 꽉 차니까 물이 허전한게 너무 티남

https://best-study-day.tistory.com/2

UI들 전부 'Scale With Screen Size'로 바꾸고 x 1920 y 1080으로 바꾸니까 해결

물 구현해보고 싶긴 했는데
일단 이력서도 써야되고
다른 프로젝트도 하려고 마감 기한도 오늘로 잡아놨었으니까

일단은 여기까지

Audio Source 오브젝트 풀링

https://gall.dcinside.com/mgallery/board/view/?id=game_dev&no=173649&page=1

원글에 말씀해주신 내용 몇 가지를 말씀드리겠습니다.
첫 번째, "스피커 하나로 이벤트를 수신 받아 원하는 음향 소스들을 송출 하는 형태"입니다. 스피커 하나로 'PlayOneShot' 메소드로 음향 소스를 송출할수는 있습니다. 다만, 가비지 메모리가 생겨 많은 요청을 할 경우 게임이 끊기는 현상이 발생할 수 있습니다. 그래서, 많은 분들이 오브젝트 풀링 기법을 활용하여 스피커들을 풀링 시켜놓고 하나씩 꺼내어 사용하는 쪽으로 합니다.

이게 뭔 소린지 설명 좀. 풀링 뭐 이게 뭐고 어떻게 하는건데

오브젝트 풀링(Object Pooling)은 성능 최적화를 위해 자주 생성되고 삭제되는 오브젝트를 미리 생성해두고 재사용(recycle)하는 기법입니다. 이는 특히 사운드, 파티클, 적 캐릭터 생성 등과 같이 짧은 시간 동안 많은 오브젝트가 필요할 때 사용됩니다.


1. 문제의 원인: PlayOneShot과 가비지 메모리

Unity의 AudioSource.PlayOneShot 메서드는 간단하게 여러 사운드를 재생할 수 있지만, 내부적으로 새로운 메모리를 할당하고 관리하기 때문에 다음과 같은 문제가 발생할 수 있습니다:

  • 가비지 메모리 증가:
    • 사운드가 재생될 때마다 새로운 오디오 데이터를 처리.
    • 재생이 끝난 후 더 이상 필요 없는 메모리를 수거(가비지 수집)하는 데 비용 발생.
  • 성능 저하:
    • 많은 요청(사운드 재생)이 동시에 들어오면 Unity가 처리하기 힘들어지고 프레임 드랍이 발생.

2. 오브젝트 풀링이란?

오브젝트 풀링은 필요한 오브젝트를 미리 생성하고, 필요할 때 가져와서 사용 후 반환하는 방식입니다.

기본 아이디어:

  1. 사운드(또는 오브젝트) 사용이 예상되는 경우, 미리 AudioSource 오브젝트를 여러 개 생성해둠.
  2. 사운드 재생이 필요할 때:
    • 새로 생성하지 않고 풀(Pool)에 저장된 오디오 소스를 가져옴.
  3. 사운드 재생이 끝난 후:
    • 풀로 다시 반환하여 다음 요청에 재사용.

이 방식으로 매번 오디오 소스를 생성/삭제하지 않아도 되므로 성능이 크게 개선됩니다.

예제: 오디오 소스 풀링

1) 사운드 풀링 매니저 클래스

using System.Collections.Generic;
using UnityEngine;

public class AudioSourcePool : MonoBehaviour
{
    public GameObject audioSourcePrefab; // AudioSource가 붙은 프리팹
    public int poolSize = 10; // 풀링할 AudioSource 개수
    private Queue<AudioSource> audioPool = new Queue<AudioSource>();

    void Awake()
    {
        // AudioSource를 미리 생성
        for (int i = 0; i < poolSize; i++)
        {
            GameObject newAudioSource = Instantiate(audioSourcePrefab);
            newAudioSource.SetActive(false); // 비활성화
            audioPool.Enqueue(newAudioSource.GetComponent<AudioSource>());
        }
    }

    // AudioSource 가져오기
    public AudioSource GetAudioSource()
    {
        if (audioPool.Count > 0)
        {
            AudioSource source = audioPool.Dequeue();
            source.gameObject.SetActive(true);
            return source;
        }

        // 풀에 오디오 소스가 없으면 새로 생성
        GameObject newAudioSource = Instantiate(audioSourcePrefab);
        return newAudioSource.GetComponent<AudioSource>();
    }

    // AudioSource 반환하기
    public void ReturnAudioSource(AudioSource source)
    {
        source.Stop();
        source.gameObject.SetActive(false); // 비활성화
        audioPool.Enqueue(source);
    }
}

2) 사운드 재생 스크립트

public class SoundManager : MonoBehaviour
{
    public AudioSourcePool audioSourcePool; // AudioSourcePool 연결
    public AudioClip explosionClip;

    public void PlaySound(Vector3 position)
    {
        // 풀에서 오디오 소스를 가져와서 재생
        AudioSource source = audioSourcePool.GetAudioSource();
        source.transform.position = position; // 위치 설정
        source.clip = explosionClip; // 클립 설정
        source.Play();

        // 사운드 재생이 끝난 후 반환
        StartCoroutine(ReturnAfterPlay(source));
    }

    private IEnumerator ReturnAfterPlay(AudioSource source)
    {
        yield return new WaitForSeconds(source.clip.length); // 클립 재생 시간 기다림
        audioSourcePool.ReturnAudioSource(source); // 반환
    }
}

네가 예시 보여준대로 코드 짜면 10개 이상의 사운드는 동시 재생 못하겠네?

맞습니다! 제가 제공한 코드에서는 오브젝트 풀의 크기(poolSize)가 10개로 고정되어 있어, 동시에 10개 이상의 사운드를 재생할 수 없는 제약이 있습니다. 이 문제를 해결하려면 오브젝트 풀링의 동작 방식을 약간 수정해야 합니다.

그니까 오브젝트 풀링이 별거가 아니라 씬에 미리 올려놓고 비활성화시켜놨다가 필요할 때 너 일해 한다는거네? 돌려막기로다가? 맨날 새로 만드는게 아니라?

맞습니다! 오브젝트 풀링(Object Pooling)의 본질은 바로 "돌려막기"입니다. 🎯

  • 요점: 오브젝트를 필요할 때마다 새로 생성하고 삭제하지 않고, 미리 만들어둔 것을 재사용하는 방식입니다.

1. 오브젝트 풀링이 왜 필요한가?

Unity에서 오브젝트를 생성하거나 삭제하는 작업(특히 InstantiateDestroy)은 비용이 많이 듭니다:

  • 메모리:
    • 새로운 오브젝트 생성 시 메모리 할당.
    • 삭제 시 가비지 컬렉션 비용 발생.
  • 성능 저하:
    • 한 번에 많은 오브젝트를 생성/삭제하면 프레임 드랍 발생.

→ 해결 방법: 미리 생성해두고 비활성화했다가 재사용하자!


2. 오브젝트 풀링 기본 흐름

초기화 단계

  1. 필요한 만큼 오브젝트를 미리 생성(예: 적, 탄환, 사운드 소스 등).
  2. 생성한 오브젝트를 비활성화(SetActive(false)) 상태로 보관.

사용 단계

  1. 오브젝트가 필요할 때 풀에서 비활성화된 오브젝트를 찾아 활성화(SetActive(true)).
  2. 오브젝트 사용이 끝나면 다시 비활성화하고 풀에 반환.

0개의 댓글