GenericUnityObjects icon indicating copy to clipboard operation
GenericUnityObjects copied to clipboard

[DidReloadScripts] Argument Exception: assemblyString cannot have zero length

Open FahrenheitKid opened this issue 1 year ago • 5 comments
trafficstars

I've just installed this through the package manager and it shows this error when I Try to use the Creatable attribute or [CreateGenericAssetMenu]. It doesn't let me create anything, my Create dropdown menu doesn't show the generic scriptable objects

Screenshot_11

FahrenheitKid avatar Dec 11 '23 22:12 FahrenheitKid

also having this issue

orkuncinfer avatar Mar 13 '24 07:03 orkuncinfer

Same here, I assume its broken in recent versions sadly

JevinLevin avatar Sep 13 '24 13:09 JevinLevin

This seems to be caused by the following function:

/// <summary>Returns the assembly name of the class implemented by this script.</summary>
/// <param name="script">The script to search for assembly in.</param>
/// <returns>
/// The assembly name without the .dll extension, or an empty string if the assembly was not found.
/// </returns>
[PublicAPI, NotNull] public static string GetAssemblyName(this MonoScript script)
{
		string assemblyName = script.Internal_GetAssemblyName();
        int lastDotIndex = assemblyName.LastIndexOf('.');
        return /* Here >> */ lastDotIndex == -1 /* << */ ? string.Empty : assemblyName.Substring(0, lastDotIndex);
}

I think it needs to be:

[PublicAPI, NotNull] public static string GetAssemblyName(this MonoScript script)
{
		string assemblyName = script.Internal_GetAssemblyName();
        int lastDotIndex = assemblyName.LastIndexOf('.');
		if(assemblyName == null || assemblyName == string.Empty)
		{
				return string.Empty;
		}
		return lastDotIndex == -1 ? assemblyName : assemblyName.Substring(0, lastDotIndex);
}

It seems the author assumed that if the dot index is -1 then the assembly is null.

12Acorns avatar Oct 09 '24 19:10 12Acorns

##Temporary fix##

Follow this: https://docs.unity3d.com/Manual/upm-embed.html

Copy 'Library\PackageCache\com.solidalloy.util@[VERSION HERE]' to 'Packages' and remove the '@[VERSION HERE]' Using the one moved to Packages, edit 'MonoScriptExtensions.cs' replacing the original 'GetAssemblyName(...)' with the fix below:

[PublicAPI, NotNull] public static string GetAssemblyName(this MonoScript script)
{
		string assemblyName = script.Internal_GetAssemblyName();
        int lastDotIndex = assemblyName.LastIndexOf('.');
		if(assemblyName == null || assemblyName == string.Empty)
		{
				return string.Empty;
		}
		return lastDotIndex == -1 ? assemblyName : assemblyName.Substring(0, lastDotIndex);
}

Repeat the above of moving the package to 'Packages' for 'com.solidalloy.type-references@[VERSION HERE]' and 'com.solidalloy.generic-unity-objects@[VERSION HERE]', make sure to remove '@[VERSION HERE]' once moved.

Next, to fix an error with the popup menu, change '_closeButtonStyle' value, from 'GUIHelper.cs' in 'com.solidalloy.util', to 'EditorStyles.toolbarTextField' and reference UnityEditor. (See #10)

Go to 'MonoScriptExtensions.cs' and change 'GetClassType' to:

[PublicAPI, CanBeNull] public static Type GetClassType(this MonoScript script, Type _type, string className = null)
{
    Type simpleType = script.GetClass();
    if (simpleType != null)
        return simpleType;

    string foundClassName = string.IsNullOrEmpty(className) ? GetFirstClassFromText(script.text) : GetFirstClassWithName(script.text, className);

    if (string.IsNullOrEmpty(foundClassName))
        return null;

    //string assemblyName = script.GetAssemblyName();
    string assemblyName = _type.GetShortAssemblyName();
Assembly assembly;

    try
    {
        assembly = Assembly.Load(assemblyName);
    }
    catch (Exception e)
    {
        // Whatever caused this exception, the type cannot be loaded, so disregard it as null.
        if (e is FileNotFoundException || e is FileLoadException)
            return null;

        throw;
    }

    string namespaceName = script.GetNamespaceName();
    string fullTypeName = namespaceName == string.Empty ? foundClassName : $"{namespaceName}.{foundClassName}";

    Type type = assembly.GetType(fullTypeName);
    return type;
}

After, in 'TypeReferenceEditor.cs' in ''TryUpdatingTypeUsingGUID' add Type classType = AssetDatabase.GetMainAssetTypeFromGUID(new GUID(GUID)); before var type = script.GetClassType(); and in 'script.GetClassType' ass to the args 'classType' Will look like: var type = script.GetClassType(classType);

In 'AssetHelper.cs' at 'GetAssetDetails' replace with:

public static bool GetAssetDetails(Type type, [CanBeNull] out string GUID, out MonoScript monoScript)
{
    GUID = string.Empty;
    monoScript = null;

    if (type == null)
        return false;

    if (type.IsGenericType)
        type = type.GetGenericTypeDefinition();

    string typeNameWithoutSuffix = type.Name.StripGenericSuffix();

    foreach (string guid in AssetDatabase.FindAssets($"t:MonoScript {typeNameWithoutSuffix}"))
    {
        string assetPath = AssetDatabase.GUIDToAssetPath(guid);
        var asset = AssetDatabase.LoadAssetAtPath<MonoScript>(assetPath);

        if (asset == null || asset.GetClassType(type, typeNameWithoutSuffix) != type)
            continue;

        GUID = guid;
        monoScript = asset;
        return true;
    }

    return false;
}

In 'TypeInfo.cs' replace 'TypeAtGUIDSame' with:

private bool TypeAtGUIDIsSame()
{
    string path = AssetDatabase.GUIDToAssetPath(GUID);
    if (path.Length == 0)
        return false;

    var monoScript = AssetDatabase.LoadAssetAtPath<MonoScript>(path);
    if (monoScript == null)
        return false;
return Type == monoScript.GetClassType(Type);
}

That should be it.

12Acorns avatar Oct 09 '24 20:10 12Acorns

Thank you so much 12Acorns, that was truly helpful !

If someone else encounters this issue, in addition to the changes above I also had to modify a couple more files:

  • In the com.solidalloy.unity-dropdown package, in file Editor/DropdownStyle.cs, update a style name (needs Unity 2022 or newer):
         public static GUIStyle SearchToolbarStyle =>
-            _searchToolbarStyle ?? (_searchToolbarStyle = new GUIStyle(GUI.skin.FindStyle("ToolbarSeachTextField")));
+            _searchToolbarStyle ?? (_searchToolbarStyle = new GUIStyle(GUI.skin.FindStyle("ToolbarSearchTextField")));
  • In the com.solidalloy.util package, in file Editor/Helpers/AssetDatabaseHelper.cs, add a missing parameter:
         public static Type GetTypeFromGUID(string guid)
         {
+            Type classType = AssetDatabase.GetMainAssetTypeFromGUID(new GUID(guid));
             string assetPath = AssetDatabase.GUIDToAssetPath(guid);

             if (string.IsNullOrEmpty(assetPath))
                return null;

             var script = AssetDatabase.LoadAssetAtPath<MonoScript>(assetPath);

-            return script == null ? null : script.GetClassType();
+            return script == null ? null : script.GetClassType(classType);
         }

Oxydiz avatar Oct 19 '24 20:10 Oxydiz