使用 AssetBundle 中的模型时的内存泄漏问题和解决方法

[最近更新时间 : 2020/10/21]

在从 AssetBundle 加载和卸载使用裁剪的模型的 Prefab 时,可能会发生内存泄漏,具体取决于 CubismMaskTexture 的处理方式。

在这里,我们将解释原因、未响应的原因以及应对措施。

 

概述

如果您想在 Unity 中处理带有裁剪集的模型,请使用 CubismMaskController。
您在 CubismMaskController.MaskTexture 中设置的蒙版纹理(CubismMaskTexture 的一个实例),如果未设置,将在初始化时在您的应用程序中引用 GlobalMaskTexture。
但是,根据项目的规范,CubismMaskTexture 的实例可能包含在 AssetBundle 中,而不是应用程序端。
在这种情况下,从 AssetBundle 加载和卸载模型可能会导致内存泄漏。

造成内存泄漏的原因是CubismMaskTexture里面的RenderTexture生成了,然后就保留了。
根据 Cubism Mask Texture 的使用方式,有两种对策。

case 1: 如果所有模型都使用一种Cubism蒙版纹理
1-1、删除CubismMaskController检查器.cs的EditorGUILayout.ObjectField
1-2、将CubismMaskController.cs中序列化的_maskTexture改为非序列化进程
1-3、重新创建AssetBundle

case 2: 如果每个模型都有一个 CubismMaskTexture 实例
2-1、在CubismMasktexture.cs中创建删除_renderTexture的方法
2-2、在销毁模型的时机调用2-1中创建的方法
2-3、重新创建AssetBundle

采取上述任一措施都可以解决内存泄漏问题。

 

背景/原因

在 Live2D 模型中制作具有裁剪集的模型的 AssetBundle 后,从那里加载和卸载模型会导致内存泄漏。

原因是每次加载模型时,都会生成一个遮罩的RenderTexture,即使模型被删除,RenderTexture 仍然存在。
在组件上设定的对象是带有对象副本的 AssetBundled,而不是对该对象的引用。
因此,如果您通过 AssetBundle 生成模型,并且 CubismMaskController.MaskTexture 设置为 GlobalMaskTexture,它是 CubismMaskTexture 的一个实例,则会在加载模型的同时生成 GlobalMaskTexture 的副本并创建 RenderTexture。
但是,即使我删除了模型,渲染纹理仍然没有被删除。结果是内存泄漏。

由于以下三个原因,此错误的更正没有反映在 Cubism SDK 中。

  1. 因为根据如何处理RenderTexture for mask,对应方法不同
  2. 专注于结构清晰和简单的Cubism组件变得复杂。
  3. 不使用 AssetBundle 没有问题

 

措施

对策的注意事项

本节介绍了两种措施。

请注意,这两个措施是独立的措施,所以不要在一个项目中同时采取两个措施。

对策因您使用Cubism蒙版纹理的方式而异。您可能只使用一个 CubismMaskTexture,或者您可能为每个模型使用一个 CubismMaskTexture 实例。
在这里,我们将解释两种使用方法中的每一种的对策。

 

Case 1: 使用一个Cubism蒙版纹理显示模型时

如果您正在使用一个 CubismMaskTexture 并显示模型,请采取此措施。

首先,删除 CubismMaskController检查器.cs 中包含的 EditorGUILayout.ObjectField。

 

接下来,将 CubismMaskController.cs 中的序列化 _maskTexture 变更为非序列化进程。

 

现在你有一个对策。
在此之后,重新创建 AssetBundle。

 

case 2: 如果每个模型都有一个 CubismMaskTexture 实例

如果每个模型都有一个 CubismMaskTexture 实例,请执行以下操作。

首先,在 CubismMaskTexture.cs 中创建一个公共方法来销毁 _randerTexture。
下面是一个代码示例。

 

在销毁模型的时候调用上述方法。
因此,您可以删除渲染纹理以及模型。

完成上述措施后,重新创建 AssetBundle。

 

© 2010 - 2022 Live2D Inc.