조개 사운드
This commit is contained in:
@@ -38,6 +38,36 @@ public class ClamOpenClose : MonoBehaviour
|
||||
[Tooltip("쾅 하고 닫힌 뒤 원래 닫힌 위치로 돌아오는 시간입니다.")]
|
||||
[SerializeField] private float snapCloseOvershootDuration = 0.02f;
|
||||
|
||||
[Header("Sound")]
|
||||
[SerializeField] private AudioSource audioSource;
|
||||
|
||||
[Tooltip("조개가 닫히며 입이 부딪힐 때 재생할 사운드입니다. 여러 개를 넣으면 랜덤 재생됩니다.")]
|
||||
[SerializeField] private AudioClip[] closeImpactSounds;
|
||||
|
||||
[Tooltip("조개가 닫히기 시작할 때 재생할 예고/마찰 사운드입니다. 필요 없으면 비워두세요.")]
|
||||
[SerializeField] private AudioClip closeStartSound;
|
||||
|
||||
[Range(0f, 1f)]
|
||||
[SerializeField] private float closeImpactVolume = 1f;
|
||||
|
||||
[Range(0f, 1f)]
|
||||
[SerializeField] private float closeStartVolume = 0.5f;
|
||||
|
||||
[Tooltip("닫힘 충격음의 최소 피치입니다.")]
|
||||
[SerializeField] private float minImpactPitch = 0.9f;
|
||||
|
||||
[Tooltip("닫힘 충격음의 최대 피치입니다.")]
|
||||
[SerializeField] private float maxImpactPitch = 1.1f;
|
||||
|
||||
[Tooltip("닫힘 충격음의 볼륨을 살짝 랜덤하게 줄지 여부입니다.")]
|
||||
[SerializeField] private bool randomizeImpactVolume = true;
|
||||
|
||||
[Tooltip("볼륨 랜덤 적용 시 최소 배율입니다.")]
|
||||
[SerializeField] private float minImpactVolumeMultiplier = 0.85f;
|
||||
|
||||
[Tooltip("볼륨 랜덤 적용 시 최대 배율입니다.")]
|
||||
[SerializeField] private float maxImpactVolumeMultiplier = 1.0f;
|
||||
|
||||
[Header("Start Option")]
|
||||
[SerializeField] private bool startAutomatically = true;
|
||||
[SerializeField] private bool startOpened = false;
|
||||
@@ -74,6 +104,17 @@ private void Awake()
|
||||
if (found != null) downShell = found;
|
||||
}
|
||||
|
||||
if (audioSource == null)
|
||||
{
|
||||
audioSource = GetComponent<AudioSource>();
|
||||
}
|
||||
|
||||
if (audioSource != null)
|
||||
{
|
||||
audioSource.playOnAwake = false;
|
||||
audioSource.loop = false;
|
||||
}
|
||||
|
||||
if (upShell == null)
|
||||
{
|
||||
Debug.LogWarning("[ClamOpenClose] UpShell이 연결되지 않았습니다.", this);
|
||||
@@ -145,6 +186,7 @@ private IEnumerator OpenCloseRoutine()
|
||||
yield return new WaitForSeconds(openWait);
|
||||
|
||||
isClosing = true;
|
||||
PlayCloseStartSound();
|
||||
onCloseStarted?.Invoke();
|
||||
|
||||
yield return MoveShells(
|
||||
@@ -158,6 +200,10 @@ private IEnumerator OpenCloseRoutine()
|
||||
|
||||
isOpen = false;
|
||||
|
||||
// 실제 입이 맞닿는 타이밍.
|
||||
// 랜덤으로 닫혀도 항상 닫힘 동작이 끝난 직후 실행됨.
|
||||
PlayCloseImpactSound();
|
||||
|
||||
if (useSnapClose)
|
||||
{
|
||||
yield return SnapCloseEffect();
|
||||
@@ -225,6 +271,47 @@ private IEnumerator SnapCloseEffect()
|
||||
downShell.localRotation = downClosedRot;
|
||||
}
|
||||
|
||||
private void PlayCloseStartSound()
|
||||
{
|
||||
if (audioSource == null || closeStartSound == null)
|
||||
return;
|
||||
|
||||
audioSource.pitch = 1f;
|
||||
audioSource.PlayOneShot(closeStartSound, closeStartVolume);
|
||||
}
|
||||
|
||||
private void PlayCloseImpactSound()
|
||||
{
|
||||
if (audioSource == null)
|
||||
return;
|
||||
|
||||
if (closeImpactSounds == null || closeImpactSounds.Length == 0)
|
||||
return;
|
||||
|
||||
AudioClip clip = closeImpactSounds[Random.Range(0, closeImpactSounds.Length)];
|
||||
|
||||
if (clip == null)
|
||||
return;
|
||||
|
||||
float originalPitch = audioSource.pitch;
|
||||
|
||||
audioSource.pitch = Random.Range(minImpactPitch, maxImpactPitch);
|
||||
|
||||
float volume = closeImpactVolume;
|
||||
|
||||
if (randomizeImpactVolume)
|
||||
{
|
||||
float volumeMultiplier = Random.Range(minImpactVolumeMultiplier, maxImpactVolumeMultiplier);
|
||||
volume *= volumeMultiplier;
|
||||
}
|
||||
|
||||
audioSource.PlayOneShot(clip, volume);
|
||||
|
||||
// PlayOneShot은 재생 직후 피치를 바꿔도 이미 재생 중인 소리에 영향이 적지만,
|
||||
// 다음 사운드 재생을 위해 기본 피치로 복구.
|
||||
audioSource.pitch = originalPitch;
|
||||
}
|
||||
|
||||
private void SetClosedImmediately()
|
||||
{
|
||||
if (upShell != null)
|
||||
|
||||
Reference in New Issue
Block a user