|
1.起因
项目组最近升级了Unity引擎,从基于2018.3.6f1修改的自编版本升级到2018.4.11f1官方版本。在升级后,很多美术同学找到我反应说他们在使用资源的Inspector面板时非常卡,严重影响他们的制作效率。
初步观察了下卡顿现象,发现只要Inspector面板中显示的Preview窗口,卡顿就出现了。先让美术同学把Preview窗口关掉,然后开始想办法定位问题。
2.问题定位
通过Deep Profiler Editor,发现了卡顿的元凶:AssetBundleNameGUI类在OnGUI时会调用GetAllAssetBundleNames。由于项目中AssetBundleName量级比较大,所以卡顿明显。
3.修改方案
查看Unity开源出来的C#代码 ( https://github.com/Unity-Technologies/UnityCsReference),可以观察到Inspector相关代码的调用顺序:
(1)每个Inpspector窗口对应的是InspectorWindow类,该类中有一个私有成员m_AssetBundleNameGUI。
(2)在Inpspector的OnGUI函数中,如果显示Preview并且资源存在AssetBunldeName。会调用m_AssetBundleNameGUI的OnAssetBundleNameGUI。
(3)在OnAssetBundleNameGUI函数中,如果m_ShowAssetBundleNameTextField字段为false,会调用AssetBundlePopup,从而调用AssetDatabase.GetAllAssetBundleVariants
在不改引擎的情况下,要如何避免调用GetAllAssetBundleVariants呢?
目前我只想到用反射的方式:获取Editor中所有Inspector,将他们的m_AssetBundleNameGUI中的m_ShowAssetBundleNameTextField,强制改为true。具体代码如下:
// 初始化
{
Assembly assembly = Assembly.GetAssembly(typeof(Editor));
Type InspectorWindow = assembly.GetType("UnityEditor.InspectorWindow");
Type AssetBundleNameGUI = assembly.GetType("UnityEditor.AssetBundleNameGUI");
m_AllInspectors = InspectorWindow.GetField("m_AllInspectors", BindingFlags.Static | BindingFlags.NonPublic);
m_AssetBundleNameGUI = InspectorWindow.GetField("m_AssetBundleNameGUI", BindingFlags.Instance | BindingFlags.NonPublic);
m_ShowAssetBundleNameTextField = AssetBundleNameGUI.GetField("m_ShowAssetBundleNameTextField", BindingFlags.Instance | BindingFlags.NonPublic);
}
// 每帧调用
{
object value = m_AllInspectors.GetValue(null);
var enumerator = ((IEnumerable)value).GetEnumerator();
while (enumerator.MoveNext())
{
var ins = enumerator.Current;
object abname = m_AssetBundleNameGUI/span><span class="p">.GetValue(ins);
m_ShowAssetBundleNameTextField.SetValue(abname, true);
}
}
这样的修改并不是很完美,比较取巧。但暂时解决了美术同学制作时的卡顿问题。 大家如果有更好的方案,欢迎指导。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|