音频 Audio
核心思路:引用格式决定路由(clip: / wwise:),门面 Audio.Play 统一播放,切换后端业务零改动。
命名空间 HYC.Framework.Audio。
一句接入
using HYC.Framework.Audio;
// 直接给引用
Audio.Play("clip:Audio/Sfx/Click");
// 从配置表字段播(AudioEvent 字段生成的是 string + [AudioField])
Audio.Play(cfg.BgmRef, AudioChannelId.Music); // 指定分组(BGM)
// 停止 / 暂停 / 音量
Audio.StopAll();
Audio.SetChannelVolume(AudioChannelId.Music, 0.8f);
Audio.SetMuted(true);
引用格式(clip: / wwise:)
配置表 / 代码里一个音频引用就是带前缀的字符串:
| 前缀 | 含义 | 示例 |
|---|---|---|
clip: | Addressables 地址,走框架默认后端 | clip:Audio/Sfx/Click |
wwise: | Wwise 事件名,走 Wwise 后端 | wwise:Play_UI_Click |
| 无前缀 | 按 clip: 处理 | Audio/Sfx/Click |
配置表字段(AudioEvent)
在配置模板里把字段类型选成 AudioEvent,生成器会产出一个 string 属性并自动挂 [AudioField]:
// 生成产物(节选)
[AudioField]
public string BgmRef; // 数据编辑器据此绘制下拉框,列出音频总览里的条目
数据编辑器里该字段是单行下拉(帧级精确,无第二行回退),选中条目即写入 clip:... / wwise:... 字符串。
音频总览(登记 + 导出)
总览资产路径约定:Assets/HYC/Audio/AudioCatalog.asset(首次打开窗口自动创建)。
- 打开
HYC Framework / Audio / Audio Manager(菜单 priority 60)。 - 在窗口里登记条目(地址 / 事件名 + 显示名 + 分组)。配置表下拉框读的就是它。
- 导出 Blob:
HYC Framework / Audio / Export Catalog Blob(priority 61)→ 产出StreamingAssets/AudioBlob/AudioCatalog.blob。
Audio.Play 会直接用字符串里的值),只是不走「总览规范化 + 分组」逻辑。忘了登记不会完全没声音,但建议都登记以便统一分组与批量预检。运行期播放 API
| 方法 | 作用 |
|---|---|
Audio.Play(ref) | 默认分组(Sfx)播放;引用已登记时以总览分组为准 |
Play(ref, volume, loop, channel) | 显式指定分组(仅当引用未登记时生效) |
PlayIn(ref, channel, volume, loop) | 强制指定分组,忽略总览登记的分组 |
Stop(handle) / StopChannel(id) / StopAll() | 停实例 / 停整组 / 停全部 |
Pause(handle, paused) | 暂停 / 恢复 |
SetChannelVolume(id, v) / SetVolume(id, v) | 设分组音量(后端未初始化也不丢) |
SetMuted(bool) | 全局静音(分组设定保留,取消后恢复) |
AudioHandle 是只读 struct(AudioHandle.Invalid 表示失败),用它后续 Stop / SetVolume / Pause。
音量分组(配置驱动)
分组集合存于 FrameworkSettings.audioGroups(HYC Settings → Audio/Groups 增删改名),每个分组有稳定 int id:
Master = id 0固定为全局总音量(作用于所有组,不可删)。- 默认 5 组:
Music(1)/Sfx(2)/Voice(3)/Ui(4)(id 不变,可改名)。 - 运行时
Audio.SetVolume(AudioChannelId.Music, 0.8f);实际增益 =Master × 组音量。
后端切换(Wwise)
// 切到 Wwise(需工程装了 Wwise 且定义宏 HYC_WWISE)
Audio.SetBackend(AudioBackend.Wwise);
// 切回默认
Audio.SetBackend(AudioBackend.Default);
切换会先停播再释放旧后端;失败保持原后端不变。业务代码与配置表零改动——前缀决定路由,与当前后端无关。没装 Wwise(缺宏)也能切到 Wwise 选项卡(返回桩实例,方法明确报错而非静默失败)。
跨端与加载
总览 Blob 走 StreamingAssets/AudioBlob/AudioCatalog.blob,与 Loc / BT 完全同构;WebGL / Android 必须经 StreamingAssets.PreloadAsync()(框架在 FrameworkBootstrap.InitializeAsync 内收口,游戏层不写平台分支)。播放本身不需要预载总览:门面拿到引用字符串会直接播;总览仅在「引用已登记 → 规范化地址 + 分组」以及「窗口 / 批量预检」时才读。
迁移说明
- 旧版「写死枚举的音量分组」已改为配置驱动(
AudioChannelId现在是包int的 readonly struct,保留隐式 int 转换兼容旧数据)。 AudioEvent是ConfigFieldType的新增枚举值(生成 string +[AudioField]);旧字符串字段不会自动变成音频下拉,需在模板里改字段类型。