private float updateInterval = 0.1f; // 0.1초 간격으로 실행
private float nextUpdate = 0f;
void Update()
{
if (Time.time >= nextUpdate)
{
nextUpdate = Time.time + updateInterval;
UpdateAudio();
}
}
이렇게 하면 UpdateAudio() 함수가 매 프레임이 아닌 0.1초 간격으로 호출되어 퍼포먼스 부담을 줄일 수 있습니다.
루프 켜져있으면 클립 변경 알아서 되지 않냐
아니요, 루프가 켜져 있어도 audioSource.clip을 변경하면 자동으로 재생되지 않습니다. audioSource.clip을 변경하면 새로운 클립으로 교체될 뿐, 재생 상태가 유지되지 않기 때문에 클립을 변경할 때마다 Play()를 호출해야 합니다.
Debug.Log("Current Playing : " + audioSource.clip); 이렇게 하니까 안 뜨는데 이름 뜨게 하려면 어케 함
Debug.Log("Current Playing: " + audioSource.clip.name);
loop 하면 isPlaying은 계속 true로 되는거임?
네, loop가 활성화된 상태에서는 audioSource.isPlaying이 항상 true로 유지됩니다. 이는 클립이 반복되기 때문에, 재생이 끝날 일이 없기 때문입니다.
if (distance > 20f)
{
audioSource.volume = 0.65f - 0.3f * (Mathf.Clamp(distance, 20f, 30f) - 20f) / 10f;
if (audioSource.clip != heartbeat_slow)
{
StartCoroutine(FadeAudio(heartbeat_slow));
}
}
else
{
audioSource.pitch = 1.5f - 0.5f * (Mathf.Clamp(distance, 0f, 20f) / 20f);
if (audioSource.clip != heartbeat_fast)
{
StartCoroutine(FadeAudio(heartbeat_fast));
}
}
이걸 update 문에 넣고
IEnumerator<UnityEngine.WaitForSeconds> FadeAudio(AudioClip newClip)
{
// Fade out
for (float vol = audioSource.volume; vol > 0; vol -= Time.deltaTime)
{
audioSource.volume = vol;
yield return null;
}
// Switch clips
audioSource.clip = newClip;
audioSource.Play();
// Fade in
for (float vol = 0; vol < 0.65f; vol += Time.deltaTime)
{
audioSource.volume = vol;
yield return null;
}
}
이걸 선언하면
오디오 간 전환할 때 볼륨이 fade in 하면서 들어옴.
근데 이건 bgm 바뀔때나 자연스러운거지
지금같은 경우엔 안 자연스러운듯
// 거리에 따라 볼륨과 피치를 조절
// distance == 20f일 땐 볼륨이 0.65가 되고, distance == 30f가 될 때까지 0.35에 선형적으로 가까워지다가 이후에는 0.35 고정
// distance == 20f일 땐 피치가 1이고, distance == 0f가 될 때까지 1.5에 선형적으로 가까워짐
float distance = Vector3.Distance(Monster.transform.position, transform.position);
audioSource.volume = (float)(0.65 - 0.3 * (Mathf.Clamp(distance, 20f, 30f) - 20f) / 10f);
audioSource.pitch = (float)(1.5 - 0.5 * (Mathf.Clamp(distance, 0f, 20f) / 20f));
너무 간단해져버렸다
이제 실제 게임에 적용하려면
거리를 잴 몬스터를 할당하고,
밤이 됐을 때만 play를 하게 하는 작업이 필요함.
[SerializeField] private GameObject Monster;
이거는 게임 중에 변경되면 Inspector에서 안 보임?
[SerializeField] private GameObject Monster;는 Inspector에서만 값을 설정할 수 있도록 만든 필드로, Inspector 창에서는 보이지만 게임 중에는 값을 직접 변경할 수 없습니다. 즉, 런타임 중에는 Inspector에서 변경 사항을 볼 수 없습니다.
Inspector에서 런타임 중 값을 실시간으로 보고 싶다면 Debug.Log(Monster) 등을 사용하여 콘솔에 출력하거나, 디버그 창에 표시할 수 있습니다.
using System.Collections.Generic;
using UnityEngine;
using System.Collections;
using Photon.Pun;
using System.Linq;
public class Heartbeat : MonoBehaviour
{
private AudioSource audioSource;
private float distance;
[SerializeField] private GameObject Monster;
void Start()
{
audioSource = GetComponent<AudioSource>();
audioSource.loop = true;
}
private void Update()
{
if (!NetworkManager.Instance || NetworkManager.Instance.IsMonster()) return;
if (Monster == null)
{
List<GameObject> Monsters = NetworkManager.Instance.Monsters.Values.Select(monster => monster.gameObject).ToList();
if (Monsters.Count > 0)
{
Monster = Monsters[0];
Debug.Log("Hearbeat.cs :: 몬스터 찾음. 이름은 " + Monster.name);
}
else
{
Debug.Log("Hearbeat.cs :: 몬스터가 없음");
return;
}
}
// 밤이고, 관전 중이 아닐 때, 몬스터와 가까워질수록 빠르고 크게 심장소리 재생
if (!TimeManager.instance.isDay && !SpectatorManager.instance.isSpectating)
{
Debug.Log("Hearbeat.cs :: 심장소리 재생");
if (!audioSource.isPlaying)
{
audioSource.Play();
}
else
{
// 거리에 따라 볼륨과 피치를 조절
distance = Vector3.Distance(Monster.transform.position, transform.position);
audioSource.volume = (float)(1 - 0.3 * (Mathf.Clamp(distance, 50f, 100f) - 50f) / 50f);
audioSource.pitch = (float)(1.5 - 0.5 * (Mathf.Clamp(distance, 0f, 50f) / 50f));
}
}
else
{
Debug.Log("Hearbeat.cs :: 심장소리 멈춤");
audioSource.Stop();
}
}
}
저번에 서버 팀원이 도와줘서 구현 다 해놨던걸로 몬스터 할당 및 밤낮 여부 판별 추가