Hi. Unity 2019.3b includes some improvement for iterating editor works, like domain reload related features.
But I found that this simple bug (or by bad design) is not fixed even it significantly impact to editor iteration time. (In my project, it added 3~5sec to every single click of object. Scene-editing is almost impossible!)
Surprisingly, it is reported at 2018.3b! and it seems that Unity completely forgotten this issue so I bumped this to the forum.
I have this somewhat annoying workaround in our MaterialEditor for some time now which simply caches the custom editor string → type. Would be a very easy fix by Unity.
public override void OnEnable()
{
if (!target)
return;
var shaderProperty = serializedObject.FindProperty("m_Shader");
var shader = shaderProperty.objectReferenceValue as Shader;
// prevent unity from creating custom shader gui as it's very slow
shaderProperty.objectReferenceValue = null;
base.OnEnable();
shaderProperty.objectReferenceValue = shader;
// create custom shader gui
CreateCustomShaderEditorIfNeededFast(shader);
}
void CreateCustomShaderEditorIfNeededFast(Shader shader)
{
var internalThis = new InternalClass(this, typeof(UnityEditor.MaterialEditor));
var customEditor = string.Empty;
if (shader != null)
{
var internalShader = new InternalClass(shader);
customEditor = internalShader.Get<string>("customEditor");
}
if (shader == null || string.IsNullOrEmpty(customEditor))
{
internalThis.Set("m_CustomEditorClassName", "");
internalThis.Set("m_CustomShaderGUI", null);
}
else
{
if (internalThis.Get<string>("m_CustomEditorClassName") == customEditor)
return;
internalThis.Set("m_CustomEditorClassName", customEditor);
internalThis.Set("m_CustomShaderGUI", CreateShaderGUI(customEditor));
internalThis.Set("m_CheckSetup", true);
}
}
static Dictionary<string, Type> customEditorCache = new Dictionary<string, Type>();
static Type ExtractCustomEditorType(string customEditorName)
{
if (string.IsNullOrEmpty(customEditorName))
return null;
if (customEditorCache.TryGetValue(customEditorName, out var editorType))
return editorType;
var str = "UnityEditor." + customEditorName;
var loadedAssemblies = InternalClass.GetStatic<Assembly[]>("EditorAssemblies.loadedAssemblies");
for (var index = loadedAssemblies.Length - 1; index >= 0; --index)
{
foreach (var c in GetTypesFromAssembly(loadedAssemblies[index]))
{
if (c.FullName.Equals(customEditorName, StringComparison.Ordinal) || c.FullName.Equals(str, StringComparison.Ordinal))
editorType = !typeof(ShaderGUI).IsAssignableFrom(c) ? null : c;
}
}
customEditorCache[customEditorName] = editorType;
return editorType;
}
static Type[] GetTypesFromAssembly(Assembly assembly)
{
if (assembly == null)
return Array.Empty<Type>();
try
{
return assembly.GetTypes();
}
catch (ReflectionTypeLoadException)
{
return Array.Empty<Type>();
}
}
static ShaderGUI CreateShaderGUI(string customEditorName)
{
var customEditorType = ExtractCustomEditorType(customEditorName);
return customEditorType == null ? null : Activator.CreateInstance(customEditorType) as ShaderGUI;
}
@julian-moschuering Thanks for sharing code! I re-wrote your code for using Unity’s new TypeCache and replacing InternalClass type (maybe your own helper class?).
Could you by any chance send us your project via a bug report (referencing the original case would suffice as a description)? We don’t have a reproducible that suffers this severely from the issue.
The same goes for everyone else. Additional reproduction projects would be much appreciated!
@LeonhardP My original report has minimul reproducible project. Case 1180416.
It has many dummy types and test object, renderer with multiple material. If you open that project and select object in hierarchy view, editor freeze 0.5~1 sec (depend on your machine spec). If the scene is playing, freeze time be much longer.
Currently, my production project applied hotfix inspired with @julian-moschuering
The issue is of course, most noticeable in a project that has tons of textures and materials, custom shaders, etc. This means that to repro it most people would have to upload their real projects with all the different materials, textures, shaders etc. This suggests that the algorithms are such that they are not constant but scale with input size so repro projects with a few items probably work just fine
The custom script here helped a ton we can actually edit materials again (2019.2). Thanks! Please don’t leave 2019 without this fix as it will make the LTS release actual cancer since well, companies using the LTS release are obviously going to be making larger and larger projects with more and more assets and will start running into this problem.
@jonathans42 's fix has landed in Trunk and should be backported to 2019.2 and 2019.3 soon.
[quote=“Kichang-Kim, post:8, topic: 756931, username:Kichang-Kim”]
My original report has minimul reproducible project. Case 1180416.
[/quote]QA had a look at the project and the issue no longer reproduces with Jonathan’s fix.
It’s February of 2020, and I am using Unity 2019.3.0f6 and this is still happening to me. Can anyone tell me where to put that script you guys are using to fix this?