Wwise 与 Unity Addressable 使用

Unity Addressables 是一个围绕 AssetBundle 构建的系统,用于将游戏素材与玩家内容分开打包。 该系统在 DLC 开发当中特别有用,方便将额外的素材存储到外部服务器上。

注意: 此 Package 为实验包。 作为 Unity Integration 的新增功能,对 Addressables 的支持可能会有变更。

注意: 不支持 Unity 2018。 鉴于在 Unity 2018 中使用外部包比较容易出现问题,我们不保证此数据包能在 2019 之前的 Unity 版本中正常使用。

Addressables 系统特别注意事项


在使用 Addressables 系统时应特别注意以下事项:

  • “使用 Addressables 加载素材”本身属于异步操作:倘若加载的 SoundBank 和发送的 Event 被关联到了同一 Trigger,有可能会出现问题。在需要精确设定 Event 时机的情况下,建议先加载 SoundBank,再触发关联 Event。Init Soundbank 是个特例,其必须在场景中的所有其他 SoundBank 之前加载。若以远程方式更新 Init Soundbank 素材,则在场景启动并加载 SoundBank 时会稍有延迟,因为要先使用 Addressables 从 Web 服务器获取新的 Init Soundbank。

  • 不可在场景中直接引用 Addressables 素材:Addressables 素材必须使用 Addressables 系统在场景中动态加载。场景中直接引用的素材会构建到场景的 AssetBundle 中,而不会通过 Addressables 加载。若将素材直接放在场景中,同时使用 Addressables 打包该素材,则游戏数据中将会有两份不同的素材:场景的 AssetBundle 中一份,Addressables 分组的 AssetBundle 中一份。

已知问题和限制


  • 工程中的所有平台必须共用同一 Generated SoundBanks Path 根目录。

  • 在 Unity 工程中设置 Generated SoundBank Path 不会自动更改 External Source 的输出路径。

  • 暂不支持保存和加载 Decoded SoundBank。

  • 暂不支持 Prepared Event。

  • 暂不支持 External Source。

Wwise Addressable 示例


Wwise Addressables 示例 页面提供有关如何参照代码示例管理 Wwise Addressables 素材的附加信息。

Wwise Addressables 素材详解


Wwise 素材导入程序

在创建后,由 WwiseBankImporter 和 WwiseStreamingAssetImporter 类处理 .bnk 和 .wem 文件。 此脚本会创建包含所述文件二进制数据的素材。随后,我们的自定义素材后处理程序 WwiseBankPostProcess 会将新素材添加到相应平台的 Addressables 分组。 接着,针对每个平台将 Init SoundBank 添加到其各自的 Addressables 分组。之所以分开添加 Init SoundBank,是因为在发布后对工程实施更改(比如添加新的音频总线)时必须予以更新。 通过将 Init SoundBank 打包到各自的 Addressables 素材包,我们可以最大限度地缩短使用托管服务获取新版素材所需的时间。 若想自定义要将素材添加到哪个 Addressables 分组以及将哪些标签应用于素材,请参阅 Wwise Addressables 示例 页面。

SoundBank 和 AddressableSoundBank

素材后处理程序还会为工程中的每个 SoundBank 创建一个 WwiseAddressableSoundBank。 此素材包含用来将平台名称映射到相应 SoundBank 和流播放媒体素材的词典。

  • WwiseAddressableSoundBank 存放在 Generated SoundBanks 文件夹的根目录下。

  • WwiseAddressableSoundBank 类使用 AssetReferenceT 指向 SoundBank 和媒体文件。

  • 在构建工程时,将把 WwiseAddressableSoundBank 的 Current Platfrom Assets 字段设为目标构建平台。

注意: WwiseAddressableSoundBank 中 SoundBank 和流播放媒体的引用为软引用。这些文件将使用 Addressables 加载且必须打包到 Addressables 分组中。

注意: 若意外删除 WwiseAddressableSoundBank,则须删除并重新生成与之关联的 SoundBank,以便另行新建并正确设置引用。

Init Bank Holder

在针对 Init SoundBank 创建 WwiseAddressableSoundBank 时,将向场景中的 “WwiseGlobal” GameObject 添加 InitBankHolder 组件。 此组件只是简单地存储 WwiseAddressableSoundBank 以便 AddressableBankManager 轻松找到它。

Addressable Bank Manager

在使用 Wwise Addressables 时,由 AkAddressableBankManager 负责内存中 SoundBank 的加载和卸载。此类会存储对正在和已经加载的 AddressableSoundBank 的引用,并确保始终最先加载 Init SoundBank。 若在完成加载 SoundBank 前触发了 AkEvent,则此类将存储所触发调用的参数,并在加载 SoundBank 后再次触发相应的 Event。

在加载 SoundBank 时,将通过 Addressables 加载与当前平台对应的 SoundBank 素材。一旦完成加载便会锁定 SoundBank 数据,并使用 AkSoundEngine.LoadBankMemoryCopy() 将内存副本加载到声音引擎中。

在 Editor 中进入游戏模式时,将使用 AssetDatabase 而非 Addressables 来同步加载 SounBank。也就是说,只能在构建好的游戏中测试异步加载。

WwiseBankReference

WwiseBankReference 类用在 Ak.Wwise.Bank 组件的自定义检视器中。 WwiseBankReference 包含对 WwiseAddressableSoundBank 的硬引用。 在通过 AkAssetUtilities.AddressableBankUpdated 委托创建 WwiseAddressableSoundBank Asset 时,会更新此引用。 若在 WwiseAddressableSoundBank 之后创建 WwiseBankReference ,则将在 SoundBanks 文件夹中搜索与 SoundBank 名称匹配的 WwiseAddressableSoundBank 素材。 序列化的 WwiseBankReference 存储在 Assets\Wwise\ScriptableObjects\SoundBank 下。

备注:

游戏对象直接引用的素材会随该游戏对象一并打包。 AkBank 组件包含对 WwiseBankReference 的硬引用,WwiseBankReference 则包含对对应 WwiseAddressableSoundBank 的硬引用。 若将带有 AkBank 组件的游戏对象放在 Addressables 分组中,则将随之一并打包 WwiseBankReference 和 WwiseAddressableSoundBank(无须显式添加到分组中)。

流播放媒体

流播放媒体(.wem 文件)同样由 WwiseBankImporter 脚本处理。 WwiseAddressableSoundBank 包含一系列对 SoundBank 关联平台专用流播放媒体素材的引用。 在加载 SoundBank 时会通过 Addressables 加载媒体素材,并将其复制到 the Application.persistentDataPath 文件夹中。 若文件夹中已存在同名文件,则对两者的哈希值进行比对。若两个文件不同,则使用 AssetBundle 中的文件加以覆盖。

///

Installing the Wwise Unity Addressables Package

通过 Unity Package Manager 和 GitHub 安装 Wwise Addressables Package


Wwise Addressables Package 的官方存储目录为 https://github.com/audiokinetic/WwiseUnityAddressables

  • 打开 Unity Package Manager,单击 + 图标并选择 Add package from git URL...

如需进一步了解如何使用 Git 存储库中托管的数据包,请参阅 Unity 文档

备注:

若显示 No "git" executable was found 错误消息,则须将 git.exe 可执行文件存储目录添加到系统环境,并在必要时重启系统以使更改生效。

备注:

为确保能够正常使用 Wwise Addressables,须同时将 Unity Addressables Package 添加到工程中。该数据包被列为 Wwise Addressables Package 的依赖项,应当会自动安装。

更新 Wwise Unity Addressables Package

在更新到新的 Wwise 版本时,建议先更新 Unity Integration,再更新 Wwise Unity Addressables Package。

在发布 Wwise 小版本或大版本的同时,也会发布对 Wwise Unity Addressables Package 的更新。不过,不一定要那么频繁地进行更新。每项更新都标记有发布和测试时使用的 Wwise 版本。我们的目的是保证新的 Unity Integration 版本和老的 Wwise Unity Addressables Package 版本之间的兼容性(除非需要实施重大更改)。比如,Wwise Unity Integration 2021.1.7 及更高版本跟 21.1.7 标签之前的 Wwise Unity Addressables Package 版本之间是不兼容的。每个 GitHub 标签在存储库的版本页面上都有一个对应的条目,其描述了所作的更改以及版本兼容性。

与 Unity Addressables Package 的兼容性

Wwise Unity Addressables Package 应当与最新的 Unity Addressables Package 版本兼容。而且,跟老的版本应当也兼容。不过,1.16.0 之前的版本并未经过测试。在默认情况下,Wwise Unity Addressables Package 使用针对 Unity Integration 支持的最低 Unity 版本验证的最新版本 Addressables Package。有关支持的 Unity 版本列表,请参阅 版本说明 - Wwise Unity Integration 2022.1.2.8150.2694 章节。

所需执行的附加步骤

若使用 Unity 2018.x,请依次转到 Project Settings > Player > Other Settings,并将 AK_WWISE_ADDRESSABLESUNITY_ADDRESSABLES 添加到 Scripting Define Symbols

警告: 此数据包不受 Unity 2018 官方支持。如使用此版本,相关风险自负。

使用 Wwise Addressables Package 设置并构建脚本


步骤 1:在 Project Settings > Wwise Editor > Generated SoundBanks Path 中,设置所生成 SoundBank 的目标目录。

注意: 为了确保能够正常导入 SoundBank,请务必将此目录设在 Assets 文件夹内。

  • 在本例中,我们将目标目录设为 Assets\WwiseData\Banks

  • 若更改此路径,则将自动修改 Wwise 中的输出目标目录。

  • 在执行此更改后打开 Wwise 设计工具时,将显示对话框并提示重新加载工程。

步骤 2:在 Wwise 设计工具内或使用 Wwise Picker 生成 SoundBank。

  • 这时 .bnk 和 .wem 文件的自定义素材导入程序将创建与所生成 SoundBank 和流播放媒体文件对应的 Unity 素材。

  • AddressableAssetsData 目录下会自动生成元数据文件和平台专用分组。

  • 您可以通过检查 Generated SoundBanks Path 下的文件来确认是否正确导入了素材。

步骤 3:依次单击 Window > Asset Management > Addressables > Groups。这时将打开 Wwise Addressables Groups 窗口。

在默认情况下,会针对每个部署平台创建一个包含平台专用 SoundBank 素材的分组。 另外,还会针对每个部署平台创建仅包含 Init SoundBank 的单独分组。

若检视场景中的 WwiseGlobal 对象,会发现其添加了 Init Bank Holder 组件。

步骤 4:为 Addressables 创建 Wwise Build Script。

  • 建议将其与默认构建脚本一并放在 AddressableAssetsData/DataBuilders 下。

  • 在浏览器中任意位置右键单击,并依次选择 Create > Addressables > Content Builders > Wwise Build Script

  • 这时将创建名为 BuildScriptWwisePacked 的素材。

步骤 5:检查 Addressables 设置。

  • 在默认情况下,其位于 AddressableAssetsData/AddressableAssetSettings

  • 从 Addressables Groups 窗口:Tools > Inspect System Settings

  • 从 Unity Editor:Window > AssetManagement > Addressables> Settings

步骤 6:将 BuildScriptWwisePacked 添加到 Addressables 构建脚本。 在 AddressableAssetSettings 所对应的 Inspector 中,将步骤 4 创建的 BuildScriptWwisePacked 素材添加到 Build and Play Mode 脚本。

构建工程


您可以在 Addressables Groups 窗口中使用 Wwise Build Script 构建 Addressables 素材包。 这样会在 Library\com.unity.Addressables\StreamingAssetsCopy\aa\<Platform Name> 下生成所有通用素材包(如 Default Local Group)及平台专用素材包。

注意: Wwise Build Script 会修改 WwiseData 分组架构的 Include in Build 属性。 若分组名称中带有 WwiseData,则只有该名称同时带有目标构建平台名称才会将其包含其中。 您可以在 BuildScriptWwisePacked.cs 脚本中修改此行为。 若要通过 Include in Build 属性手动控制将哪些分组包含在内,则可直接使用默认构建脚本。

一旦完成 Addressables 素材构建,就可以照常构建工程了。

注意: 在修改工程或向其添加新的 SoundBank 后,须重新构建 Addressables 分组。 此外,在切换平台后也要重新构建 Addressables 分组。

在构建目录下:

  • Addressables 素材包将被复制到 StreamingAssets\aa\

移除 Wwise Addressables Package


在移除此数据包后,需执行一些附加步骤来确保 Wwise Integration 能够正常工作。

  • 从 Unity 素材文件夹中移除包含所生成 SoundBank 的文件夹。

  • 通过 Unity Package Manager 卸载数据包,或删除 <UnityProject>\Packages\manifest.json 文件中的对应行。

  • 在 Wwise Project Settings 中,将 SoundBank Paths 设为 Assets 之外的路径。

  • 重新生成 SoundBank。

  • 若仍使用 Unity Addressables Package,请务必清理 Addressables 分组。

备注:

若使用 Unity 2018,请依次转到 Project Settings > Player > Other Settings,并从 Scripting Define Symbols 中移除 AK_WWISE_ADDRESSABLESUNITY_ADDRESSABLES

DLC 打包基础教程

在本例中,我们将展示如何将某些素材(如新的物品或角色)分开存放到使用 Addressables 打包的对应 DLC 素材包中。

安装 Addressables Demo Scene


若尚未在工程中设置 Wwise Unity Addressables Package,请参照 Installing the Wwise Unity Addressables Package 页面所述进行设置。

本教程中所用 Addressables Demo Scene 的官方存储目录为 https://github.com/audiokinetic/WwiseUnityAddressablesDemoScene。 该 Demo Scene 会用到 Unity Demo Game 中的素材,因此必须先通过 Audiokinetic Launcher 予以安装。

步骤:

  • 通过 Audiokinetic Launcher 安装最新 Unity Demo Game(版本不低于 2021.1.0)。

  • 将 Wwise Unity Addressables Demo Scene 克隆到所用电脑上。

  • 在 Unity 中打开 Demo Game。

  • 最后,使用 Package Manager 中的 Add package from disk 选项添加 Wwise Unity Addressables Demo Scene 数据包。

备注:

此数据包无法通过 Add package from git URL 来添加,因为这样安装的话会无法打开数据包中包含的场景。

快速入门


我们专门为此教程在 Wwise 工程中创建了两个音效、两个 Event 和一个 SoundBank。

我们使用 AkBankAkEvent 组件创建了两个 GameObject Prefab:DlcAssetHighImpact 和 DlcAssetLowImpact。 这两个 Prefab 会加载 “DLC” SoundBank,并在实例化时播放对应的音效。

除此之外,我们还创建了两个场景:AddressablesDemoScene 和 AddressablesSubScene。 AddressablesDemoScene 是个简单的 Unity 场景,里面包含了一些互动按钮,方便测试 Addressables 素材的加载和卸载。 AddressablesSubScene 则是个仅包含 “DlcAssetLowImpact” Prefab 的场景。我们可使用其来对“通过 Addressables 加载包含 Wwise 对象的场景”进行测试。

备注:

AddressablesDemoScene 还包含一个有关如何借助 Wwise Addressables Package 使用本地化语音并更改语言的示例。

所有这些素材以及下节所述脚本均存放在 WwiseUnityAddressablesDemoScene 数据包中。

您可以通过在对应 Inspector 中启用 Addressable 复选框来将以下三项标记为 Addressables 素材:

  • AddressablesSubScene.unity

  • Prefabs/DlcAssetHighImpact.prefab

  • Prefabs/DlcAssetLowImpact.prefab

注意: 若从工程中移除 Unity Addressables Package,则将从所有素材移除 Addressable 字段。在重新安装该数据包时,并不会保留该复选框的状态。

Addressables Groups 窗口内,可看到 Default Local Group 中默认替换了这些 Addressables 素材。

如需创建新的分组,可右键单击 Addressables Groups 窗口并选择 Create New Group,或从菜单中依次选择 Create > Group > Packed Assets。 为 DLC 素材创建两个新的分组:

  • DLC_Assets – 用于 Prefab 和子场景。

  • DLC_WwiseData_Windows – 用于平台专用 Soundbank 素材。

备注:

在本例中,我们只为 Windows 平台创建了一个附加 SoundBank 分组。不过,一般来说每个所要部署到的平台都要创建一个。

  • 将 DlcAssetHighImpact、DlcAssetLowImpact 和 AddressablesSubScene 从 Default Local Group 移到 DLC_Assets 分组。

  • 将平台专用 “DLC” SoundBank 素材从 WwiseData_Windows 移到 DLC_WwiseData_Windows 分组。

备注:

我们确保了会在平台专用分组名称中包含字符串 WwiseData 和平台名称 Windows,以便在构建 Addressables 时由 BuildWwiseData 脚本正确地进行处理。

在 Addressables Groups 窗口中,将 Play Mode Script 设为 Use Existing Build,并通过 Wwise Build Script 构建新的 Addressables 数据包(如 构建工程 章节所述)。

现在,打开 AddressablesDemoScene。

通过 Addressables 加载素材


在此场景中,有两个按钮:

  • 左侧按钮用于通过 Addressables 加载 “DlcAssetHighImpact” Prefab 并将其实例化。

  • 右侧按钮用于加载 AddressableSubScene 并将其实例化。

  • 此场景包含 DlcAssetLowImpact 素材。

若检视 “Loading DLC Assets Demo” GameObject,会看到我们创建了一个 AssetLoader 对象,并且其包含 AddressablePrefabLoader 组件。


using UnityEngine;

using UnityEngine.AddressableAssets;

using UnityEngine.ResourceManagement.AsyncOperations;
 

public class AddressablePrefabLoader : MonoBehaviour
{
    public AssetReference reference;
 
    public void Load()
    {
        Addressables.LoadAssetAsync<GameObject>(reference).Completed += asyncOp =>
        {
            if (asyncOp.Status == AsyncOperationStatus.Succeeded)
            {
                Instantiate(asyncOp.Result,this.transform);
            }
        };
    }
}

此组件包含 AssetReference。我们已在对应 Inspector 中将其设为 “DlcAssetHighImpact” Prefab。

在运行游戏并按下左侧按钮时,将调用 AddressablePrefabLoader 上的设定 Load 方式:从 DLC_Assets 加载,并将 “DlcAssetHighImpact” Prefab 实例化。 一旦实例化,AkBank 组件便会从 DLC_WwiseData_Windows 素材包加载 SoundBank。

通过 Addressables 加载场景


若检视 “Loading DLC Scene Demo” GameObject,会看到我们创建了一个 SceneLoader 对象,并且其包含 AddressableSceneLoader 组件。


using UnityEngine;
 

using UnityEngine.AddressableAssets;

using UnityEngine.ResourceManagement.AsyncOperations;

using UnityEngine.ResourceManagement.ResourceProviders;

using UnityEngine.SceneManagement;
 

public class AddressableSceneLoader : MonoBehaviour
{
 
    public AssetReference scene;
    private AsyncOperationHandle<SceneInstance> sceneHandle;
 
    public void Awake()
    {
        DontDestroyOnLoad(gameObject);
    }
 
    public void LoadScene()
    {
        if (!sceneHandle.IsValid() )
        {
            scene.LoadSceneAsync( LoadSceneMode.Additive).Completed += SceneLoadComplete;
        }
        else

        {
            UnloadScene();
        }
    }
 
    public void UnloadScene()
    {
        Addressables.UnloadSceneAsync(sceneHandle).Completed += op =>
        {
            if (op.Status == AsyncOperationStatus.Succeeded)
            {
                Debug.Log("Successfully unloaded scene");
            }
        };
    }
 
    private void SceneLoadComplete(AsyncOperationHandle<SceneInstance> obj)
    {
        sceneHandle = obj;
        if (obj.Status == AsyncOperationStatus.Succeeded)
        {
            Debug.Log(obj.Result.Scene.name + " successfully loaded");
        }
    }
}

此组件使用 AssetReference 保存对 AddressablesSubScene 的引用。 在第一次按下按钮时,会调用 LoadSceneMethod,进而采用 LoadSceneAsync 方式加载场景,并将其添加到当前场景中。 在第二次按下按钮时,将卸载场景。

AddressablesSubScene 仅包含 “DlcAssetLowImpact” Prefab,其在实例化时会加载 “DLC” Soundbank 并播放对应的 Event。

更改语言


在此场景中的第三个示例中,可在 English 和 French 之间切换语言,并播放本地化声音样本。 此示例使用 AkWwiseSetLocalization 脚本。在按下绿色或蓝色按钮时,会调用 AkAddressableBankManager.SetLanguageAndReloadLocalizedBanks 函数,并将语言更改为 English 或 French。

此函数执行以下操作:

  • 卸载所有本地化 SoundBank

  • 卸载 Init SoundBank

  • 使用 AkSoundEngine.SetCurrentLanguage 设置语言

  • 重新加载 Init SoundBank

  • 重新加载本地化 SoundBank


using UnityEngine;
 

public class AkWwiseSetLocalization : MonoBehaviour
{
    public string LanguageString;
 
    public void SetLanguage()
    {
        Debug.Log($"Setting language to {LanguageString}");
        AK.Wwise.Unity.WwiseAddressables.AkAddressableBankManager.Instance.SetLanguageAndReloadLocalizedBanks(LanguageString);
    }
}

接下来便可构建 AddressablesDemoScene 并测试按钮,以此确保构建好的游戏能够正常加载这些素材。

设置 Addressables Hosting


下面我们来配置 Unity 以使用内置托管服务处理 Addressables DLC 素材。这样无需重新构建玩家内容便可对“通过 Addressables 更新素材”进行测试。

首先,构建 AddressablesDemoScene,并确保其能够正常工作。 在构建窗口中,须通过 Add open scenes 按钮添加 AddressablesDemoScene,并选择将其作为所要构建的场景。

接着,我们来配置 Addressables Hosting(可从 Tools 菜单访问)。

下面来创建 Local Hosting 服务,并选中 Enable 复选框以启用该服务。

通过菜单打开 Addressables Profiles 窗口 (Profile > Manage Profiles),并新建一个名为 Editor Hosted 的配置文件。

然后,将 Path 分别设为:

  • LocalBuildPath:HostedData/[BuildTarget]

  • LocalLoadPath:http://[PrivateIpAddress]:[HostingServicePort]

  • RemoteBuildPath:HostedData/[BuildTarget]

  • RemoteLoadPath:http://[PrivateIpAddress]:[HostingServicePort]

然后,通过右键单击 Editor Hosted 并选择 Set Active 来激活此配置文件。

备注:

有关如何使用 Addressables 托管服务的详细信息,请参阅官方文档

检视 DLC_WwiseData_Windows 分组素材,并确保已更新其 Build Path 和 Load Path。

打开 Addressable Asset Settings,并启用 Build Remote Catalog 。分别将 Build Path 和 Load Path 设为 LocalBuildPath 和 LocalLoadPath。

使用 Wwise Build Script 重新构建 Addressables 素材。注意要在 <Unity Project Path>\HostedData 下创建新的 Addressables 素材包。

接下来重新构建 AddressablesDemoScene 以测试是否能够正常处理素材。

打开 Addressables Hosting 窗口,来在运行游戏时查看传入请求。在第一次按下按钮时,窗口底部的事件日志中应会显示请求。

更新 Addressables 素材

下面我们来使用 Addressables 更新 DlcAssetHighImpact 音效。

首先,在 Wwise 中调节 imp_axe_stone_high 声音样本的 Pitch 值来使变化更加明显。然后,重新生成 SoundBank。

然后,在 Addressables Groups 窗口中依次选择 Build >Update a previous build。在打开的选择窗口中,在 AddressableAssetsData/Windows 下选择 addressables_content_state.bin 文件。

最后,再次运行构建好的游戏(无需重新构建)。在打开时,应会在 Addressables Hosting 窗口中看到目录更新请求。

这时按下左侧按钮,应会听到按照新 Pitch 值播放的音效。

有关 Addressables 目录和预定开发周期的详细信息,请参阅官方文档

备注:

此教程中提供的脚本仅可满足对“通过 Addressables 加载素材”进行测试的最低要求。 在自己的工程中加载素材时,最好选用更为稳妥的解决方案。 如需查看更多进阶示例,请转至 Unity Addressables Sample 存储库。

/

Wwise Addressables 示例

Wwise Addressable Asset Metadata Preserver


在使用 Wwise Addressables 素材时,要想确保更新 WwiseAddressableBank 素材,最简单的方法是删除生成的 SoundBanks 文件夹并重新生成 SoundBank。在删除 Addressables 素材时,会清除 Addressables 分组的内容。在重新导入时,其父组和标签将会丢失。Wwise Unity Addressables Package 中包含的这个示例脚本提供相应功能来保留 Addressables 素材元数据(如父组和标签)。

工作原理

我们添加了一项可选设置可供启用来帮助恢复丢失的分组和标签。该设置可在 Unity 工程设置的 Wwise Addressables 下找到。在启用后,可指定元数据的目标目录。此目录应设在 Unity 工程的 Assets 文件夹内。

WwiseAssetMetadataPreserver 脚本会在 Assets/Wwise/Addressables 下添加一个菜单触发器,以便保存工程中所有 Wwise Addressables 素材的元数据。在触发时,会针对每个 Wwise Addressables 素材创建 AddressableMetadata 素材,并将父组和标签的名称序列化。脚本还会通过 WwiseBankPostProcess.GetAssetMetadataDelegate 函数对自身进行注册。此委托允许外部代码在通过 WwiseBankPostProcess 自定义导入器导入时填入用于设置素材字段的元数据结构。该导入器会在添加到 Unity 工程时导入 .bnk 和 .wem 文件。

借助这两种机制,可在执行清理前将素材元数据序列化,并在生成 Soundbank 后重新导入时重新应用于素材。

备注:

此脚本只是为了展示如何做到这一点。您可以根据自身制作要求来编写元数据填入代码。

示例代码

#if AK_WWISE_ADDRESSABLES && UNITY_ADDRESSABLES
 

using UnityEditor.AddressableAssets;

using UnityEditor.AddressableAssets.Settings;

using System.Collections.Generic;

using UnityEditor;

using UnityEngine;

using System.IO;
 

namespace AK.Wwise.Unity.WwiseAddressables
{
    /* 

       此类提供相应功能来保留并恢复 Wwise Addressables 素材分组和标签元数据。
       在删除素材时,此信息会丢失。要想修复损坏的 WwiseAddressableSounbanks,最简单的方法是清除 Wwise Addressables 素材文件夹。
       此类只是为了展示如何实现这一功能,并不是一个完善的解决方案。
     */
    [InitializeOnLoad]
    class WwiseAddressableAssetMetadataPreserver
    {
        static WwiseAddressableAssetMetadataPreserver()
        {
            if (AkAddressablesEditorSettings.Instance.UseSampleMetadataPreserver)
            {
                BindMetadataDelegate();
            }
        }
        
        //在 WwiseBankPostProcess AssetPostProcessor 上设置 GetAssetMetadataDelegate(处理 .bnk 和 .wem 文件的导入)

        public static void BindMetadataDelegate()
        {
            WwiseBankPostProcess.GetAssetMetadataDelegate += GetMetadata;
        }
 
        //取消设置委托(在禁用功能时)

        public static void UnbindMetaDataDelegate()
        {
            WwiseBankPostProcess.GetAssetMetadataDelegate -= GetMetadata;
        }
 
        为每个 Wwise Addressables 素材创建 AddressableMetadata 素材来追踪分组和标签。
        //按照与 Wwise 素材匹配的层级结构来在对应文件夹下创建元数据素材

        //文件夹层级结构和素材名称用于在导入时与素材进行匹配

        [UnityEditor.MenuItem("Assets/Wwise/Addressables/Serialize addressable asset metadata")]
        public static void PreserveAllWwiseAssetMetadata()
        {
            AddressableAssetSettings addressableSettings = AddressableAssetSettingsDefaultObject.Settings;
            foreach (AddressableAssetGroup group in addressableSettings.groups)
            {
                foreach (AddressableAssetEntry assetEntry in group.entries)
                {
                    if (assetEntry.MainAsset)
                    {
                        if (assetEntry.MainAsset.GetType().IsSubclassOf(typeof(WwiseAsset)))
                        {
                            CreateMetadataAsset(assetEntry.AssetPath, assetEntry.labels, group.name);
                        }
                    }
                }
            }
        }
 
        [UnityEditor.MenuItem("Assets/Wwise/Addressables/Preserve addressable asset metadata", true)]
        public static bool ValidatePreserveAllWwiseAssetMetadata()
        {
            return AkAddressablesEditorSettings.Instance.UseSampleMetadataPreserver;
        }
 
        //创建必要的子文件夹和元数据素材

        public static void CreateMetadataAsset(string assetPath, HashSet<string> assetLabels, string groupName)
        {
            string soundbankPath = assetPath.Replace(AkAssetUtilities.GetSoundbanksPath(), "");
            var splitBankPath = soundbankPath.Split('/');
            AddressableMetadata metaDataAsset = ScriptableObject.CreateInstance<AddressableMetadata>();
            metaDataAsset.labels = new List<string>(assetLabels);
            metaDataAsset.groupName = groupName;
 
            var rootPath = AkAddressablesEditorSettings.Instance.MetadataPath;
 
            if (!Directory.Exists(Path.Combine(Application.dataPath, rootPath)))
            {
                UnityEditor.AssetDatabase.CreateFolder("Assets", rootPath);
            }
 
            for (int i = 1; i < splitBankPath.Length - 1; i++)
            {
                if (!Directory.Exists(Path.Combine(Application.dataPath, Path.Combine(rootPath, splitBankPath[i]))))
                {
                    AssetDatabase.CreateFolder(Path.Combine("Assets", rootPath), splitBankPath[i]);
                }
                rootPath = Path.Combine(rootPath, splitBankPath[i]);
            }
 
            string assetMetadataPath = Path.Combine("Assets", rootPath, Path.GetFileNameWithoutExtension(assetPath) + ".asset");
            AddressableMetadata oldAsset = AssetDatabase.LoadAssetAtPath<AddressableMetadata>(assetMetadataPath);
            if (oldAsset)
            {
                if (!metaDataAsset.IsDifferent(oldAsset))
                {
                    return;
                }
            }
 
            UnityEditor.AssetDatabase.CreateAsset(metaDataAsset, assetMetadataPath);
        }
 
        我们可以根据平台和语言来确定元数据素材的存放位置。
        public static AddressableMetadata FindMetadataAsset(string assetName, string platformName, string languageName)
        {
            string MetadataAssetPath;
            if (languageName !="SFX")
            {
                MetadataAssetPath = Path.Combine("Assets", AkAddressablesEditorSettings.Instance.MetadataPath, platformName, languageName, Path.GetFileNameWithoutExtension(assetName) + ".asset");
            }
            else

            {
                MetadataAssetPath = Path.Combine("Assets", AkAddressablesEditorSettings.Instance.MetadataPath, platformName, Path.GetFileNameWithoutExtension(assetName) + ".asset");
            }
            return AssetDatabase.LoadAssetAtPath<AddressableMetadata>(MetadataAssetPath);
        }
 
        //在导入 .bnk 和 .wem 文件时调用。将尝试查找并加载工程中存在的元数据对象。

        public static bool GetMetadata(string assetName, string platformName, string languageName, ref AddressableMetadata metaData )
        {
            AddressableMetadata asset = FindMetadataAsset(assetName, platformName, languageName);
            if ( asset )
            {
                metaData = asset;
                return true;
            }
            return false;
        }
    }
}
 
#endif

///

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值