유니티 사운드 조절 시키기 (Sound Controller)

농담고미고미·2024년 5월 24일

Unity 개발 일지

목록 보기
1/26
📢 **목표**
  1. 사운드 조절창에서 Slider로 소리 조절하기
  2. 배경음 유지시키기 (Scene을 왔다갔다해도 배경음이 흘러나오게끔)

https://www.youtube.com/watch?v=rdX7nhH6jdM&t=345s

🎀 코드 백업
  • Sound script
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    **[System.Serializable]**
    public class Sound
    {
        public string name;
        public AudioClip clip;
    }
    
    [System.Serializable] : [SerializeField]는 unity의 attribute 중 하나로 해당 필드를 inspector창에서 직렬화되도록 지정한다. 그러므로 해당 필드의 값을 인스펙터창에서 수정할 수 있고, 프래핍 또는 씬에 저장될 때 유지된다. 일반적으로 객체의 메모리 상태는 해당 객체가 실행 중인 동안에만 유지된다. 프로그램이 종료되면 객체 상태는 사라지게 된다. 하지만 직렬화를 사용하면 객체는 메모리에서 상태를 보존하지 않고도 파일에 저장하거나 네트워크를 전송할 수 있다. [System.Serializable]은 이 Attruibute를 class나 struct 위에 선언하게 되면 해당 타입이 직렬화 가능한 형태가 된다. 직렬화 가능한 class나 struct로 만들어지는 객체는 상태를 저장하고 복원할 수 있다. 이를 이용해서 게임을 종료한 후에도 이전 상태를 보존 가능.
  • AudioManager script
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class AudioManager : MonoBehaviour
    {
        **public static AudioManager Instance;**
    
        public Sound[] musicSounds, sfxSounds;
        //왜 Sound는 배열로 선언한거지?
        //Sound 안에서도 배경음과 효과음이 있고, 배경음이 여러개일 수도 있고, 효과음이 여러개일 수 있으니 배열로 접근하는게 편하다.
        public AudioSource musicSource, sfxSource;
    
        private void Awake()
        {
            if (Instance == null)
            {
                **Instance = this;
                DontDestroyOnLoad(gameObject);**
            }
            else
            {
                Destroy(gameObject);
            }
        }
    
        private void Start()
        {
            PlayMusic("Theme");
        }
        public void PlayMusic(string name)
        {
            **Sound s = Array.Find(musicSounds, x => x.name == name);**
            //sound[]의 배경음 중에서 내가 원하는 음악을 찾을려고
    
            if (s == null)
            {
                Debug.Log("Sound Not Found");
            }
    
            else
            {
                **musicSource.clip = s.clip;**
                musicSource.Play();
            }
        }
    
        public void PlaySFX(string name)
        {
            Sound s = Array.Find(sfxSounds, x => x.name == name);
    
            if (s == null)
            {
                Debug.Log("Sound Not Found");
            }
    
            else
            {
                **sfxSource.PlayOneShot(s.clip);**
                //효과음은 한번씩만 재생되야 하므로 PlayOneShot을 이용한다.
            }
        }
    
        public void ToggleMusic()
        {
            musicSource.mute = !musicSource.mute;
        }
        public void ToggleSFX()
        {
            sfxSource.mute = !sfxSource.mute;
        }
        **public void MusicVolume(float volume)
        {
            musicSource.volume = volume;
        }**
        public void SFXVolume(float volume)
        {
            sfxSource.volume = volume;
        }
    }
    
  • UIController script
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class UIController : MonoBehaviour
    {
        public Slider _musicSlider, _sfxSlider;
    
        public void ToggleMusic()
        {
            AudioManager.Instance.ToggleMusic();
        }
    
        public void ToggleSFX()
        {
            AudioManager.Instance.ToggleSFX();
        }
    
        **public void MusicVolume()
        {
            AudioManager.Instance.MusicVolume(_musicSlider.value);**
            //_musicSlider의 값을 가져와서 MusicVolume으로 설정한다. 
        **}**
    
        public void SFXVolume()
        {
            AudioManager.Instance.SFXVolume(_sfxSlider.value);
        }
    }
    

  • 유니티 기본 개념 (참고용) private, public : private로 선언하면 객체가 다른 객체의 내부 자료를 직접 확인할 수는 없고, 해당 객체가 미리 정의해놓은 메소드를 통해서만 그 객체를 간접적으로 이용 가능하다. 이렇게 객체를 이용할 수 있는 통로가 되는 것을 인터페이스라 한다. 클래스 멤버 변수를 public으로 지정함으로써 유니티 에디터의 inspector에서 해당 변수의 값을 쉽게 변경할 수 있도록 하는 경우가 있다. static instance : 한 개의 객체를 여러 군데에서 사용하기 위한 방법 (해당 오브젝트가 아닌 다른 오브젝트 안의 스크립트에서도 그 기능을 불러와 쓸 수 있다.) pref : PlayerPrefs은 유니티에서 제공하는 데이터 관리 클래스다. Awake(): 항상 Start 함수 전에 호출되며 프리팹이 인스턴스화 된 직후에 호출된다.
    sing UnityEngine;
    
    public class GameClass : MonoBehaviour
    {
        private GameObject _player;
    
        void Awake()
        {
            _player = GameObject.FindWithTag("Player");
        }
    }
    스크립트 간의 참조를 설정하기 위해서 Awake()를 사용해줘야 한다. Awake는 모든 오브젝트가 초기화되고 호출되기 때문에 다른 스크립트와 연결을 보장할 수 있다. 유니티에서 MonoBehaviour을 상속 받은 클래스에서 사용 가능하다. Audio Source: 소리를 발생시키는 컴포넌트.

배경음 유지 및 사운드 조절창

  1. Sound script 생성
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class Sound
{
    public string name;
    public AudioClip clip;
}
  1. Audio manager script 추가
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class AudioManager : MonoBehaviour
{
    public Sound[] musicSounds, sfxSounds;
    public AudioSource musicSource, sfxSource;
}

Audio manager의 Music Sounds, Sfx Sounds에 음악을 추가한다 (미리 사운드 좀 다운 받아놓자)

  1. Audio Manager에 Music Source, Sfx Source 추가

    audio source를 add component한다. (영상 참고)

  2. Audio Manager에 PlayMusic, PlaySFX에 대한 코드 작성

    AudioManager를 static Instance로 선언

    게임이 시작될 때 bgm이 나오도록 코드 작성(Start)… 이하 영상 참고

  3. UI Controller script 생성

    MusicVolume, SFXVolume으로 Audio Manager에서 끌고오면 됨.

profile
농담곰을 좋아해요 말랑곰탱이

0개의 댓글