반응형
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SoundManager : MonoBehaviour
{
private Dictionary<string, float> audioVolume = new Dictionary<string, float>();
private Dictionary<string, AudioClip> clipPool = new Dictionary<string, AudioClip>();
private float mainVolume = 1;
private List<SoundObject> soundObjectPool = new List<SoundObject>();
private Transform poolParent = null;
private bool isInit = false;
private static SoundManager _current;
public static SoundManager current
{
get
{
if (_current == null)
{
_current = new GameObject("SoundManager").AddComponent<SoundManager>();
DontDestroyOnLoad(_current.gameObject);
return _current;
}
else
return _current;
}
}
private void Awake()
{
Init();
}
private void Init()
{
this.audioVolume.Add("FX", 1 * this.mainVolume);
this.audioVolume.Add("BGM", 1 * this.mainVolume);
this.poolParent = new GameObject("SoundObject_PoolParent").transform;
this.poolParent.SetParent(this.transform);
this.poolParent.position = Vector3.zero;
this.poolParent.localRotation = Quaternion.identity;
this.poolParent.localScale = Vector3.one;
}
private SoundObject GetPoolingSoundObject()
{
for (int i = 0; i < this.soundObjectPool.Count; i++)
if (!this.soundObjectPool[i].gameObject.activeSelf)
{
this.soundObjectPool[i].transform.SetParent(null);
this.soundObjectPool[i].transform.position = Vector3.zero;
this.soundObjectPool[i].transform.localScale = Vector3.one;
this.soundObjectPool[i].transform.localRotation = Quaternion.identity;
this.soundObjectPool[i].gameObject.SetActive(true);
return this.soundObjectPool[i];
}
return null;
}
private AudioClip GetPoolingAudioClip(string path)
{
if (this.clipPool.ContainsKey(path))
return this.clipPool[path];
else
{
AudioClip clip = Resources.Load<AudioClip>(path);
if (clip != null)
{
this.clipPool[path] = clip;
return this.clipPool[path];
}
else
{
Debug.LogWarning("존재 하지 않는 오디오 경로 입니다.");
return null;
}
}
}
private SoundObject CreateSoundObject()
{
var soundObject = Instantiate(Resources.Load<SoundObject>("Sound/SoundObject"));
soundObject.transform.position = Vector3.zero;
soundObject.transform.localScale = Vector3.one;
soundObject.transform.localRotation = Quaternion.identity;
this.soundObjectPool.Add(soundObject);
return soundObject;
}
private SoundObject GetSoundObject(float volume, Vector3 soundPos)
{
var soundObject = GetPoolingSoundObject();
if (soundObject == null)
soundObject = CreateSoundObject();
soundObject.transform.position = soundPos;
return soundObject;
}
public SoundObject PlayFXSound(AudioClip clip, float volume, Vector3 soundPos)
{
var soundObject = GetSoundObject(volume * this.audioVolume["FX"], soundPos);
soundObject.PlayAudioOneShot(this, clip, volume);
return soundObject;
}
public SoundObject PlayBGMSound(AudioClip clip, float volume, Vector3 soundPos)
{
var soundObject = GetSoundObject(volume * this.audioVolume["FX"], soundPos);
soundObject.PlayAudioLoop(this, clip, volume);
return soundObject;
}
public SoundObject PlayFXSound(string audioPath, float volume, Vector3 soundPos)
{
var soundObject = GetSoundObject(volume * this.audioVolume["FX"], soundPos);
AudioClip clip = GetPoolingAudioClip(audioPath);
soundObject.PlayAudioOneShot(this, clip, volume);
return soundObject;
}
public SoundObject PlayBGMSound(string audioPath, float volume, Vector3 soundPos)
{
var soundObject = GetSoundObject(volume * this.audioVolume["FX"], soundPos);
AudioClip clip = GetPoolingAudioClip(audioPath);
soundObject.PlayAudioLoop(this, clip, volume);
return soundObject;
}
public void ReturnPool(SoundObject soundObject)
{
soundObject.transform.SetParent(this.poolParent);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Cube : MonoBehaviour
{
public AudioClip bulletSound = null;
private void Start()
{
//CreateSoundObject();
SoundManager.current.PlayFXSound(bulletSound, 1, this.transform.position);
}
private void CreateSoundObject()
{
//게임 오브젝트 생성 (사운드 오브젝트)
GameObject soundObject = new GameObject("SoundObject");
//생성된 사운드 오브젝트를 자식으로... -> 총알이 멀어지면 소리도 함께 멀어져야하니까
soundObject.transform.SetParent(this.transform);
//사운드 포지션, 로테이션 (0, 0, 0)으로 초기화
soundObject.transform.localPosition = Vector3.zero;
soundObject.transform.localRotation = Quaternion.identity;
//사운드 오브젝트에 AudioSource 컴포넌트 붙이기
AudioSource source = soundObject.AddComponent<AudioSource>();
//사운드 오브젝트 클립 연결
source.clip = bulletSound;
//반복 재생할건지. 반복 재생할 거면 true 한번만 재생할 거면 false
source.loop = true;
//3D 사운드, pan level key값 1로
//1에 가까워질수록 3D 사운드에 가까워짐
AnimationCurve ac = source.GetCustomCurve(AudioSourceCurveType.SpatialBlend);
Keyframe[] keys = new Keyframe[1];
for(int i = 0; i <keys.Length; i++)
{
keys[i].value = 1.0f;
}
ac.keys = keys;
source.SetCustomCurve(AudioSourceCurveType.SpatialBlend, ac);
//==============================================//
//클립 재생
source.Play();
}
private void Playsound()
{
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SoundObject : MonoBehaviour
{
public enum SoundState
{
Init,
Play,
Pause,
Stop
}
private AudioSource audioSource = null;
private SoundManager parent = null;
private float wasAudioVol = 0;
private SoundState state = SoundState.Init;
private void Awake()
{
this.audioSource = this.GetComponent<AudioSource>();
}
public void PlayAudio(SoundManager parent, AudioClip audioClip, float vol, bool isLoop)
{
if (audioClip == null)
{
Debug.LogError("존재하지 않는 클립 입니다");
StopAudio();
return;
}
this.audioSource.clip = audioClip;
this.parent = parent;
this.audioSource.volume = vol;
this.state = SoundState.Play;
if (isLoop)
{
this.audioSource.loop = true;
this.audioSource.Play();
}
else
{
this.audioSource.loop = false;
this.audioSource.Play();
}
}
public void PlayAudioOneShot(SoundManager parent, AudioClip audioClip, float vol)
{
PlayAudio(parent, audioClip, vol, false);
}
public void PlayAudioLoop(SoundManager parent, AudioClip audioClip, float vol)
{
PlayAudio(parent, audioClip, vol, true);
}
public void PauseAudio()
{
this.audioSource.Pause();
this.state = SoundState.Pause;
}
public void StopAudio()
{
this.audioSource.Stop();
ClearAudio();
}
public void ClearAudio()
{
this.state = SoundState.Stop;
this.audioSource.clip = null;
this.gameObject.SetActive(false);
this.parent.ReturnPool(this);
}
private void Update()
{
if (this.audioSource.time >= this.audioSource.clip.length)
ClearAudio();
}
}
반응형
'Unity_C# > Unity' 카테고리의 다른 글
[Unity] Unity 세팅 (0) | 2021.06.04 |
---|---|
[Unity/C#] Steam VR teleport할 깜빡거리는 문제 (0) | 2020.09.15 |
[Unity/C#] Audio 관리 코드 (0) | 2020.09.11 |
[Unity/C#] Unity와 Visual Studio가 연결이 안되어 있을 때 (2) | 2020.09.07 |
[Unity] Steam VR / Vive Input Utility 컨트롤러 진동 주는 법 (0) | 2020.08.21 |