SoundManager.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SoundManager
{
    AudioSource[] _audioSources = new AudioSource[(int)Define.Sound.MaxCount]; // 오디오소스를 관리하는 배열
    Dictionary<string, AudioClip> _audioClips = new Dictionary<string, AudioClip>(); // 오디오클립을 관리하는 배열
    // NPC Player -> AudioSource
    // NPC 음원   -> AudioClip
    // 관객(귀)   -> AudioListener

    public void Init()
    {
        GameObject root = GameObject.Find("@Sound"); // 모든 사운드를 관리하는 객체를 생성한다.
        if (root == null)
        {
            root = new GameObject { name = "@Sound" };
            Object.DontDestroyOnLoad(root);

            string[] soundNames = System.Enum.GetNames(typeof(Define.Sound)); // enum으로 선언한 사운드의 타입의 이름을 가져와서 배열로 만든다.
            for (int i = 0; i < soundNames.Length-1; i++)
            {
                GameObject go = new GameObject { name = soundNames[i] }; // 가져온 이름을 가진 새 게임 오브젝트를 만든다.
                _audioSources[i] = go.AddComponent<AudioSource>(); // 오디오 소스를 관리하는 배열을 AudioSource 컴포넌트를 붙여 채운다
                go.transform.parent = root.transform; // 관리 객체의 자식으로 붙여준다.
            }

            _audioSources[(int)Define.Sound.Bgm].loop = true; // loop여부를 설정한다.
        }
    }

    public void Clear() // 정리 함수
    {
        foreach(AudioSource audioSource in _audioSources)
        {
            audioSource.clip = null;
            audioSource.Stop();
        }
        _audioClips.Clear();
    }

    public void Play(string path, Define.Sound type = Define.Sound.Effect, float pitch = 1.0f)
    { // 오디오 클립을 가져와서 재생한다. 
        AudioClip audioClip = GetOrAddAudioClip(path, type);
        Play(audioClip, type, pitch);
    }

    public void Play(AudioClip audioClip, Define.Sound type = Define.Sound.Effect, float pitch = 1.0f)
    { // 입력받은 오디오 클립을 오디오 소스를 관리하는 배열에서 불러와서 재생한다.
        if (audioClip == null)
            return;

        if (type == Define.Sound.Bgm)
        { // 배경음악의 경우 재생중인 음악을 끄고 새로 재생
            AudioSource audioSource = _audioSources[(int)Define.Sound.Bgm];

            if (audioSource.isPlaying)
                audioSource.Stop();

            audioSource.pitch = pitch;
            audioSource.clip = audioClip;
            audioSource.Play(); // 계속 재생
        }
        else
        { // 효과음의 경우 그냥 재생
            AudioSource audioSource = _audioSources[(int)Define.Sound.Effect];
            audioSource.pitch = pitch;
            audioSource.PlayOneShot(audioClip); // 한번만 재생
        }


    }
    AudioClip GetOrAddAudioClip(string path, Define.Sound type = Define.Sound.Effect)
    { // 오디오 클립을 가져오는데, 없으면 붙여주고 가져온다.
        if (path.Contains("Sounds/") == false)
            path = $"Sounds/{path}";

        AudioClip audioClip = null;

        if (type == Define.Sound.Bgm)
        {
            audioClip = Managers.Resource.Load<AudioClip>(path);
        }
        else
        {
            
            if (_audioClips.TryGetValue(path, out audioClip) == false)
            {
                audioClip = Managers.Resource.Load<AudioClip>(path);
                _audioClips.Add(path, audioClip);
            }

        }
        if (audioClip == null)
            Debug.Log($"AudioClip Missing! {path}");

        return audioClip;
    }
}

 

코드를 만들고 Managers.cs에 붙여준다.

 

'UNITY' 카테고리의 다른 글

UNITY - Coroutine  (0) 2024.01.23
UNITY - Object Pooling  (1) 2024.01.23
UNITY - UI 자동화 - 게임 UI 구현  (0) 2024.01.22
UNITY - Scene  (1) 2024.01.12
UNITY - Animation - Animator Controller를 활용한 애니메이션 전환  (3) 2024.01.12

+ Recent posts