You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测Unity AudioSource的音量变化?

Unity AudioSource 音量变化检测方案

Unity 原生的 AudioSource 并没有提供直接监听音量变化的回调或事件,你可以通过以下几种方案实现需求:

1. 自定义封装属性,触发自定义事件

通过封装类包裹 AudioSource,将 volume 替换为带逻辑的属性,在音量修改时主动触发事件。这种方式能统一控制所有音量修改的入口,是最推荐的方案。

using UnityEngine;
using UnityEngine.Events;

public class AudioVolumeMonitor : MonoBehaviour
{
    [SerializeField] private AudioSource _audioSource;
    public UnityEvent<float> OnVolumeChanged;

    private float _currentVolume;

    private void Awake()
    {
        _audioSource ??= GetComponent<AudioSource>();
        _currentVolume = _audioSource.volume;
    }

    public float Volume
    {
        get => _audioSource.volume;
        set
        {
            // 浮点精度容错,避免微小数值波动误触发
            if (Mathf.Abs(value - _currentVolume) > 0.001f)
            {
                _currentVolume = value;
                _audioSource.volume = value;
                OnVolumeChanged?.Invoke(_currentVolume);
            }
        }
    }
}

用法:将该脚本挂载到带有 AudioSource 的物体上,在 Inspector 面板中绑定 OnVolumeChanged 的回调逻辑,之后所有音量调整都通过这个脚本的 Volume 属性进行,即可在音量变化时触发事件。

2. 轮询检测音量变化

如果无法统一修改所有音量访问的代码,可以在 Update 中定期检查音量值,与上一帧的记录对比,发现变化时执行逻辑。

using UnityEngine;

public class AudioVolumeChecker : MonoBehaviour
{
    [SerializeField] private AudioSource _audioSource;
    [SerializeField] private float _checkInterval = 0.1f; // 检测间隔,平衡性能与灵敏度

    private float _lastVolume;
    private float _timer;

    private void Awake()
    {
        _audioSource ??= GetComponent<AudioSource>();
        _lastVolume = _audioSource.volume;
    }

    private void Update()
    {
        _timer += Time.deltaTime;
        if (_timer >= _checkInterval)
        {
            _timer = 0;
            float currentVolume = _audioSource.volume;
            if (Mathf.Abs(currentVolume - _lastVolume) > 0.001f)
            {
                HandleVolumeChange(currentVolume);
                _lastVolume = currentVolume;
            }
        }
    }

    private void HandleVolumeChange(float newVolume)
    {
        // 这里编写音量变化后的处理逻辑
        Debug.Log($"音量更新:{newVolume}");
    }
}

注意:不要将检测间隔设置得过小,否则会增加不必要的性能开销。

3. 编辑器监听Inspector音量修改(进阶)

如果需要捕获在 Inspector 面板中手动修改音量的操作,可以通过自定义编辑器实现:

using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(AudioSource))]
public class AudioSourceVolumeEditor : Editor
{
    private float _lastVolume;

    private void OnEnable()
    {
        var audioSource = target as AudioSource;
        _lastVolume = audioSource.volume;
    }

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        var audioSource = target as AudioSource;
        
        if (Mathf.Abs(audioSource.volume - _lastVolume) > 0.001f)
        {
            _lastVolume = audioSource.volume;
            // 通过SendMessage通知物体上的方法,也可以改用事件系统
            audioSource.SendMessage("OnInspectorVolumeChanged", _lastVolume, SendMessageOptions.DontRequireReceiver);
        }
    }
}

用法:在带有 AudioSource 的物体上添加一个包含 OnInspectorVolumeChanged(float newVolume) 方法的脚本,即可接收 Inspector 中音量修改的通知。


内容的提问来源于stack exchange,提问作者iv67

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 18:05:25