Unity:通过脚本播放音频并在运行时添加Audio Listener
问题分析与解决
你的代码里立方体无法发声的核心原因是AudioSource没有实际的音频数据可播放——你只设置了pitch参数,但没有给它提供任何音频剪辑,也没有生成实时的正弦波音频流。以下是修复方案:
修复步骤
1. 替换音频生成逻辑:使用OnAudioFilterRead实时生成正弦波
Unity的AudioSource如果没有绑定AudioClip,默认不会产生声音。我们可以通过OnAudioFilterRead回调来实时生成正弦波音频数据,完全通过代码实现,无需依赖外部音频文件。
修改Cube类的代码如下:
[RequireComponent(typeof(AudioSource))] public class Cube : MonoBehaviour { public float amplitude = 0.5f; // 正弦波振幅(控制音量) public float baseFrequency = 440f; // 基础频率(A4标准音) public float speed = 1f; // 频率变化速度 private Vector3 startPosition; private AudioSource audioSource; private float phase; // 正弦波相位,避免重启音频时重置 void Start() { startPosition = transform.position; audioSource = GetComponent<AudioSource>(); // 关键设置:禁用空间音频(避免距离过远导致音量衰减到0) audioSource.spatialBlend = 0f; audioSource.loop = true; audioSource.Play(); // 提前启动播放,触发OnAudioFilterRead回调 } void Update() { // 保留立方体位置动画逻辑 float time = Time.time * speed; float sineValue = amplitude * Mathf.Sin(2 * Mathf.PI * baseFrequency * time); transform.position = startPosition + new Vector3(0f, sineValue, 0f); } // 实时生成音频数据的核心回调 void OnAudioFilterRead(float[] data, int channels) { float sampleRate = AudioSettings.outputSampleRate; // 让频率随时间变化,和立方体动画联动 float dynamicFrequency = baseFrequency + Mathf.Sin(Time.time * speed) * 100f; for (int i = 0; i < data.Length; i += channels) { // 生成正弦波样本 float sample = amplitude * Mathf.Sin(phase); // 将样本应用到所有声道(立体声需同时赋值左右声道) for (int j = 0; j < channels; j++) { data[i + j] = sample; } // 更新相位并防止溢出 phase += 2 * Mathf.PI * dynamicFrequency / sampleRate; if (phase > 2 * Mathf.PI) { phase -= 2 * Mathf.PI; } } } }
2. 检查AudioListener的位置
你的代码中创建了位于Vector3.zero的AudioListener,而立方体生成在(10,10,10)。如果需要3D音频效果,可以调整audioSource.spatialBlend为1,并将立方体移动到AudioListener附近(比如Vector3(0,0,0));如果只需要2D音频,保持spatialBlend=0即可,不受位置影响。
3. 移除无效的pitch逻辑
之前的代码试图用正弦值控制pitch,但这不是生成正弦波音频的正确方式——pitch仅用于改变已有音频的播放速度,没有音频源的话毫无意义。修复后的代码直接生成对应频率的正弦波样本,无需依赖pitch调整。
额外注意事项
- 确保Unity编辑器的Audio Mixer主轨道未静音,且音量设置正常。
- 测试时可以降低振幅(比如设为0.2),避免音频过载失真。
内容的提问来源于stack exchange,提问作者RandomNumberFun
相关产品推荐
相关产品推荐

