diff --git a/Assets/UdonSharp/Editor/BuildUtilities.meta b/Assets/UdonSharp/Editor/BuildUtilities.meta new file mode 100644 index 00000000..bfbe11fd --- /dev/null +++ b/Assets/UdonSharp/Editor/BuildUtilities.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e814c25513069cc499028a77f499b5a0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UdonSharp/Editor/BuildUtilities/UdonSharpBuildChecks.cs b/Assets/UdonSharp/Editor/BuildUtilities/UdonSharpBuildChecks.cs new file mode 100644 index 00000000..dd72c674 --- /dev/null +++ b/Assets/UdonSharp/Editor/BuildUtilities/UdonSharpBuildChecks.cs @@ -0,0 +1,46 @@ + +using UnityEditor; +using UnityEngine; +using VRC.SDKBase.Editor.BuildPipeline; + +namespace UdonSharp +{ + public class UdonSharpBuildChecks : IVRCSDKBuildRequestedCallback + { + public int callbackOrder => -1; + + /// + /// If you're considering commenting any section of this out, try enabling the force compile in the U# settings first. + /// This is here to prevent you from corrupting your project files. + /// If scripts are left uncompiled from Unity's side when uploading, there is a chance to corrupt your assemblies which can cause all of your UdonBehaviours to lose their variables if handled wrong. + /// + /// + /// + public bool OnBuildRequested(VRCSDKRequestedBuildType requestedBuildType) + { + UdonSharpSettings settings = UdonSharpSettings.GetSettings(); + bool shouldForceCompile = settings != null && settings.shouldForceCompile; + + // Unity doesn't like this and will throw errors if it ends up compiling scripts. But it seems to work. + // This is marked experimental for now since I don't know if it will break horribly in some case. + if (shouldForceCompile) + { + AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate | ImportAssetOptions.ForceSynchronousImport); + } + else + { + AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); + + if (EditorApplication.isCompiling) + { + //EditorUtility.DisplayDialog("Udon# build error", "Scripts are in the process of compiling, please retry build after scripts have compiled.", "OK"); + Debug.LogError("[UdonSharp] Scripts are in the process of compiling, please retry build after scripts have compiled."); + typeof(SceneView).GetMethod("ShowNotification", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static).Invoke(null, new object[] { "Scripts are in the process of compiling, please retry build after scripts have compiled." }); + return false; + } + } + + return true; + } + } +} diff --git a/Assets/UdonSharp/Editor/BuildUtilities/UdonSharpBuildChecks.cs.meta b/Assets/UdonSharp/Editor/BuildUtilities/UdonSharpBuildChecks.cs.meta new file mode 100644 index 00000000..a28e3d1a --- /dev/null +++ b/Assets/UdonSharp/Editor/BuildUtilities/UdonSharpBuildChecks.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 67ef2f829963ac94db0d01f19c3a1caf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UdonSharp/Editor/Editors/UdonSharpSettings.cs b/Assets/UdonSharp/Editor/Editors/UdonSharpSettings.cs index 9b3dcd46..1d53b9d1 100644 --- a/Assets/UdonSharp/Editor/Editors/UdonSharpSettings.cs +++ b/Assets/UdonSharp/Editor/Editors/UdonSharpSettings.cs @@ -53,6 +53,8 @@ void Start() public bool includeInlineCode = true; public bool listenForVRCExceptions = false; + public bool shouldForceCompile = false; + public static UdonSharpSettings GetSettings() { UdonSharpSettings settings = AssetDatabase.LoadAssetAtPath(SettingsSavePath); @@ -126,6 +128,7 @@ public class UdonSharpSettingsProvider private static readonly GUIContent includeInlineCodeLabel = new GUIContent("Inline code", "Include C# inline in generated assembly"); private static readonly GUIContent listenForVRCExceptionsLabel = new GUIContent("Listen for client exceptions", "Listens for exceptions from Udon and tries to match them to scripts in the project"); private static readonly GUIContent scanningBlackListLabel = new GUIContent("Scanning blacklist", "Directories to not watch for source code changes and not include in class lookups"); + private static readonly GUIContent forceCompileLabel = new GUIContent("Force compile on upload", "Forces Unity to synchronously compile scripts when a world build is started. Unity will complain and throw errors, but it seems to work. This is a less intrusive way to prevent Unity from corrupting assemblies on upload."); [SettingsProvider] public static SettingsProvider CreateSettingsProvider() @@ -166,6 +169,11 @@ public static SettingsProvider CreateSettingsProvider() EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.listenForVRCExceptions)), listenForVRCExceptionsLabel); } + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Experimental", EditorStyles.boldLabel); + + EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.shouldForceCompile)), forceCompileLabel); + if (EditorGUI.EndChangeCheck()) { settingsObject.ApplyModifiedProperties(); diff --git a/Assets/UdonSharp/Editor/UdonSharpEditorAssembly.asmdef b/Assets/UdonSharp/Editor/UdonSharpEditorAssembly.asmdef index 8dc74ff7..fc0b4888 100644 --- a/Assets/UdonSharp/Editor/UdonSharpEditorAssembly.asmdef +++ b/Assets/UdonSharp/Editor/UdonSharpEditorAssembly.asmdef @@ -3,8 +3,8 @@ "references": [ "VRC.Udon", "VRC.Udon.Editor", - "UdonSharp.Runtime", - "VRC.Udon.Serialization.OdinSerializer" + "VRC.Udon.Serialization.OdinSerializer", + "UdonSharp.Runtime" ], "optionalUnityReferences": [], "includePlatforms": [ @@ -25,7 +25,8 @@ "VRC.Udon.ClientBindings.dll", "VRCSDK3.dll", "VRCSDKBase.dll", - "System.Collections.Immutable.dll" + "System.Collections.Immutable.dll", + "VRCSDKBase-Editor.dll" ], "autoReferenced": true, "defineConstraints": []