跳到主要内容

音频系统

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

  1. Assets > Create > Audio Mixer
  2. 在 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");
}
}
}

音频优化

性能建议

  1. 使用合适的加载类型

    • 短音效:Decompress On Load
    • 长音乐:Streaming
    • 中等长度:Compressed In Memory
  2. 强制单声道

    • 3D 音效勾选 Force To Mono
    • 减少内存占用
  3. 使用 AudioMixer

    • 批量控制音量
    • 应用音效(混响、低通等)
  4. 对象池播放音效

    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);
    }
    }

下一步

掌握音频系统后,你可以:

  1. 学习 粒子系统 添加视觉特效
  2. 了解 动画系统 制作角色动画
  3. 探索 物理系统 实现真实的物理效果