We spent a week chasing ghosts/fixing crashes on start-up when non-programmers synced our project because of this issue, and I wanted to write up the bug and suggest a temporary workaround for anyone else who sees it.
In Unity 2017.1.0f3, on a project with the Google Play Games plugin, script changes made while Unity is not running don’t trigger a compile. At startup, we saw this stack trace:
NullReferenceException: Object reference not set to an instance of an object
UnityEditor.Scripting.ScriptCompilation.EditorCompilation.DirtyScript (System.String path) (at C:/buildslave/unity/build/Editor/Mono/Scripting/ScriptCompilation/EditorCompilation.cs:88)
UnityEditor.Scripting.ScriptCompilation.EditorCompilationInterface.DirtyScript (System.String path) (at C:/buildslave/unity/build/Editor/Mono/Scripting/ScriptCompilation/EditorCompilationInterface.cs:44)
UnityEditor.AssetDatabase:Refresh()
GooglePlayGames.Editor.GPGSUpgrader:.cctor() (at Assets/GooglePlayGames/Editor/GPGSUpgrader.cs:110)
UnityEditor.EditorAssemblies:ProcessInitializeOnLoadAttributes()
If you hit play, it’ll run the most recently compiled thing, which meant features looked half-working, or crashed completely if assets and scripts diverged enough – artists and designers were hit hardest, since they didn’t edit scripts. The only way to get it to compile was to tab out of Unity, change some C# file, and tab back.
Our workaround for now is to comment out line 110 of GPGSUpgrader.cs, so it doesn’t call AssetDatabase.Refresh(). But, it looks like the general problem here is that it’s not safe to call AssetDatabase.Refresh() from UnityEditor.EditorAssemblies: ProcessInitializeOnLoadAttributes(). Based on ILSpy output, it’s because EditorCompilation.DirtyScript() references allScripts, which is initialized to null and only set by EditorCompilation.SetAllScripts().
Hope this helps save some headaches until a fix lands.