/// <summary> /// 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. /// </summary> /// <param name="requestedBuildType"></param> /// <returns></returns> 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); }
/// <summary> /// 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. /// </summary> /// <param name="requestedBuildType"></param> /// <returns></returns> 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) { Debug.LogError("[<color=#FF00FF>UdonSharp</color>] Scripts are in the process of compiling, please retry build after scripts have compiled."); UdonSharpUtils.ShowEditorNotification("Scripts are in the process of compiling, please retry build after scripts have compiled."); return(false); } } return(true); }
private bool DrawCreateScriptButton() { if (GUILayout.Button("Create Script")) { string thisPath = AssetDatabase.GetAssetPath(this); //string initialPath = Path.GetDirectoryName(thisPath); string fileName = Path.GetFileNameWithoutExtension(thisPath).Replace(" Udon C# Program Asset", "").Replace(" ", "").Replace("#", "Sharp"); string chosenFilePath = EditorUtility.SaveFilePanelInProject("Save UdonSharp File", fileName, "cs", "Save UdonSharp file"); if (chosenFilePath.Length > 0) { string fileContents = UdonSharpSettings.GetProgramTemplateString(Path.GetFileNameWithoutExtension(chosenFilePath)); File.WriteAllText(chosenFilePath, fileContents); AssetDatabase.ImportAsset(chosenFilePath, ImportAssetOptions.ForceSynchronousImport); AssetDatabase.Refresh(); sourceCsScript = AssetDatabase.LoadAssetAtPath <MonoScript>(chosenFilePath); return(true); } } return(false); }
public static string GetProgramTemplateString(string scriptName) { scriptName = scriptName.Replace(" ", "") .Replace("#", "Sharp") .Replace("(", "") .Replace(")", "") .Replace("*", "") .Replace("<", "") .Replace(">", "") .Replace("-", "_"); UdonSharpSettings settings = GetSettings(); string templateStr; if (settings != null && settings.newScriptTemplateOverride != null) { templateStr = settings.newScriptTemplateOverride.ToString(); } else { templateStr = DefaultProgramTemplate; } templateStr = templateStr.Replace("<TemplateClassName>", scriptName); return(templateStr); }
static void HandleScriptModifications() { UdonSharpSettings settings = UdonSharpSettings.GetSettings(); if (settings != null) { if (!settings.autoCompileOnModify) { modifiedScripts.Clear(); return; } if (settings.waitForFocus && !UnityEditorInternal.InternalEditorUtility.isApplicationActive) { return; } } if (modifiedScripts.Count == 0) { return; } UdonSharpProgramAsset[] udonSharpPrograms = UdonSharpProgramAsset.GetAllUdonSharpPrograms(); HashSet <UdonSharpProgramAsset> assetsToUpdate = new HashSet <UdonSharpProgramAsset>(); foreach (MonoScript script in modifiedScripts) { foreach (UdonSharpProgramAsset programAsset in udonSharpPrograms) { if (programAsset.sourceCsScript == script) { assetsToUpdate.Add(programAsset); } } } try { if (assetsToUpdate.Count > 0) { if (settings == null || settings.compileAllScripts) { UdonSharpProgramAsset.CompileAllCsPrograms(); } else { UdonSharpCompiler compiler = new UdonSharpCompiler(assetsToUpdate.ToArray()); compiler.Compile(); } } } finally { modifiedScripts.Clear(); } }
static void SetupWatchers() { if (fileSystemWatchers != null) { UdonSharpSettings settings = UdonSharpSettings.GetSettings(); bool watcherEnabled = settings == null || settings.autoCompileOnModify; if (watcherEnabled != lastEnabledState) { lastEnabledState = watcherEnabled; foreach (FileSystemWatcher watcher in fileSystemWatchers) { if (watcher != null) { watcher.EnableRaisingEvents = watcherEnabled; } } } return; } AssemblyReloadEvents.beforeAssemblyReload += CleanupWatchers; string[] blacklistedDirectories = UdonSharpSettings.GetScannerBlacklist(); string[] directories = Directory.GetDirectories("Assets/", "*", SearchOption.AllDirectories).Append("Assets/") .Select(e => e.Replace('\\', '/')) .Where(e => !blacklistedDirectories.Any(name => name.TrimEnd('/') == e.TrimEnd('/') || e.StartsWith(name))) .ToArray(); List <string> sourceDirectories = new List <string>(); foreach (string directory in directories) { if (Directory.GetFiles(directory, "*.cs").Length > 0) { sourceDirectories.Add(directory); } } fileSystemWatchers = new FileSystemWatcher[sourceDirectories.Count]; for (int i = 0; i < sourceDirectories.Count; ++i) { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(sourceDirectories[i], "*.cs"); fileSystemWatcher.IncludeSubdirectories = false; fileSystemWatcher.InternalBufferSize = 1024; // Someone would need to modify 64 files in a single directory at once to hit this fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite; fileSystemWatcher.Changed += OnSourceFileChanged; fileSystemWatchers[i] = fileSystemWatcher; } }
public static SettingsProvider CreateSettingsProvider() { SettingsProvider provider = new SettingsProvider("Project/Udon Sharp", SettingsScope.Project) { label = "Udon Sharp", keywords = new HashSet <string>(new string[] { "Udon", "Sharp", "U#", "VRC", "VRChat" }), guiHandler = (searchContext) => { UdonSharpSettings settings = UdonSharpSettings.GetOrCreateSettings(); SerializedObject settingsObject = UdonSharpSettings.GetSerializedSettings(); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.autoCompileOnModify)), autoCompileLabel); if (settings.autoCompileOnModify) { EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.compileAllScripts)), compileAllLabel); if (!settings.compileAllScripts) { EditorGUILayout.HelpBox("Only compiling the script that has been modified can cause issues if you have multiple scripts communicating via methods.", MessageType.Warning); } } EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.waitForFocus)), waitForFocusLabel); EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.newScriptTemplateOverride)), templateOverrideLabel); EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.scanningDirectoryBlacklist)), scanningBlackListLabel, true); EditorGUILayout.Space(); EditorGUILayout.LabelField("Debugging", EditorStyles.boldLabel); EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.buildDebugInfo)), includeDebugInfoLabel); if (settings.buildDebugInfo) { EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.includeInlineCode)), includeInlineCodeLabel); 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(); EditorUtility.SetDirty(UdonSharpSettings.GetSettings()); } }, }; return(provider); }
public static string GetProgramTemplateString() { UdonSharpSettings settings = GetSettings(); if (settings != null && settings.newScriptTemplateOverride != null) { return(settings.newScriptTemplateOverride.ToString()); } return(DefaultProgramTemplate); }
public static string[] GetScannerBlacklist() { UdonSharpSettings settings = GetSettings(); if (settings != null) { return(BuiltinScanningBlacklist.Concat(settings.scanningDirectoryBlacklist).ToArray()); } return(BuiltinScanningBlacklist); }
internal static UdonSharpSettings GetOrCreateSettings() { UdonSharpSettings settings = AssetDatabase.LoadAssetAtPath <UdonSharpSettings>(SettingsSavePath); if (settings == null) { settings = ScriptableObject.CreateInstance <UdonSharpSettings>(); AssetDatabase.CreateAsset(settings, SettingsSavePath); AssetDatabase.SaveAssets(); } return(settings); }
private static void CreateUSharpScript() { string folderPath = "Assets/"; if (Selection.activeObject != null) { folderPath = AssetDatabase.GetAssetPath(Selection.activeObject); if (Selection.activeObject.GetType() != typeof(UnityEditor.DefaultAsset)) { folderPath = Path.GetDirectoryName(folderPath); } } else if (Selection.assetGUIDs.Length > 0) { folderPath = AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[0]); } folderPath = folderPath.Replace('\\', '/'); string chosenFilePath = EditorUtility.SaveFilePanelInProject("Save UdonSharp File", "", "cs", "Save UdonSharp file", folderPath); if (chosenFilePath.Length > 0) { string chosenFileName = Path.GetFileNameWithoutExtension(chosenFilePath).Replace(" ", "").Replace("#", "Sharp"); string assetFilePath = Path.Combine(Path.GetDirectoryName(chosenFilePath), $"{chosenFileName}.asset"); if (AssetDatabase.LoadAssetAtPath <UdonSharpProgramAsset>(assetFilePath) != null) { if (!EditorUtility.DisplayDialog("File already exists", $"Corresponding asset file '{assetFilePath}' already found for new UdonSharp script. Overwrite?", "Ok", "Cancel")) { return; } } string fileContents = UdonSharpSettings.GetProgramTemplateString(chosenFileName); File.WriteAllText(chosenFilePath, fileContents); AssetDatabase.ImportAsset(chosenFilePath, ImportAssetOptions.ForceSynchronousImport); MonoScript newScript = AssetDatabase.LoadAssetAtPath <MonoScript>(chosenFilePath); UdonSharpProgramAsset newProgramAsset = ScriptableObject.CreateInstance <UdonSharpProgramAsset>(); newProgramAsset.sourceCsScript = newScript; AssetDatabase.CreateAsset(newProgramAsset, assetFilePath); AssetDatabase.Refresh(); } }
public CompilationModule(UdonSharpProgramAsset sourceAsset) { programAsset = sourceAsset; resolver = new ResolverContext(); moduleSymbols = new SymbolTable(resolver, null); moduleLabels = new LabelTable(); fieldsWithInitializers = new HashSet <FieldDeclarationSyntax>(); if (programAsset.sourceCsScript == null) { throw new System.ArgumentException($"Asset '{AssetDatabase.GetAssetPath(programAsset)}' does not have a valid program source to compile from"); } sourceCode = UdonSharpUtils.ReadFileTextSync(AssetDatabase.GetAssetPath(programAsset.sourceCsScript)); settings = UdonSharpSettings.GetSettings(); }
static void HandleScriptModifications(List <MonoScript> scripts) { UdonSharpSettings settings = UdonSharpSettings.GetSettings(); if (settings != null && !settings.autoCompileOnModify) { return; } string[] udonSharpDataAssets = AssetDatabase.FindAssets($"t:{typeof(UdonSharpProgramAsset).Name}"); List <UdonSharpProgramAsset> udonSharpPrograms = new List <UdonSharpProgramAsset>(); foreach (string dataGuid in udonSharpDataAssets) { udonSharpPrograms.Add(AssetDatabase.LoadAssetAtPath <UdonSharpProgramAsset>(AssetDatabase.GUIDToAssetPath(dataGuid))); } HashSet <UdonSharpProgramAsset> assetsToUpdate = new HashSet <UdonSharpProgramAsset>(); foreach (MonoScript script in scripts) { foreach (UdonSharpProgramAsset programAsset in udonSharpPrograms) { if (programAsset.sourceCsScript == script) { assetsToUpdate.Add(programAsset); } } } if (assetsToUpdate.Count > 0) { if (settings == null || settings.compileAllScripts) { UdonSharpProgramAsset.CompileAllCsPrograms(); } else { UdonSharpCompiler compiler = new UdonSharpCompiler(assetsToUpdate.ToArray()); compiler.Compile(); } } }
static void OnEditorUpdate() { SetupWatchers(); UdonSharpSettings settings = UdonSharpSettings.GetSettings(); bool watcherEnabled = settings == null || settings.autoCompileOnModify; if (watcherEnabled != lastEnabledState && fileSystemWatchers != null) { lastEnabledState = watcherEnabled; foreach (FileSystemWatcher watcher in fileSystemWatchers) { if (watcher != null) { watcher.EnableRaisingEvents = watcherEnabled; } } } List <MonoScript> modifiedScripts = null; lock (modifiedFileLock) { if (modifiedFilePaths.Count > 0) { modifiedScripts = new List <MonoScript>(); foreach (string filePath in modifiedFilePaths) { MonoScript asset = AssetDatabase.LoadAssetAtPath <MonoScript>(filePath.Replace(Application.dataPath.Replace("/", "\\"), "Assets")); modifiedScripts.Add(asset); } modifiedFilePaths.Clear(); } } if (modifiedScripts != null && modifiedScripts.Count > 0) { HandleScriptModifications(modifiedScripts); } }
public static string GetProgramTemplateString(string scriptName) { scriptName = SanitizeName(scriptName); UdonSharpSettings settings = GetSettings(); string templateStr; if (settings != null && settings.newScriptTemplateOverride != null) { templateStr = settings.newScriptTemplateOverride.ToString(); } else { templateStr = DefaultProgramTemplate; } templateStr = templateStr.Replace("<TemplateClassName>", scriptName); return(templateStr); }
public bool OnBuildRequested(VRCSDKRequestedBuildType requestedBuildType) { if (requestedBuildType == VRCSDKRequestedBuildType.Avatar) { return(true); } if (UdonSharpSettings.GetSettings()?.disableUploadCompile ?? false) { return(true); } UdonSharpProgramAsset.CompileAllCsPrograms(true, false); UdonSharpEditorCache.SaveAllCache(); if (UdonSharpProgramAsset.AnyUdonSharpScriptHasError()) { Debug.LogError("[<color=#FF00FF>UdonSharp</color>] Failed to compile UdonSharp scripts for build, check error log for details."); UdonSharpUtils.ShowEditorNotification("Failed to compile UdonSharp scripts for build, check error log for details."); return(false); } return(true); }
public static UdonSharpSettings GetSettings() { UdonSharpSettings settings = AssetDatabase.LoadAssetAtPath <UdonSharpSettings>(SettingsSavePath); return(settings); }
public int Compile(List <ClassDefinition> classDefinitions) { if (programAsset.sourceCsScript == null) { throw new System.ArgumentException($"Asset '{AssetDatabase.GetAssetPath(programAsset)}' does not have a valid program source to compile from"); } Profiler.BeginSample("Compile Module"); programAsset.compileErrors.Clear(); sourceCode = File.ReadAllText(AssetDatabase.GetAssetPath(programAsset.sourceCsScript)); Profiler.BeginSample("Parse AST"); SyntaxTree tree = CSharpSyntaxTree.ParseText(sourceCode); Profiler.EndSample(); int errorCount = 0; string errorString = ""; foreach (Diagnostic diagnostic in tree.GetDiagnostics()) { if (diagnostic.Severity == DiagnosticSeverity.Error) { errorCount++; LinePosition linePosition = diagnostic.Location.GetLineSpan().StartLinePosition; errorString = UdonSharpUtils.LogBuildError($"error {diagnostic.Descriptor.Id}: {diagnostic.GetMessage()}", AssetDatabase.GetAssetPath(programAsset.sourceCsScript).Replace("/", "\\"), linePosition.Line, linePosition.Character); programAsset.compileErrors.Add(errorString); } } if (errorCount > 0) { ErrorCount = errorCount; Profiler.EndSample(); return(errorCount); } Profiler.BeginSample("Visit"); UdonSharpFieldVisitor fieldVisitor = new UdonSharpFieldVisitor(fieldsWithInitializers); fieldVisitor.Visit(tree.GetRoot()); MethodVisitor methodVisitor = new MethodVisitor(resolver, moduleSymbols, moduleLabels); methodVisitor.Visit(tree.GetRoot()); UdonSharpSettings settings = UdonSharpSettings.GetSettings(); ClassDebugInfo debugInfo = null; if (settings == null || settings.buildDebugInfo) { debugInfo = new ClassDebugInfo(sourceCode, settings == null || settings.includeInlineCode); } ASTVisitor visitor = new ASTVisitor(resolver, moduleSymbols, moduleLabels, methodVisitor.definedMethods, classDefinitions, debugInfo); try { visitor.Visit(tree.GetRoot()); visitor.VerifyIntegrity(); } catch (System.Exception e) { SyntaxNode currentNode = visitor.visitorContext.currentNode; string logMessage = ""; if (currentNode != null) { FileLinePositionSpan lineSpan = currentNode.GetLocation().GetLineSpan(); logMessage = UdonSharpUtils.LogBuildError($"{e.GetType()}: {e.Message}", AssetDatabase.GetAssetPath(programAsset.sourceCsScript).Replace("/", "\\"), lineSpan.StartLinePosition.Line, lineSpan.StartLinePosition.Character); } else { logMessage = e.ToString(); Debug.LogException(e); } programAsset.compileErrors.Add(logMessage); errorCount++; } Profiler.EndSample(); if (errorCount == 0) { Profiler.BeginSample("Build assembly"); string dataBlock = BuildHeapDataBlock(); string codeBlock = visitor.GetCompiledUasm(); programAsset.SetUdonAssembly(dataBlock + codeBlock); Profiler.EndSample(); Profiler.BeginSample("Assemble Program"); programAsset.AssembleCsProgram((uint)(moduleSymbols.GetAllUniqueChildSymbols().Count + visitor.GetExternStrCount())); Profiler.EndSample(); programAsset.behaviourIDHeapVarName = visitor.GetIDHeapVarName(); programAsset.fieldDefinitions = visitor.visitorContext.localFieldDefinitions; if (debugInfo != null) { debugInfo.FinalizeDebugInfo(); } programAsset.debugInfo = debugInfo; } Profiler.EndSample(); return(errorCount); }
public static SettingsProvider CreateSettingsProvider() { SettingsProvider provider = new SettingsProvider("Project/Udon Sharp", SettingsScope.Project) { label = "Udon Sharp", keywords = new HashSet <string>(new string[] { "Udon", "Sharp", "U#", "VRC", "VRChat" }), guiHandler = (searchContext) => { UdonSharpSettings settings = UdonSharpSettings.GetOrCreateSettings(); SerializedObject settingsObject = UdonSharpSettings.GetSerializedSettings(); // Compiler settings EditorGUILayout.LabelField("Compiler", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.autoCompileOnModify)), autoCompileLabel); if (settings.autoCompileOnModify) { EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.compileAllScripts)), compileAllLabel); if (!settings.compileAllScripts) { EditorGUILayout.HelpBox("Only compiling the script that has been modified can cause issues if you have multiple scripts communicating via methods.", MessageType.Warning); } } EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.waitForFocus)), waitForFocusLabel); EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.disableUploadCompile)), disableUploadCompileLabel); if (settings.disableUploadCompile) { EditorGUILayout.HelpBox(@"Do not disable this setting unless it is not viable to wait for the compile on upload process. Disabling this setting will make the UNITY_EDITOR define not work as expected and will break prefabs that depend on the define being accurate between game and editor builds.", MessageType.Warning); } EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.newScriptTemplateOverride)), templateOverrideLabel); EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.scanningDirectoryBlacklist)), scanningBlackListLabel, true); EditorGUILayout.Space(); // Interface settings EditorGUILayout.LabelField("Interface", EditorStyles.boldLabel); SerializedProperty defaultDrawerProperty = settingsObject.FindProperty(nameof(UdonSharpSettings.defaultBehaviourInterfaceType)); defaultDrawerProperty.stringValue = DrawCustomEditorSelection(defaultDrawerProperty.stringValue); EditorGUILayout.Space(); // Debugging settings EditorGUILayout.LabelField("Debugging", EditorStyles.boldLabel); EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.buildDebugInfo)), includeDebugInfoLabel); if (settings.buildDebugInfo) { EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.includeInlineCode)), includeInlineCodeLabel); EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.listenForVRCExceptions)), listenForVRCExceptionsLabel); } EditorGUILayout.Space(); SerializedProperty watcherModeProperty = settingsObject.FindProperty(nameof(UdonSharpSettings.watcherMode)); EditorGUILayout.PropertyField(watcherModeProperty, outputLogWatcherModeLabel); if (watcherModeProperty.enumValueIndex == (int)UdonSharpSettings.LogWatcherMode.Prefix) { EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.logWatcherMatchStrings)), prefixArrayLabel, true); } EditorGUILayout.Space(); // Experimental settings EditorGUILayout.LabelField("Experimental", EditorStyles.boldLabel); EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.shouldForceCompile)), forceCompileLabel); if (EditorGUI.EndChangeCheck()) { settingsObject.ApplyModifiedProperties(); EditorUtility.SetDirty(UdonSharpSettings.GetSettings()); } }, }; return(provider); }
static void HandleScriptModifications() { UdonSharpSettings settings = UdonSharpSettings.GetSettings(); if (settings != null) { if (!settings.autoCompileOnModify) { modifiedScripts.Clear(); return; } if (settings.waitForFocus && !UnityEditorInternal.InternalEditorUtility.isApplicationActive) { return; } } if (modifiedScripts.Count == 0) { return; } string[] udonSharpDataAssets = AssetDatabase.FindAssets($"t:{typeof(UdonSharpProgramAsset).Name}"); List <UdonSharpProgramAsset> udonSharpPrograms = new List <UdonSharpProgramAsset>(); foreach (string dataGuid in udonSharpDataAssets) { udonSharpPrograms.Add(AssetDatabase.LoadAssetAtPath <UdonSharpProgramAsset>(AssetDatabase.GUIDToAssetPath(dataGuid))); } HashSet <UdonSharpProgramAsset> assetsToUpdate = new HashSet <UdonSharpProgramAsset>(); foreach (MonoScript script in modifiedScripts) { foreach (UdonSharpProgramAsset programAsset in udonSharpPrograms) { if (programAsset.sourceCsScript == script) { assetsToUpdate.Add(programAsset); } } } try { if (assetsToUpdate.Count > 0) { if (settings == null || settings.compileAllScripts) { UdonSharpProgramAsset.CompileAllCsPrograms(); } else { UdonSharpCompiler compiler = new UdonSharpCompiler(assetsToUpdate.ToArray()); compiler.Compile(); } } } finally { modifiedScripts.Clear(); } modifiedScripts.Clear(); }