[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 15 (편리한 오디오🔊시스템 구축)

2023. 5. 25. 21:27·게임개발/언데드서바이벌_골드메탈_클론코딩

https://www.youtube.com/watch?v=YPEkpwPrmPk&list=PLO-mt5Iu5TeZF8xMHqtT_DhAPKmjF6i3x&index=20&t=1749s 


1. 유니티의 오디오

AudioClip : 오디오 및 사운드 파일 에셋 타입

Create Empty > AudioManager 생성

AudioSource : 에셋인 AudioClip을 재생시켜주는 컴포넌트

Play On Awake : 활성화 되어 있으면 최초 1회 자동 재생

AudioListener : 장면에서 재생 중인 오디오를 듣는 컴포넌트

Audio의 여러가지 필터가 존재한다.


2. 오디오 매니저

오디오를 관리할 스크립트 새로 생성 후 빈 오브젝트에 추가 (AudioManager.cs)

잊지 말고 즉시 Add Component

public class AudioManager : MonoBehaviour
{
    public static AudioManager instance;

	void Awake()
    {
        instance = this;
        Init();
    }
}

- 정적 메모리에 담기 위한 instance변수 선언

 

변수 선언

public class AudioManager : MonoBehaviour
{
    public static AudioManager instance;

    [Header("#BGM")]
    public AudioClip bgmClip;
    public float bgmVolume;
    AudioSource bgmPlayer;

    [Header("#SFX")]
    public AudioClip[] sfxClips;
    public float sfxVolume;
    public int channels;
    AudioSource[] sfxPlayers;
    int channelIndex;
}

- 배경음과 관련된 클립, 볼륨, 오디오소스 변수 선언

- 코드 복사하여 효과음 코드로 편집

- 다량의 효과음을 낼 수 있도록 채널 개수 변수 선언

- sfx는 동시다발적으로 여러 사운드를 발생 시켜 채널시스템을 위해 배열 선언

- 몇번째 채널을 썻는지 저장하는 channelIndex

 

초기화 함수 Init()

    void Init()
    {
        //배경음 플레이어 초기화
        GameObject bgmObject = new GameObject("BgmPlayer"); 
        bgmObject.transform.parent = transform;
        bgmPlayer = bgmObject.AddComponent<AudioSource>();
        bgmPlayer.playOnAwake = false;
        bgmPlayer.loop = true;
        bgmPlayer.volume = bgmVolume;
        bgmPlayer.clip = bgmClip;
    }

- 배경을 담당하는 자식 오브젝트를 생성

- bgmPlayer 초기화

- AddComponent 함수로 오디오소스를 생성하고 변수에 저장

- 설정 초기화

 

효과음 초기화

    void Init()
    {
		...
        //효과음 플레이어 초기화
        GameObject sfxObject = new GameObject("SfxObject");
        sfxObject.transform.parent = transform;
        sfxPlayers = new AudioSource[channels];

        for(int index = 0; index < sfxPlayers.Length; index++)
        {
            sfxPlayers[index] = sfxObject.AddComponent<AudioSource>();
            sfxPlayers[index].playOnAwake = false;
            sfxPlayers[index].volume = sfxVolume;
        }
    }

- 채널 값을 사용하여 오디오소스 배열 초기화

- 반복문으로 모든 효과음 오디오소스 생성하면서 저장

 

볼륨 bgm 0.5, sfx 0.2 설정

 


3. 효과음 시스템

모든 효과음 파일을 선택하고 효과음 배열변수에 드래그드랍

 

enum Sfx 생성

    public enum Sfx { Dead, Hit, LevelUp = 3, Lose, Melee, Range = 7, Select, Win };

- 효과음과 1:1 대응하는 열거형 데이터 선언

- 열거형 데이터는 대응하는 숫자를 지정할 수 있어요

 

효과음 재생 함수 작성

    public void PlaySfx(Sfx sfx)
    {
        sfxPlayers[0].clip = sfxClips[(int)sfx];
        sfxPlayers[0].Play();
    }

- 숫자로 쓰기 위해 명시적으로 (int) 선언

- 오디오소스의 클립을 변경하고 Play 함수 호출

 

쉬고 있는 플레이어에 실행시키게 수정

    public void PlaySfx(Sfx sfx)
    {
        for(int index = 0; index < sfxPlayers.Length; index++)
        {
            int loopIndex = (index + channelIndex) % sfxPlayers.Length;

            if (sfxPlayers[loopIndex].isPlaying)
                continue;

            channelIndex = loopIndex;
            sfxPlayers[loopIndex].clip = sfxClips[(int)sfx];
            sfxPlayers[loopIndex].Play();
            break;
        }
        
    }

- 채널 개수만큼 순회하도록 채널인덱스 변수 활용

- coutinue : 반복문 도중 다음 루프로 건너뛰는 키워드

- 효과음 재생이 된 이후에는 꼭 break로 반복문 종료

 

 

효과음을 재생할 부분마다 재생함수 호출

public class GameManager : MonoBehaviour
{
	...
    public void GameStart(int id)
    {
		...
        AudioManager.instance.PlaySfx(AudioManager.Sfx.Select);
    }
    
    IEnumerator GameOverRoutine()
    {
        ...
        AudioManager.instance.PlaySfx(AudioManager.Sfx.Lose);
    }
    IEnumerator GameVictoryRoutine()
    {
		...
        AudioManager.instance.PlaySfx(AudioManager.Sfx.Win);
    }
public class AchiveManager: MonoBehaviour{
	...
	IEnumerator NoticeRoutine()
    {
        uiNotice.SetActive(true);
        AudioManager.instance.PlaySfx(AudioManager.Sfx.LevelUp);

        yield return wait;
        uiNotice.SetActive(false);
    }
}
public class LevelUp : MonoBehaviour
{
	...
    public void show()
    {
        ...
        AudioManager.instance.PlaySfx(AudioManager.Sfx.LevelUp);
    }
    public void hide()
    {
        ...
        AudioManager.instance.PlaySfx(AudioManager.Sfx.Select);
    }
}
public class Weapon : MonoBehaviour
{
	...
    void Fire()
    {
		...
        AudioManager.instance.PlaySfx(AudioManager.Sfx.Range);
    }
}
public class Enemy : MonoBehaviour
{
		...
        if (health > 0)
        {
            ...
            AudioManager.instance.PlaySfx(AudioManager.Sfx.Hit);
        }
        else
        {
            ...
            if(GameManager.instance.isLive)
                AudioManager.instance.PlaySfx(AudioManager.Sfx.Dead);
        }
    }
}

- 언데드 사망 사운드는 게임 종료 시에는 나지 않도록 조건 추가

- if문 안쪽 로직이 한 줄이라면 중괄호 생략 가능

 

사운드가 2개 이상 있을 때 랜덤하게 재생하기

public class AudioManager : MonoBehaviour
	public void PlaySfx(Sfx sfx)
    {
        ...
            int ranIndex = 0;
            if (sfx == Sfx.Hit || sfx == Sfx.Melee)
            {
                ranIndex = Random.Range(0, 2);
            }

            channelIndex = loopIndex;
            sfxPlayers[loopIndex].clip = sfxClips[(int)sfx + ranIndex];
            ...
    }
}

4. 배경음 시스템

 

배경음을 재생하는 함수 작성

    public void PlayBgm(bool isPlay)
    {
        if (isPlay)
        {
            bgmPlayer.Play();
        }
        else
        {
            bgmPlayer.Stop();
        }
    }

 

게임 시작 부분과 종료 부분에 해당 함수 호출

public class GameManager : MonoBehaviour
{
    public void GameStart(int id)
    {
        ...
        AudioManager.instance.PlayBgm(true);
        AudioManager.instance.PlaySfx(AudioManager.Sfx.Select);
    }

    IEnumerator GameOverRoutine()
    {
		...
        AudioManager.instance.PlayBgm(false);
        AudioManager.instance.PlaySfx(AudioManager.Sfx.Lose);
    }
    IEnumerator GameVictoryRoutine()
    {
        ...
        AudioManager.instance.PlayBgm(false);
        AudioManager.instance.PlaySfx(AudioManager.Sfx.Win);
    }

 

LevelUp 시에

Audio HighPass Filter를 담을 변수 선언(높은 음역대만 통과시키고, 낮음 음역대는 막음)

Audio HighPass Filter를 담을 변수 선언

public class AudioManager : MonoBehaviour
{
    ...

    [Header("#BGM")]
    ...
    AudioHighPassFilter bgmEffect;
    ...
    
    void Init()
    {
        //배경음 플레이어 초기화
        ...
        bgmEffect = Camera.main.GetComponent<AudioHighPassFilter>();
    }

- 메인 카메라 접근은 Camera 클래스를 사용하면 간편해요'

 

필터를 켜고 끄는 함수도 작성

	public void EffectBgm(bool isPlay)
    {
        bgmEffect.enabled = isPlay;
    }

 

레벨 업 UI가 나타날 때 필터를 켜고 사라지면 끄도록 함수 호출

public class LevelUp : MonoBehaviour
{
	public void show()
    {
       ...
        AudioManager.instance.EffectBgm(true);
    }

    public void hide()
    {
        ...
        AudioManager.instance.EffectBgm(false);
    }

 

Audio HighPass Filter는 Listener Effect 계열

 

Sfx들을 Audio HighPass Filter의 효과를 받지 않게 보완

public class AudioManager : MonoBehaviour
{
	void Init()
    {
		...
        //효과음 플레이어 초기화
		...

        for(int index = 0; index < sfxPlayers.Length; index++)
        {
            ...
            sfxPlayers[index].bypassListenerEffects = true;
            ...
        }
    }
}

- 효과음 초기화 하는 부분에 byPassListenerEffects를 true로 변경


깃허브 올리기

Commit : ver 1.15
Description : Sound System

 

https://github.com/mekain80/CloneCode_Undead_Survivor

 

GitHub - mekain80/CloneCode_Undead_Survivor: https://www.youtube.com/watch?v=MmW166cHj54&list=PLO-mt5Iu5TeZF8xMHqtT_DhAPKmjF6i3x

https://www.youtube.com/watch?v=MmW166cHj54&list=PLO-mt5Iu5TeZF8xMHqtT_DhAPKmjF6i3x&index=1 - GitHub - mekain80/CloneCode_Undead_Survivor: https://www.youtube.com/watch?v=MmW166cHj54&li...

github.com

 

'게임개발 > 언데드서바이벌_골드메탈_클론코딩' 카테고리의 다른 글

[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 14+ (캐릭터 해금🔓시스템)  (0) 2023.05.25
[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 14 (플레이 캐릭터🧑‍🤝‍🧑선택 )  (0) 2023.05.11
[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 13 (게임 시작과 종료)  (0) 2023.05.11
[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 12 (레벨업🥳시스템)  (0) 2023.05.10
[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 11+ (플레이어 무기 장착 표현하기)  (0) 2023.05.10
'게임개발/언데드서바이벌_골드메탈_클론코딩' 카테고리의 다른 글
  • [클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 14+ (캐릭터 해금🔓시스템)
  • [클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 14 (플레이 캐릭터🧑‍🤝‍🧑선택 )
  • [클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 13 (게임 시작과 종료)
  • [클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 12 (레벨업🥳시스템)
메카인
메카인
  • 메카인
    메카인의 지식창고
    메카인
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 코딩 공부
        • TIL(Today I Learn)
        • TIL
        • 백준(C++)
        • Python
        • 알고리즘
        • 프로젝트 회고
      • C++
        • C++
        • C++ STL
        • C,C++ mCoding yotube
      • 게임개발
        • 언데드서바이벌_골드메탈_클론코딩
        • 3D_골드메탈_클론코딩
        • 유니티_문제해결
        • 게임 수학
      • Unreal 공부
        • UE5 GameDev
        • Unreal Engine 4 C++ The Ult..
      • 교재 문제 풀이
        • 운영체제
      • 정보처리기사
        • 정처기 요약
        • 정처기 오답노트
      • 학교수업
        • 데이터베이스
        • 프로그래밍 언어론
        • 리눅스 시스템
        • 네트워크
      • 일상
        • 주식
        • 독서
      • (비공개 전용)
        • memory
        • Build
        • OOP
        • Smart Pointer
        • lamda
        • 게임 수학
        • 모던 C++
        • 모던 C++ STL
        • 모던 C++ Concurrency, Paralle..
        • 책
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
    • 블로그 관리
  • 링크

  • 공지사항

    • 공지사항 - 인생과 블로그의 목표
  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
메카인
[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 15 (편리한 오디오🔊시스템 구축)
상단으로

티스토리툴바