运行时资源替换(Runtime Asset Swapping)
对于大多数动态资源替换用例,我们建议使用数据绑定。数据绑定只更改绑定的属性,因此图形的不同部分可以使用不同的图像或字体。
本页面说明如何使用 CustomAssetLoaderCallback 在 Rive 文件中以文件级别替换字体、图片或音频资源。
当你希望替换资源在整个文件中出现原始资源的所有位置都被使用时,这种方法很有用。例如,如果你需要全局替换一种字体,以便所有使用该字体的文本自动更新,你可以在一个地方完成,而无需为每个实例配置单独的属性绑定。
设置资源加载
要在运行时替换资源,请在加载 Rive 文件时提供一个回调:
File.Load(Asset asset, CustomAssetLoaderCallback customAssetLoaderCallback);
File.Load(TextAsset asset, CustomAssetLoaderCallback customAssetLoaderCallback);
File.Load(byte[] riveFileByteContents, CustomAssetLoaderCallback customAssetLoaderCallback);
当运行时需要加载资源时,将调用你的回调。如果你已处理资源加载,回调应返回 true;如果让运行时使用默认加载行为处理,则返回 false。
以下示例展示了如何在运行时替换字体:
private FontOutOfBandAsset m_fontOobAsset;
private File m_file;
FontEmbeddedAssetReference fontEmbeddedAssetReference;
private bool OobAssetLoaderDelegate(EmbeddedAssetReference assetReference)
{
// 保留对 fontEmbeddedAssetReference 的引用,以便稍后再次更新字体
fontEmbeddedAssetReference = assetReference as FontEmbeddedAssetReference;
if (fontEmbeddedAssetReference != null)
{
fontEmbeddedAssetReference.SetFont(m_fontOobAsset);
return true;
}
return false;
}
private void Start()
{
m_fontOobAsset.Load();
m_file = Rive.File.Load(asset, OobAssetLoaderDelegate);
// 你可以在这里再次调用 fontEmbeddedAssetReference.SetFont() 来更改字体
}
private void OnDestroy()
{
m_fontOobAsset.Unload();
m_file.Dispose();
}
带回退的重载
Rive.File.Load() 的一个重载包含 fallbackToAssignedAssets 参数。
如果设置为 true,并且你的自定义加载器没有处理某个资源,运行时将查找分配给你的 Rive 资源在 Unity 检查器中的引用,并在存在时自动加载它们。当你只想替换某些资源而依赖默认引用处理其余资源时,这很方便。
var file = File.Load(myRiveAsset, MyCustomAssetLoader, fallbackToAssignedAssets: true);
资源类型
你可以在运行时替换以下类型的资源:
FontOutOfBandAsset:用于字体文件ImageOutOfBandAsset:用于图片文件AudioOutOfBandAsset:用于音频文件
资源引用类型
在回调中处理资源时,你需要在设置资源之前检查 EmbeddedAssetReference 的类型。每种资源类型都有自己的引用类,具有特定的 setter 方法:
private bool AssetLoaderDelegate(EmbeddedAssetReference assetReference)
{
// 处理字体资源
if (assetReference is FontEmbeddedAssetReference fontReference)
{
fontReference.SetFont(myFontAsset);
return true;
}
// 处理图片资源
if (assetReference is ImageEmbeddedAssetReference imageReference)
{
imageReference.SetImage(myImageAsset);
return true;
}
// 处理音频资源
if (assetReference is AudioEmbeddedAssetReference audioReference)
{
audioReference.SetAudio(myAudioAsset);
return true;
}
return false;
}
内存管理
使用运行时资源替换时,我们建议遵循以下最佳实践:
-
在回调中使用带外资源之前,始终对其调用
Load()。 -
正确释放资源:
- 当资源不再需要时,对其调用
Unload()。 - 当你完成 Rive 文件时,对其调用
Dispose()。
- 当资源不再需要时,对其调用
动态创建带外资源
如果你的资源在构建时不在 Unity 项目中(例如,如果你从 CDN 加载图片),你可以使用 OutOfBandAsset.Create<T>() 方法在运行时创建带外资源。这里的 bytes 参数应该是资源的原始文件数据。
这适用于字体、图片和音频,只要你使用适当的类型(FontOutOfBandAsset、ImageOutOfBandAsset 或 AudioOutOfBandAsset)。
byte[] imageBytes = /* 从 CDN 或其他地方获取 */;
var myImageAsset = OutOfBandAsset.Create<ImageOutOfBandAsset>(imageBytes);
示例
有关 Unity 中运行时资源替换的演示,请参阅 Rive Unity Examples 仓库中的 Image Swapping 场景。