배경음악 추가

This commit is contained in:
김민구
2026-07-08 05:42:29 +09:00
parent 6e641be1c7
commit 64f3408d4e
2 changed files with 90 additions and 23 deletions
+3
View File
@@ -59571,6 +59571,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 99e32a34df5b44d91a7f5280093cd383, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::SoundManager
lobbyBgmClip: {fileID: 8300000, guid: 39f24fa81a3ca4c43bed61b4ff4a7228, type: 3}
battleBgmClip: {fileID: 8300000, guid: 39f24fa81a3ca4c43bed61b4ff4a7228, type: 3}
buttonClickClip: {fileID: 8300000, guid: a9aa2b3b2a44a784bba46038b467f994, type: 3}
attackSwingClip: {fileID: 8300000, guid: 04b0b69230019a140ad1818f9970a743, type: 3}
punchHitClip: {fileID: 8300000, guid: 64cf1790cb30f874590e1c96c4141691, type: 3}
@@ -59578,6 +59580,7 @@ MonoBehaviour:
playerDeathClip: {fileID: 8300000, guid: 291608b8d286e2a4580ff36324455ce2, type: 3}
transitionClip: {fileID: 8300000, guid: 64795b87003c2324fa0814fbc336066c, type: 3}
typingClip: {fileID: 8300000, guid: a4559fb7c4092fb479860fa337317ac3, type: 3}
typingPoolSize: 5
--- !u!82 &2016794388
AudioSource:
m_ObjectHideFlags: 0
+87 -23
View File
@@ -1,26 +1,32 @@
using UnityEngine;
using UnityEngine.SceneManagement;
[RequireComponent(typeof(AudioSource))]
public class SoundManager : MonoBehaviour
{
// 전역 어디서나 효과음을 호출할 수 있는 싱글톤 인스턴스
// 전역 어디서나 효과음과 BGM을 호출할 수 있는 싱글톤 인스턴스
public static SoundManager Instance { get; private set; }
[Header("BGM 배경음악 오디오 클립 등록")]
public AudioClip lobbyBgmClip; // 로비 씬 배경음악
public AudioClip battleBgmClip; // 배틀 스테이지 배경음악
[Header("효과음 오디오 클립 등록 슬롯")]
public AudioClip buttonClickClip; // 버튼 클릭음 (button sound 1/2)
public AudioClip buttonClickClip; // 버튼 클릭음
public AudioClip attackSwingClip; // 플레이어/적 공격 휘두르기 소리
public AudioClip punchHitClip; // 피격 타격음 (Punch Medium Big)
public AudioClip enemyDeathClip; // 적 사망음 (monster dead)
public AudioClip playerDeathClip; // 플레이어 사망음 (Dead)
public AudioClip transitionClip; // 성벽 통과 씬 전환음 (go to castle background1)
public AudioClip typingClip; // 대화창 글자 타이핑음 (button sound 1 등)
public AudioClip punchHitClip; // 피격 타격음
public AudioClip enemyDeathClip; // 적 사망음
public AudioClip playerDeathClip; // 플레이어 사망음
public AudioClip transitionClip; // 성벽 통과 씬 전환음
public AudioClip typingClip; // 대화창 글자 타이핑음
[Header("타자기 효과음 풀링 설정")]
[SerializeField] private int typingPoolSize = 5; // 동시 중첩 재생 가능한 최대 채널 수
[SerializeField] private int typingPoolSize = 5;
private AudioSource[] typingAudioPool;
private int nextPoolIndex = 0;
private AudioSource globalAudioSource;
private AudioSource globalSFXSource; // 효과음 전용 소스
private AudioSource bgmAudioSource; // BGM 전용 루프 소스
private void Awake()
{
@@ -34,24 +40,83 @@ public class SoundManager : MonoBehaviour
Instance = this;
DontDestroyOnLoad(gameObject);
globalAudioSource = GetComponent<AudioSource>();
if (globalAudioSource == null)
// 1. 효과음 전용 오디오 소스 설정
globalSFXSource = GetComponent<AudioSource>();
if (globalSFXSource == null)
{
globalAudioSource = gameObject.AddComponent<AudioSource>();
globalSFXSource = gameObject.AddComponent<AudioSource>();
}
// 시작 시 타자기 효과음용 오디오 풀 컴포넌트를 자식으로 미리 생성해 둡니다. (영구 재사용)
// 2. BGM 전용 독립 오디오 소스 생성 및 셋팅 (루프 기능 및 독립 볼륨)
bgmAudioSource = gameObject.AddComponent<AudioSource>();
bgmAudioSource.playOnAwake = false;
bgmAudioSource.loop = true;
// 3. 효과음 풀링 초기화
InitializeTypingPool();
}
// 오브젝트 가비지를 줄이기 위한 오디오 풀링 초기화
private void OnEnable()
{
// 유니티 씬 로드 완료 이벤트를 리스닝합니다. (씬 전환 시 BGM 자동 매핑용)
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnDisable()
{
// 이벤트 해제
SceneManager.sceneLoaded -= OnSceneLoaded;
}
// 씬이 완벽하게 로드되었을 때 실행되는 콜백 함수
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
PlayBgmForScene(scene.name);
}
// 씬 이름 기반 배경음악 교체 메서드
public void PlayBgmForScene(string sceneName)
{
AudioClip targetBgm = null;
// 씬 이름과 매치되는 배경음악 선별
if (sceneName == "Lobby")
{
targetBgm = lobbyBgmClip;
}
else if (sceneName == "battleStage")
{
targetBgm = battleBgmClip;
}
if (bgmAudioSource == null) return;
// 현재 이미 똑같은 배경음악이 돌고 있다면 끊김 없이 연주 유지
if (bgmAudioSource.clip == targetBgm && bgmAudioSource.isPlaying) return;
// 이전 배경음악 정지 및 새 음악 매핑 후 루프 재생
bgmAudioSource.Stop();
bgmAudioSource.clip = targetBgm;
if (targetBgm != null)
{
bgmAudioSource.volume = 0.45f; // 효과음에 비해 잔잔하도록 볼륨 기본 설정
bgmAudioSource.Play();
Debug.Log($"[SoundManager] '{sceneName}' 씬 진입 감지 -> BGM 자동 재생: {targetBgm.name}");
}
else
{
Debug.LogWarning($"[SoundManager] '{sceneName}' 씬에 등록된 BGM 오디오 클립이 없습니다.");
}
}
private void InitializeTypingPool()
{
typingAudioPool = new AudioSource[typingPoolSize];
for (int i = 0; i < typingPoolSize; i++)
{
GameObject child = new GameObject($"TypingAudioChannel_{i}");
child.transform.SetParent(this.transform); // SoundManager 자식으로 묶어 구조 정돈
child.transform.SetParent(this.transform);
AudioSource source = child.AddComponent<AudioSource>();
source.playOnAwake = false;
@@ -60,16 +125,16 @@ public class SoundManager : MonoBehaviour
}
}
// 기본 단발성 효과음 재생 메서드
// 기본 단발성 효과음 재생
public void PlayOneShot(AudioClip clip, float volume = 1f)
{
if (clip != null && globalAudioSource != null)
if (clip != null && globalSFXSource != null)
{
globalAudioSource.PlayOneShot(clip, volume);
globalSFXSource.PlayOneShot(clip, volume);
}
}
// 편리한 인게임 사운드 트리거 래퍼
// 효과음 바인딩 메서드
public void PlayButtonClick() => PlayOneShot(buttonClickClip, 0.7f);
public void PlayAttackSwing() => PlayOneShot(attackSwingClip, 0.85f);
public void PlayPunchHit() => PlayOneShot(punchHitClip, 0.95f);
@@ -77,20 +142,19 @@ public class SoundManager : MonoBehaviour
public void PlayPlayerDeath() => PlayOneShot(playerDeathClip, 1.0f);
public void PlayTransition() => PlayOneShot(transitionClip, 0.9f);
// 타자기 출력 연출 효과음 (풀링 및 피치 벤딩 결합)
// 타자기 효과음
public void PlayTyping()
{
if (typingClip == null || typingAudioPool == null || typingAudioPool.Length == 0) return;
// 순환 순서 인덱스의 오디오 채널을 하나 획득합니다.
AudioSource channel = typingAudioPool[nextPoolIndex];
nextPoolIndex = (nextPoolIndex + 1) % typingPoolSize;
if (channel != null)
{
channel.clip = typingClip;
channel.volume = 0.22f; // 음질 중첩을 고려해 볼륨 세부 튜닝
channel.pitch = Random.Range(0.85f, 1.15f); // 미세 피치 조절로 기계음 최소화
channel.volume = 0.22f;
channel.pitch = Random.Range(0.85f, 1.15f);
channel.Play();
}
}