using UnityEngine; using Unheimlich.Gameplay.Player; namespace Unheimlich.Audio { public class AudioSourceDemo : MonoBehaviour { [Header("Demo Settings")] [SerializeField] private AudioClip _clip; [SerializeField] private bool _playOnStart = true; [SerializeField] private bool _loop = true; [SerializeField] private float _volume = 0.5f; [SerializeField] private float _sourceMinDistance = 1f; [SerializeField] private float _sourceMaxDistance = 20; [Header("Distance Culling")] [SerializeField] private bool _enableDistanceCulling = true; [SerializeField] private float _cullingDistance = 50f; [SerializeField] private float _fadeStartDistance = 40f; private AudioSource _source; private bool _hasStarted = false; private float _savedTime = 0f; private bool _wasPlaying = false; private bool _isCulled = false; private Transform _player; public float OriginalVolume => _volume; public float GetDistanceFadeMultiplier(Vector3 listenerPosition) { if (!_enableDistanceCulling) return 1f; float distance = Vector3.Distance(transform.position, listenerPosition); if (distance > _cullingDistance) return 0f; if (distance > _fadeStartDistance) { float fadeRange = _cullingDistance - _fadeStartDistance; float fadeAmount = (distance - _fadeStartDistance) / fadeRange; return 1f - Mathf.Clamp01(fadeAmount); } return 1f; } private void Awake() { _source = GetComponent(); if (_source == null) _source = gameObject.AddComponent(); _source.clip = _clip; _source.loop = _loop; _source.volume = _volume; _source.playOnAwake = false; _source.spatialBlend = 1f; _source.rolloffMode = AudioRolloffMode.Logarithmic; _source.minDistance = _sourceMinDistance; _source.maxDistance = _sourceMaxDistance; } private void OnEnable() { if (_wasPlaying && _savedTime > 0f) { _source.time = _savedTime; _source.Play(); } } private void Start() { if (_playOnStart && _clip != null && !_hasStarted && !_source.isPlaying) { _source.Play(); _hasStarted = true; } Player playerObj = Player.Instance; if (playerObj != null) _player = playerObj.transform; } private void Update() { if (_enableDistanceCulling && _player != null && _source != null) { float distance = Vector3.Distance(transform.position, _player.position); if (distance > _cullingDistance) { if (!_isCulled) { _source.volume = 0f; _isCulled = true; } } else if (distance > _fadeStartDistance) { float fadeRange = _cullingDistance - _fadeStartDistance; float fadeAmount = (distance - _fadeStartDistance) / fadeRange; fadeAmount = Mathf.Clamp01(fadeAmount); _source.volume = _volume * (1f - fadeAmount); _isCulled = false; } else { if (_isCulled || _source.volume != _volume) { _source.volume = _volume; _isCulled = false; } } } } private void OnDisable() { _wasPlaying = _source.isPlaying; _savedTime = _source.time; } } }