private static void HandleScriptModifications()
        {
            UdonSharpSettings settings = UdonSharpSettings.GetSettings();

            if (!settings.autoCompileOnModify)
            {
                _modifiedScripts.Clear();
                return;
            }

            if (settings.waitForFocus && !UnityEditorInternal.InternalEditorUtility.isApplicationActive)
            {
                return;
            }

            if (_modifiedScripts.Count == 0)
            {
                return;
            }

            try
            {
                UdonSharpProgramAsset.CompileAllCsPrograms();
            }
            finally
            {
                _modifiedScripts.Clear();
            }
        }
Exemplo n.º 2
0
        /// <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.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)
                {
                    UdonSharpUtils.LogWarning("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);
        }
Exemplo n.º 3
0
        public bool OnBuildRequested(VRCSDKRequestedBuildType requestedBuildType)
        {
            if (requestedBuildType == VRCSDKRequestedBuildType.Avatar)
            {
                return(true);
            }

            if (UdonSharpSettings.GetSettings().disableUploadCompile)
            {
                return(true);
            }

            UdonSharpCompilerV1.CompileSync(new UdonSharpCompileOptions()
            {
                IsEditorBuild = false
            });
            UdonSharpEditorCache.SaveAllCache();

            if (UdonSharpProgramAsset.AnyUdonSharpScriptHasError())
            {
                UdonSharpUtils.LogError("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);
            }

            if (UdonSharpEditorManager.RunAllUpgrades())
            {
                UdonSharpUtils.LogWarning(UdonSharpEditorManager.UPGRADE_MESSAGE);
                return(false);
            }

            return(true);
        }
Exemplo n.º 4
0
        public static string GetProgramTemplateString(string scriptName)
        {
            scriptName = SanitizeName(scriptName);

            UdonSharpSettings settings = GetSettings();

            string templateStr = settings.newScriptTemplateOverride != null?settings.newScriptTemplateOverride.ToString() : DefaultProgramTemplate;

            templateStr = templateStr.Replace("<TemplateClassName>", scriptName);

            return(templateStr);
        }
Exemplo n.º 5
0
        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)
            {
                chosenFilePath = UdonSharpSettings.SanitizeScriptFilePath(chosenFilePath);
                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, System.Text.Encoding.UTF8);

                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();
            }
        }
Exemplo n.º 6
0
        public static UdonSharpSettings GetSettings()
        {
            if (_settings)
            {
                return(_settings);
            }

            UdonSharpSettings settings = AssetDatabase.LoadAssetAtPath <UdonSharpSettings>(UdonSharpLocator.SettingsPath);

            if (settings == null)
            {
                _settings = settings = CreateInstance <UdonSharpSettings>();
            }

            return(settings);
        }
Exemplo n.º 7
0
        internal static UdonSharpSettings GetOrCreateSettings()
        {
            string            settingsPath = UdonSharpLocator.SettingsPath;
            UdonSharpSettings settings     = AssetDatabase.LoadAssetAtPath <UdonSharpSettings>(settingsPath);

            if (settings == null)
            {
                if (!AssetDatabase.IsValidFolder(Path.GetDirectoryName(settingsPath)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(settingsPath));
                }

                _settings = settings = CreateInstance <UdonSharpSettings>();
                AssetDatabase.CreateAsset(settings, settingsPath);
                AssetDatabase.SaveAssets();
            }

            return(settings);
        }
        private static void SetupWatchers()
        {
            if (_fileSystemWatchers != null)
            {
                UdonSharpSettings settings = UdonSharpSettings.GetSettings();

                bool watcherEnabled = settings.autoCompileOnModify;

                if (watcherEnabled == _lastEnabledState)
                {
                    return;
                }

                _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);
            // }

            IEnumerable <string> sourcePaths = CompilationContext.GetAllFilteredSourcePaths(true);

            HashSet <string> sourceDirectoriesSet = new HashSet <string>();

            foreach (string sourcePath in sourcePaths)
            {
                sourceDirectoriesSet.Add(Path.GetDirectoryName(sourcePath));
            }

            string[] sourceDirectories = sourceDirectoriesSet.ToArray();

            _fileSystemWatchers = new FileSystemWatcher[sourceDirectories.Length];

            for (int i = 0; i < sourceDirectories.Length; ++i)
            {
                FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(sourceDirectories[i], "*.cs");
                fileSystemWatcher.IncludeSubdirectories = false;
                fileSystemWatcher.InternalBufferSize    = 512; // Someone would need to modify 32 files in a single directory at once to hit this

                fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;
                fileSystemWatcher.Changed     += OnSourceFileChanged;

                _fileSystemWatchers[i] = fileSystemWatcher;
            }
        }
Exemplo n.º 9
0
        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 = new SerializedObject(settings);

                    // Compiler settings
                    EditorGUILayout.LabelField("Compiler", EditorStyles.boldLabel);

                    EditorGUI.BeginChangeCheck();
                    EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.autoCompileOnModify)), _autoCompileLabel);

                    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(settings);
                    }
                },
            };

            return(provider);
        }