Unity 5.5.0p3 - importing any new C# scripts causes compiler to fail

I’m having a strange issue with my project in Unity 5.5.0p3

I can switch platforms between Mac Standalone and IOS without any issues.
I can also build from these platforms which then runs OK on my Mac and iPhone.

However, if I try to import any Asset into my project I get a crash every time when compiling.

This is a sample of the log entries around when it crashes:

Platform assembly: /Applications/Unity 5.5.0p3/Unity 5.5.0p3.app/Contents/PlaybackEngines/macstandalonesupport/UnityEditor.OSXStandalone.Extensions.dll (this message is harmless)
Loading /Applications/Unity 5.5.0p3/Unity 5.5.0p3.app/Contents/PlaybackEngines/macstandalonesupport/UnityEditor.OSXStandalone.Extensions.dll into Unity Child Domain
Non platform assembly: /Applications/Unity 5.5.0p3/PlaybackEngines/iOSSupport/UnityEditor.iOS.Extensions.Xcode.dll (this message is harmless)
Loading /Applications/Unity 5.5.0p3/PlaybackEngines/iOSSupport/UnityEditor.iOS.Extensions.Xcode.dll into Unity Child Domain
Non platform assembly: /Applications/Unity 5.5.0p3/PlaybackEngines/iOSSupport/UnityEditor.iOS.Extensions.Common.dll (this message is harmless)
Loading /Applications/Unity 5.5.0p3/PlaybackEngines/iOSSupport/UnityEditor.iOS.Extensions.Common.dll into Unity Child Domain
metadata.c:887: assertion ‘index < meta->heap_strings.size’ failed
metadata.c:887: assertion ‘index < meta->heap_strings.size’ failed
metadata.c:887: assertion ‘index < meta->heap_strings.size’ failed
metadata.c:915: assertion ‘index < meta->heap_blob.size’ failed
metadata.c:915: assertion ‘index < meta->heap_blob.size’ failed
metadata.c:915: assertion ‘index < meta->heap_blob.size’ failed
metadata.c:887: assertion ‘index < meta->heap_strings.size’ failed
metadata.c:887: assertion ‘index < meta->heap_strings.size’ failed
metadata.c:915: assertion ‘index < meta->heap_blob.size’ failed
The following assembly referenced from /Users/user/Unity-RAD_Rally/Library/ScriptAssemblies/Assembly-CSharp-Editor.dll could not be loaded:
Assembly: (assemblyref_index=3)
Version: 25970.29806.29779.29793
Public Key: 0907d8af90186095
The assembly was not found in the Global Assembly Cache, a path listed in the MONO_PATH environment variable, or in the location of the executing assembly (/Users/user/Unity-RAD_Rally/Library/ScriptAssemblies/).

I then get plenty of “Could not load file TypeLoadException” and “The class … could not be loaded, used in …” errors - hundreds of them.

Once it gets into this state I have to kill Unity. If I then delete the Asset I just imported from the Asset Store (together with its .meta files), and also delete Library/ScriptAssemblies it compiles OK and I’m back with what appears to be a usable project.

If I then manually create a C# Script from the project view, Unity compiles OK and does not seem to have the same issue. If I edit any of my existing scripts Unity compiles OK.

It would therefore appear to be isolated to an issue with Importing new assets, and the subsequent compilation of the imported scripts.

I have only noticed this after upgrading from 5.5.0p2 to 5.5.0p3. This project is also pretty big (20GB+) so unfortunately there is no way I’m going to be able to upload it easily with a bug report.

I have submitted bug case 865933 with the Editor Log as an attachment.

Any help would be really appreciated, thanks!

UPDATE 1 - I have tried doing a full uninstall/reinstall of Unity - still has the same issue. Have also tried deleting Library/metadata - this rebuilds OK however the same issue exists when I go to import any new Assets/C# scripts - Unity crashes with the same metadata.c errors.

I have confirmed the issue is only with this project - if I take another existing project and import an Asset Unity compiles OK - no issues at all.

Deleting the entire Library folder also does not fix this issue - it still ends up with the exact same errors.

UPDATE 2 - managed to reproduce this every time importing uNature, yet AltTrees System imports OK. Thought it might therefore have something to do with corrupt meta information coming from the Cache Server, however after disabling the Cache Server and deleting the Library/metadata folder it still ends up crashing in the same way.

UPDATE 3 - Happy New Year!

So I have the following copies of this project on hand. 1) Latest version - under full version control using Sourcetree / Mecurial. 2) A backup of the last known good state which includes the .hg, however restoring this backup has the same issue. I thought this state was OK as I could at the time import Assets and build to Standalone and IOS. 3) A backup from a few weeks OK which definitely should not have this issue.

I don’t want to just restore from the older backup and fix this, I want to know exactly why this has happened and ideally how to fix it. I have gone through every combination of deleting the Library folder, disabling the Cache server but still the issue occurs. I have rewound Sourcetree back to a known good checkpoint where I last imported Assets and the issue still exists even after deleting the Library folder. So it would seem the Version Control in this case is going to be useless. I have also tried upgrading the project to Unity 5.6.0b3 to see if that is affected and yes, the issue still occurs. If I try to import any new Assets it crashes with metadata.c errors.

Would really love to get some feedback on this, I can find very few references to metadata.c issues on google, they mostly refer to issues outside of Unity and aren’t very helpful in trying to identify why this is happening. Anyone with any ideas?

UPDATE 4 - still no idea how to fix this :frowning:

Did some more tests on my project - deleting all .meta files and the Library/metadata folder just as an experiment to see if this might at least isolate the issue. Nope, still fails in exactly the same way with metadata.c errors and then the following:

The following assembly referenced from /Users/user/Unity-RAD_Rally/Library/ScriptAssemblies/Assembly-CSharp-Editor.dll could not be loaded:
Assembly: (assemblyref_index=4)
Version: 27718.24943.16756.29795
Public Key: 0907d8af90186095
The assembly was not found in the Global Assembly Cache, a path listed in the MONO_PATH environment variable, or in the location of the executing assembly (/Users/user/Unity-RAD_Rally/Library/ScriptAssemblies/).

Looks through the logs it looks like the compile of Assembly-CSharp-Editor.dll completes OK, but then has this error about the assembly not being found. I can however browse the Assembly in Monodevelop and view all the namespaces/classes OK

UPDATE 5 - Restored from another backup from 2 weeks ago, and it has the exact same issue. So that is my current project and both my backups affected. Guess the next step is to go back in the version control history and hope I find a stable revision. Given what I’ve already tried I am not feeling confident about this at all…:face_with_spiral_eyes:

UPDATE 6 - still broken

So, my project is now in a weird state. If I rewind my version control back two steps I can actually install quite a few different Assets from the Asset Store. I am deleting the Library and Temp folders before I open Unity. I have confirmed the Assets I am importing have editor scripts. So it is somewhat stable and would explain why I’ve been backing it up thinking it is in a good state.

However, Unity still blows up when I import uNature. I thought it might be isolated to that, but then SaberCSG also causes the exact same issue. I even deleted uNature from my Asset Store downloads, and confirmed that the MD5 of the unitypackage before/after downloading from the Asset Store is exactly the same. It is exactly the same package so that doesn’t appear to have been corrupted.

UPDATE 7 - so I have a stable project which can update existing Assets (e.g. Grab Yer Assets) without crashing Unity. I just can’t add anything new otherwise it causes the same metadata.c issues. I did another test, if I delete everything in my Assets folder and then importing uNature on it’s own this works OK. It doesn’t fail with metadata.c errors.

UPDATE 8 - issue appears to be identified

After deleting everything in the Assets folder worked, I decided to delete all non-essential Assets in batches. One batch didn’t have the issue so I then went back and one-by-one removed Assets testing for the issue.

The issue in my project appears to be caused by Gaia 1.5.3 - if this Asset is present I can’t import any other Assets without Unity crashing with metadata.c errors. If I remove this from the project, I can import Sabre CSG (as an example, this was crashing previously).

If I remove everything from my project except for Gaia however, I can import uNature and Sabre CSG without Unity crashing. The issue isn’t present. This still makes it difficult to provide a repo project for this bug (due to the size). :eyes:

Hmm… never or heard of this before… obviously some sort of weird Unity issue with your project that seems to have manifested with Gaia.

Have you tried deleting library folder and letting everything re-import (rather than just individual assets) ?

Another option - delete Gaia from your download cache and redownload it - maybe something got corrupted there as well.

Thanks for the feedback Adam, definitely a Unity issue.
Something is corrupted in my project but I can’t figure it out unfortunately.

I have tried:

  • Shutting down my Cache Server (so that it can’t be providing corrupted files)
  • Deleting Gaia from my project
  • Clearing the Library and Temp folders
  • Restarting Unity (which then rebuilds the Library folder)
  • Importing Gaia again (I thought this would have “clean” .meta files with no chance of repeating the issue
  • Import uNature again - it still crashes despite the above steps

Gaia from my Asset Store-5.x folder

md5 Gaia\ -\ Terrain\ Creation\ Texturing\ Population.unitypackage
MD5 (Gaia - Terrain Creation Texturing Population.unitypackage) = b794aa77e6d9a54b3cc832ce1601df43

After deleting it and downloading it again, the md5 is the same:

md5 Gaia\ -\ Terrain\ Creation\ Texturing\ Population.unitypackage
MD5 (Gaia - Terrain Creation Texturing Population.unitypackage) = b794aa77e6d9a54b3cc832ce1601df43

I have sent another update to Unity regarding the case I have logged. Hopefully someone from Unity will be able to respond with some feedback.

Update 9 - further isolated the issue

Right, so I noticed in the Editor.Log that Chronos.AddonDetector was being called in OnPostprocessAllAssets

Chronos: Enabled PlayMaker addon.

…
Chronos.Addon:Check(Boolean) (at Assets/Chronos/Source/Utilities/Editor/AddonDetector.cs:69)
Chronos.AddonDetector:CheckForAddons(Boolean) (at Assets/Chronos/Source/Utilities/Editor/AddonDetector.cs:31)
Chronos.AddonDetector:OnPostprocessAllAssets(String[ ], String[ ], String[ ], String[ ]) (at Assets/Chronos/Source/Utilities/Editor/AddonDetector.cs:46)

Thinking this looks interesting, I updated Chronos from 2.4.3 to 2.4.4 but the issue still occurred. I then decided just to delete Assets/Chronos/Source/Utilities/Editor/AddonDetector.cs altogether and now uNature installs OK with Gaia present in my project.

So it would appear that something is occurring during the OnPostprocessAllAssets that corrupts the metadata specific to Gaia / uNature and causes my project to crash.

Removing this file appears to at least provide a workaround for the moment :slight_smile:

Update 10 - cannot really create a bug repo

So I import Chronos and Gaia into a new project. AddonDetector.cs does not run automatically in this new project, no matter if I do reimport all, etc. uNature then also imports cleanly.

So from what I can tell for some reason in my other project AddonDetector runs on every single file, all the time, and looks to then trigger the metadata.c issue.

This may hopefully help someone in the future, it took a lot of time to narrow this down.

Some nice detective work there!!

Developer of Chronos here, sorry this has caused you so much trouble.

You can rest assured that AddonDetector is not strictly necessary to Chronos; it only means you’ll have to manually enable PlayMaker support if you need it.

Reviewing the AddonDetector source, I don’t see why it would cause a crash, though. I adapted it from @Demigiant 's DOTween code (with permission!). It basically looks for some file pattern (e.g. a PlayMaker file) and if so, enables a CHRONOS_PLAYMAKER define so the plugin can automatically include or exclude code depending on whether PlayMaker is in the assets folder.

I’ll post the full source below, in case someone has a better eye for what might be causing the bug:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;

namespace Chronos
{
    class AddonDetector : AssetPostprocessor
    {
        const string PluginName = "Chronos";
        const string DefinePrefix = "CHRONOS_";

        static readonly Addon[] addons =
        {
            new Addon()
            {
                name = "PlayMaker",
                define = "PLAYMAKER",
                filePattern = "PlayMakerMainMenu.cs"
            }
        };

        static void CheckForAddons(bool display)
        {
            int foundCount = 0;

            foreach (Addon addon in addons)
            {
                if (addon.Check(display))
                {
                    foundCount++;
                }
            }

            if (display)
            {
                Debug.LogFormat("{0}: Addon check complete. {1} / {2} addons found.\n", PluginName, foundCount, addons.Length);
            }
        }

        // Automatic check for addons
        static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
        {
            CheckForAddons(false);
        }

        [MenuItem("Assets/" + PluginName + "/Check for addons...")]
        public static void ManualCheckForAddons()
        {
            CheckForAddons(true);
        }

        public class Addon
        {
            public string name { get; set; }
            public string define { get; set; }
            public string filePattern { get; set; }

            public bool Check(bool display)
            {
                if (Directory.GetFiles(Application.dataPath, filePattern, SearchOption.AllDirectories).Any())
                {
                    bool added = AddDefine();

                    if (added)
                    {
                        Debug.LogFormat("{0}: Enabled {1} addon.\n", PluginName, name);
                    }
                    else if (display)
                    {
                        Debug.LogFormat("{0}: {1} addon is enabled.\n", PluginName, name);
                    }

                    return true;
                }
                else
                {
                    bool removed = RemoveDefine();

                    if (removed)
                    {
                        Debug.LogFormat("{0}: Disabled {1} addon.\n", PluginName, name);
                    }
                    else if (display)
                    {
                        Debug.LogFormat("{0}: {1} addon is disabled.\n", PluginName, name);
                    }

                    return false;
                }
            }

            // Adapted from Demigiant's awesome voodoo.
            // He makes some rad stuff, have a look! http://demigiant.com/

            public bool AddDefine()
            {
                bool added = false;

                string define = DefinePrefix + this.define;

                foreach (BuildTargetGroup group in Enum.GetValues(typeof(BuildTargetGroup)))
                {
                    if (group == BuildTargetGroup.Unknown)
                    {
                        continue;
                    }

                    if (typeof(BuildTargetGroup).GetField(group.ToString()).IsDefined(typeof(ObsoleteAttribute), true))
                    {
                        continue;
                    }

                    List<string> defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group).Split(';').Select(d => d.Trim()).ToList();

                    if (!defines.Contains(define))
                    {
                        added = true;
                        defines.Add(define);
                        PlayerSettings.SetScriptingDefineSymbolsForGroup(group, string.Join(";", defines.ToArray()));
                    }
                }

                return added;
            }

            public bool RemoveDefine()
            {
                bool removed = false;

                string define = DefinePrefix + this.define;

                foreach (BuildTargetGroup group in Enum.GetValues(typeof(BuildTargetGroup)))
                {
                    if (group == BuildTargetGroup.Unknown)
                    {
                        continue;
                    }

                    if (typeof(BuildTargetGroup).GetField(group.ToString()).IsDefined(typeof(ObsoleteAttribute), true))
                    {
                        continue;
                    }

                    List<string> defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group).Split(';').Select(d => d.Trim()).ToList();

                    if (defines.Contains(define))
                    {
                        removed = true;
                        defines.Remove(define);
                        PlayerSettings.SetScriptingDefineSymbolsForGroup(group, string.Join(";", defines.ToArray()));
                    }
                }

                return removed;
            }
        }
    }
}