音频系统
Unity 的音频系统让你可以轻松添加音效和音乐,提升游戏的沉浸感。
音频系统概述
音频系统组件:
├── AudioClip - 音频资源
├── AudioSource - 音频播放器
├── AudioListener - 音频接收器(通常放在主相机)
└── AudioMixer - 音频混音器
AudioClip(音频片段)
AudioClip 是 Unity 中的音频资源。
支持的音频格式
| 格式 | 说明 |
|---|---|
| WAV | 无损格式,适合短音效 |
| MP3 | 有损压缩,适合音乐 |
| OGG | 开源格式,适合长音频 |
| AIFF | 苹果无损格式 |
导入设置
选中音频文件,Inspector 中的设置:
| 属性 | 说明 |
|---|---|
| Force To Mono | 强制单声道 |
| Load In Background | 后台加载 |
| Preload Audio Data | 预加载音频数据 |
| Load Type | 加载方式 |
| Compression Format | 压缩格式 |
Load Type 选项:
Decompress On Load- 加载时解压(内存占用大,播放快)Compressed In Memory- 内存中压缩(内存占用小,CPU 开销大)Streaming- 流式加载(适合长音乐)
AudioSource(音频源)
AudioSource 组件用于播放音频。
主要属性
public class AudioSourceController : MonoBehaviour
{
public AudioSource audioSource;
void Start()
{
// 设置音频片段
audioSource.clip = someAudioClip;
// 设置音量 (0-1)
audioSource.volume = 0.5f;
// 设置音高 (-3 到 3,1 为正常)
audioSource.pitch = 1f;
// 设置循环
audioSource.loop = true;
// 设置静音
audioSource.mute = false;
// 设置 3D 音效属性
audioSource.spatialBlend = 0f; // 0 = 2D, 1 = 3D
audioSource.minDistance = 1f;
audioSource.maxDistance = 50f;
}
}
播放控制
public class AudioPlayback : MonoBehaviour
{
public AudioSource audioSource;
void PlayAudio()
{
// 播放
audioSource.Play();
// 延迟播放
audioSource.PlayDelayed(2f); // 延迟 2 秒
// 指定时间播放
audioSource.time = 10f; // 从 10 秒处开始
audioSource.Play();
// 暂停
audioSource.Pause();
// 停止
audioSource.Stop();
// 检查是否正在播放
if (audioSource.isPlaying)
{
Debug.Log("正在播放");
}
}
// 播放一次性音效(不占用 AudioSource)
public AudioClip clip;
void PlayOneShot()
{
audioSource.PlayOneShot(clip, 0.8f); // 音量 0.8
}
// 在指定位置播放音效
public AudioClip explosionClip;
void PlayAtPosition()
{
AudioSource.PlayClipAtPoint(explosionClip, transform.position, 1f);
}
}
AudioListener(音频监听器)
AudioListener 接收场景中的音频,通常放在主相机上。
public class AudioListenerController : MonoBehaviour
{
void Start()
{
// 设置全局音量
AudioListener.volume = 1f;
// 暂停所有音频
AudioListener.pause = false;
// 设置全局音效速度
AudioListener.velocityUpdateMode = AudioVelocityUpdateMode.Fixed;
}
}
注意
场景中只能有一个激活的 AudioListener。
3D 音效
空间化音频
public class SpatialAudio : MonoBehaviour
{
public AudioSource audioSource;
void Start()
{
// 完全 3D 音效
audioSource.spatialBlend = 1f;
// 音量衰减模式
audioSource.rolloffMode = AudioRolloffMode.Linear;
// Logarithmic - 对数衰减(真实)
// Linear - 线性衰减
// Custom - 自定义曲线
// 最小/最大距离
audioSource.minDistance = 5f; // 在此距离内音量最大
audioSource.maxDistance = 100f; // 在此距离外音量最小
// 多普勒效应(移动时的音高变化)
audioSource.dopplerLevel = 1f;
// 扩散角度
audioSource.spread = 0f; // 0 = 全方向,360 = 定向
}
}
AudioMixer(音频混音器)
AudioMixer 用于管理和混合多个音频源。
创建 AudioMixer
- Assets > Create > Audio Mixer
- 在 Audio Mixer 窗口(Window > Audio > Audio Mixer)中编辑
混音器结构
Master (主混音器)
├── BGM (音乐组)
│ └── 背景音乐
├── SFX (音效组)
│ ├── UI 音效
│ ├── 角色音效
│ └── 环境音效
└── Voice (语音组)
└── 对话语音
代码控制混音器
using UnityEngine.Audio;
public class AudioMixerController : MonoBehaviour
{
public AudioMixer audioMixer;
// 设置音量(使用分贝)
public void SetMasterVolume(float volume)
{
// volume: 0.0001 到 1,对应 -80dB 到 0dB
float dB = volume > 0 ? 20 * Mathf.Log10(volume) : -80;
audioMixer.SetFloat("MasterVolume", dB);
}
public void SetBGMVolume(float volume)
{
float dB = volume > 0 ? 20 * Mathf.Log10(volume) : -80;
audioMixer.SetFloat("BGMVolume", dB);
}
public void SetSFXVolume(float volume)
{
float dB = volume > 0 ? 20 * Mathf.Log10(volume) : -80;
audioMixer.SetFloat("SFXVolume", dB);
}
// 获取当前音量
public float GetVolume(string parameterName)
{
float value;
audioMixer.GetFloat(parameterName, out value);
return Mathf.Pow(10, value / 20);
}
// 快照切换(用于不同场景音效)
public AudioMixerSnapshot normalSnapshot;
public AudioMixerSnapshot underwaterSnapshot;
public void EnterWater()
{
// 2 秒过渡到水下音效
underwaterSnapshot.TransitionTo(2f);
}
public void ExitWater()
{
normalSnapshot.TransitionTo(1f);
}
}
音频管理器
创建一个全局音频管理器:
public class AudioManager : MonoBehaviour
{
public static AudioManager Instance;
[Header("混音器")]
public AudioMixer audioMixer;
[Header("音频源")]
public AudioSource bgmSource;
public AudioSource sfxSource;
[Header("音频库")]
public AudioClip[] bgmClips;
public AudioClip[] sfxClips;
void Awake()
{
// 单例模式
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
// 播放背景音乐
public void PlayBGM(int index, bool loop = true)
{
if (index < 0 || index >= bgmClips.Length) return;
bgmSource.clip = bgmClips[index];
bgmSource.loop = loop;
bgmSource.Play();
}
public void PlayBGM(string name, bool loop = true)
{
AudioClip clip = System.Array.Find(bgmClips, x => x.name == name);
if (clip != null)
{
bgmSource.clip = clip;
bgmSource.loop = loop;
bgmSource.Play();
}
}
// 停止背景音乐
public void StopBGM()
{
bgmSource.Stop();
}
// 播放音效
public void PlaySFX(int index)
{
if (index < 0 || index >= sfxClips.Length) return;
sfxSource.PlayOneShot(sfxClips[index]);
}
public void PlaySFX(string name)
{
AudioClip clip = System.Array.Find(sfxClips, x => x.name == name);
if (clip != null)
{
sfxSource.PlayOneShot(clip);
}
}
// 在指定位置播放音效
public void PlaySFXAtPosition(string name, Vector3 position)
{
AudioClip clip = System.Array.Find(sfxClips, x => x.name == name);
if (clip != null)
{
AudioSource.PlayClipAtPoint(clip, position);
}
}
// 音量控制
public void SetMasterVolume(float volume)
{
audioMixer.SetFloat("MasterVolume", VolumeToDecibel(volume));
}
public void SetBGMVolume(float volume)
{
audioMixer.SetFloat("BGMVolume", VolumeToDecibel(volume));
}
public void SetSFXVolume(float volume)
{
audioMixer.SetFloat("SFXVolume", VolumeToDecibel(volume));
}
float VolumeToDecibel(float volume)
{
return volume > 0 ? 20 * Mathf.Log10(volume) : -80;
}
}
音效触发示例
public class PlayerAudio : MonoBehaviour
{
public AudioClip jumpSound;
public AudioClip landSound;
public AudioClip footstepSound;
float footstepTimer;
public float footstepInterval = 0.5f;
void Update()
{
// 跳跃
if (Input.GetButtonDown("Jump"))
{
AudioManager.Instance?.PlaySFX("Jump");
}
// 脚步声
if (IsMoving() && IsGrounded())
{
footstepTimer += Time.deltaTime;
if (footstepTimer >= footstepInterval)
{
AudioManager.Instance?.PlaySFX("Footstep");
footstepTimer = 0;
}
}
}
void OnCollisionEnter(Collision collision)
{
// 着陆
if (collision.relativeVelocity.magnitude > 5f)
{
AudioManager.Instance?.PlaySFX("Land");
}
}
}
音频优化
性能建议
-
使用合适的加载类型
- 短音效:
Decompress On Load - 长音乐:
Streaming - 中等长度:
Compressed In Memory
- 短音效:
-
强制单声道
- 3D 音效勾选
Force To Mono - 减少内存占用
- 3D 音效勾选
-
使用 AudioMixer
- 批量控制音量
- 应用音效(混响、低通等)
-
对象池播放音效
public class SFXObjectPool : MonoBehaviour
{
public GameObject audioSourcePrefab;
private Queue<AudioSource> pool = new Queue<AudioSource>();
public void PlaySFX(AudioClip clip, Vector3 position)
{
AudioSource source = GetAudioSource();
source.transform.position = position;
source.clip = clip;
source.Play();
StartCoroutine(ReturnToPool(source, clip.length));
}
AudioSource GetAudioSource()
{
if (pool.Count > 0)
return pool.Dequeue();
return Instantiate(audioSourcePrefab).GetComponent<AudioSource>();
}
IEnumerator ReturnToPool(AudioSource source, float delay)
{
yield return new WaitForSeconds(delay);
pool.Enqueue(source);
}
}
下一步
掌握音频系统后,你可以: