U
章 04世界与游戏循环7 课 — 点击打开
05 / 07 · 10 分钟
世界与游戏循环

声音与氛围

到目前为止的项目

Assets/

Scenes/

Arena.unity

Terrain

Scripts/

PropScatter.csGameAudioSettings.csFootstepPlayer.cs

Prefabs/

Knight prefab

Animations/

AC_Knight

Audio/

MainMixer

你已经有的这一课新增

除了你在 tab 01 里加的音乐和按键音,你做到现在的所有东西都是静音的。Knight 走路没有脚步声,放技能没有声音,森林里也没有风声。

随便挑一个游戏把声音关掉,它立刻就显得很廉价。氛围感有一半来自声音,而新手往往把这一整半完全跳过。

动态图解

三个层级、一个 mixer,凡是世界里占一个位置的音都用 3D 衰减。

三个音频层

  • Music —— 一条循环音轨,2D,音量不随距离变化。Spatial Blend 设为 0。

  • Ambience —— 风声、鸟叫、河流。铺满全局的底用 2D,某处具体的瀑布用 3D。

  • SFX —— 脚步声、打击、放技能。一律 3D,一律很短,一律做成池复用。

导入设置决定你的内存预算

  1. 1

    音乐和很长的环境音 → Load Type = Streaming,Compression = Vorbis,Quality 60–70%。

  2. 2

    短 SFX → Load Type = Decompress On Load,Compression = PCM 或 ADPCM。它们必须一调用就立刻出声。

  3. 3

    凡是场景第一秒用不到的,都把 Preload Audio Data 的勾去掉。

  4. 4

    所有 3D 声音都勾上 Force To Mono —— 反正 Unity 要自己算方位,立体声没意义,而且体积能省一半。

Audio Mixer —— 每个层一根音量滑块

  1. 1

    Window▸Audio▸Audio Mixer → 新建一个名为 MainMixer 的 mixer。

  2. 2

    在 Master 下面加三个 group:Music、Ambience、SFX。

  3. 3

    右键每个 group 的 Volume → Expose to script,再把参数名改成 MusicVol、AmbienceVol、SfxVol。

  4. 4

    把每个 AudioSource 的 Output 指到对应的 group。这样一根滑块就能控制一整类声音。

GameAudioSettings.cs — the settings menu talks to the mixer
using UnityEngine;
using UnityEngine.Audio;

public class GameAudioSettings : MonoBehaviour
{
    [SerializeField] private AudioMixer mixer;

    /// slider gives 0..1, the mixer wants decibels
    public void SetMusic(float value01)    => SetVolume("MusicVol", value01);
    public void SetAmbience(float value01) => SetVolume("AmbienceVol", value01);
    public void SetSfx(float value01)      => SetVolume("SfxVol", value01);

    void SetVolume(string param, float value01)
    {
        // -80 dB is silence. Log10 makes the slider feel linear to the ear.
        float db = value01 <= 0.0001f ? -80f : Mathf.Log10(value01) * 20f;
        mixer.SetFloat(param, db);
        PlayerPrefs.SetFloat(param, value01);
    }

    void Start()
    {
        SetMusic(PlayerPrefs.GetFloat("MusicVol", 0.6f));
        SetAmbience(PlayerPrefs.GetFloat("AmbienceVol", 0.8f));
        SetSfx(PlayerPrefs.GetFloat("SfxVol", 1f));
    }
}

听起来真的像 3D 的声音

  • Spatial Blend = 1 把音源变成完全的 3D;为 0 时站在哪儿听着都一样响。

  • Volume Rolloff 用 Linear 比 Logarithmic 好调,小关卡尤其如此。

  • Min Distance 是还能保持满音量的半径,Max Distance 是完全听不到的距离。常用值:2 m 和 20 m。

  • 场景里必须恰好只有一个 AudioListener,而且它应该挂在相机上。

听起来不像机关枪的脚步声

FootstepPlayer.cs — on the Knight, driven by Animation Events on AC_Knight
using UnityEngine;

public class FootstepPlayer : MonoBehaviour
{
    [SerializeField] private AudioSource source;
    [SerializeField] private AudioClip[] clips;          // 4–6 variations

    private int last = -1;

    /// called from an Animation Event on the walk / run clips
    public void Step()
    {
        if (clips.Length == 0) return;

        // never play the same clip twice in a row
        int i = Random.Range(0, clips.Length);
        if (clips.Length > 1 && i == last) i = (i + 1) % clips.Length;
        last = i;

        source.pitch = Random.Range(0.92f, 1.08f);      // tiny pitch jitter
        source.PlayOneShot(clips[i], Random.Range(0.8f, 1f));
    }
}
  • 四个采样再加随机音高,就是“一个游戏”和“一个半成品”之间的差别。这只花十分钟。

  • PlayOneShot 能让声音叠着放;source.Play() 会把上一个直接掐断。

  • 用 Animation Event 才能把脚步声正好落在脚落地那一帧 —— 拿计时器去触发永远对不上。

去哪里找音效

  • freesound.org —— 量大、免费,但每个文件都要看它的许可证(CC0 最保险)。

  • Unity Asset Store 里有免费的音效包;按价格 0 过滤就行。

  • 用手机自己录也行。碎石路上的脚步声、门、键盘 —— 效果比你想的好得多。

  • 绝对不要把从 YouTube 上找来的音乐发出去。在应用商店吃版权投诉,整个应用都会被下架。