사운드 추가 및 리소스 깨지는 문제 수정

This commit is contained in:
김민구
2026-07-08 05:36:12 +09:00
parent 60e65a4c7d
commit 6e641be1c7
29 changed files with 472 additions and 119 deletions
@@ -0,0 +1,97 @@
using UnityEngine;
[RequireComponent(typeof(AudioSource))]
public class SoundManager : MonoBehaviour
{
// 전역 어디서나 효과음을 호출할 수 있는 싱글톤 인스턴스
public static SoundManager Instance { get; private set; }
[Header("효과음 오디오 클립 등록 슬롯")]
public AudioClip buttonClickClip; // 버튼 클릭음 (button sound 1/2)
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 등)
[Header("타자기 효과음 풀링 설정")]
[SerializeField] private int typingPoolSize = 5; // 동시 중첩 재생 가능한 최대 채널 수
private AudioSource[] typingAudioPool;
private int nextPoolIndex = 0;
private AudioSource globalAudioSource;
private void Awake()
{
// 싱글톤 보장
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
globalAudioSource = GetComponent<AudioSource>();
if (globalAudioSource == null)
{
globalAudioSource = gameObject.AddComponent<AudioSource>();
}
// 시작 시 타자기 효과음용 오디오 풀 컴포넌트를 자식으로 미리 생성해 둡니다. (영구 재사용)
InitializeTypingPool();
}
// 오브젝트 가비지를 줄이기 위한 오디오 풀링 초기화
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 자식으로 묶어 구조 정돈
AudioSource source = child.AddComponent<AudioSource>();
source.playOnAwake = false;
source.loop = false;
typingAudioPool[i] = source;
}
}
// 기본 단발성 효과음 재생 메서드
public void PlayOneShot(AudioClip clip, float volume = 1f)
{
if (clip != null && globalAudioSource != null)
{
globalAudioSource.PlayOneShot(clip, volume);
}
}
// 편리한 인게임 사운드 트리거 래퍼들
public void PlayButtonClick() => PlayOneShot(buttonClickClip, 0.7f);
public void PlayAttackSwing() => PlayOneShot(attackSwingClip, 0.85f);
public void PlayPunchHit() => PlayOneShot(punchHitClip, 0.95f);
public void PlayEnemyDeath() => PlayOneShot(enemyDeathClip, 1.0f);
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.Play();
}
}
}