diff --git a/HOWTO.pdf b/HOWTO.pdf index 3e7176e..7486f39 100644 Binary files a/HOWTO.pdf and b/HOWTO.pdf differ diff --git a/LICENSE b/LICENSE index 8250fd1..13b5259 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015 dotBunny Inc. +Copyright (c) 2016 dotBunny Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Plugins/Editor/VSCode.cs b/Plugins/Editor/VSCode.cs index 776c199..314311c 100644 --- a/Plugins/Editor/VSCode.cs +++ b/Plugins/Editor/VSCode.cs @@ -1,10 +1,10 @@ -/* +/* * Unity VSCode Support * * Seamless support for Microsoft Visual Studio Code in Unity * * Version: - * 2.41 + * 2.45 * * Authors: * Matthew Davey @@ -25,12 +25,17 @@ public static class VSCode /// /// Current Version Number /// - public const float Version = 2.41f; + public const float Version = 2.45f; /// /// Current Version Code /// public const string VersionCode = "-RELEASE"; + + /// + /// Download URL for Unity Debbuger + /// + public const string UnityDebuggerURL = "https://unity.gallery.vsassets.io/_apis/public/gallery/publisher/Unity/extension/unity-debug/1.0.1/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage"; #region Properties @@ -63,9 +68,37 @@ public static bool Enabled } set { + // When turning the plugin on, we should remove all the previous project files + if (!Enabled && value) + { + ClearProjectFiles(); + } EditorPrefs.SetBool("VSCode_Enabled", value); } } + public static bool UseUnityDebugger + { + get + { + return EditorPrefs.GetBool("VSCode_UseUnityDebugger", false); + } + set + { + if ( value != UseUnityDebugger ) { + + // Set value + EditorPrefs.SetBool("VSCode_UseUnityDebugger", value); + + // Do not write the launch JSON file because the debugger uses its own + if ( value ) { + WriteLaunchFile = false; + } + + // Update launch file + UpdateLaunchFile(); + } + } + } /// /// Should the launch.json file be written? @@ -156,6 +189,24 @@ static string ProjectPath } } + /// + /// Should the script editor be reverted when quiting Unity. + /// + /// + /// Useful for environments where you do not use VSCode for everything. + /// + static bool RevertExternalScriptEditorOnExit + { + get + { + return EditorPrefs.GetBool("VSCode_RevertScriptEditorOnExit", true); + } + set + { + EditorPrefs.SetBool("VSCode_RevertScriptEditorOnExit", value); + } + } + /// /// Quick reference to the VSCode settings folder /// @@ -199,7 +250,7 @@ static VSCode() { UpdateUnityPreferences(true); UpdateLaunchFile(); - + // Add Update Check DateTime targetDate = LastUpdate.AddDays(UpdateTime); if (DateTime.Now >= targetDate) @@ -207,18 +258,19 @@ static VSCode() CheckForUpdate(); } } - - //System.AppDomain.CurrentDomain.DomainUnload += System_AppDomain_CurrentDomain_DomainUnload; + + // Event for when script is reloaded + System.AppDomain.CurrentDomain.DomainUnload += System_AppDomain_CurrentDomain_DomainUnload; + } + static void System_AppDomain_CurrentDomain_DomainUnload(object sender, System.EventArgs e) + { + if (Enabled && RevertExternalScriptEditorOnExit) + { + UpdateUnityPreferences(false); + } } - // static void System_AppDomain_CurrentDomain_DomainUnload (object sender, System.EventArgs e) - // { - // if (Enabled) { - // UpdateUnityPreferences (false); - // } - // } - #region Public Members /// @@ -302,6 +354,7 @@ static void CallVSCode(string args) proc.StartInfo.Arguments = args; proc.StartInfo.UseShellExecute = false; #endif + proc.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; proc.StartInfo.CreateNoWindow = true; proc.StartInfo.RedirectStandardOutput = true; proc.Start(); @@ -329,7 +382,11 @@ static void CheckForUpdate() if (Debug) { UnityEngine.Debug.Log("[VSCode] " + e.Message); + } + + // Don't go any further if there is an error + return; } finally { @@ -340,9 +397,10 @@ static void CheckForUpdate() LastUpdate = DateTime.Now; // Fix for oddity in downlo - if ( fileContent.Substring(0, 2) != "/*" ) { + if (fileContent.Substring(0, 2) != "/*") + { int startPosition = fileContent.IndexOf("/*", StringComparison.CurrentCultureIgnoreCase); - + // Jump over junk characters fileContent = fileContent.Substring(startPosition); } @@ -368,14 +426,47 @@ static void CheckForUpdate() // Always make sure the file is writable System.IO.FileInfo fileInfo = new System.IO.FileInfo(path); fileInfo.IsReadOnly = false; - + // Write update file File.WriteAllText(path, fileContent); + + // Force update on text file + AssetDatabase.ImportAsset(AssetDatabase.GUIDToAssetPath(GUIDs[0]), ImportAssetOptions.ForceUpdate); } + } } } + /// + /// Clear out any existing project files and lingering stuff that might cause problems + /// + static void ClearProjectFiles() + { + var currentDirectory = Directory.GetCurrentDirectory(); + var solutionFiles = Directory.GetFiles(currentDirectory, "*.sln"); + var projectFiles = Directory.GetFiles(currentDirectory, "*.csproj"); + var unityProjectFiles = Directory.GetFiles(currentDirectory, "*.unityproj"); + + foreach (string solutionFile in solutionFiles) + { + File.Delete(solutionFile); + } + foreach (string projectFile in projectFiles) + { + File.Delete(projectFile); + } + foreach (string unityProjectFile in unityProjectFiles) + { + File.Delete(unityProjectFile); + } + + // Replace with our clean files (only in Unity 5) +#if !UNITY_4_0 && !UNITY_4_1 && !UNITY_4_2 && !UNITY_4_3 && !UNITY_4_5 && !UNITY_4_6 && !UNITY_4_7 + SyncSolution(); +#endif + } + /// /// Force Unity Preferences Window To Read From Settings /// @@ -404,7 +495,7 @@ static void FixUnityPreferences() var invokerType = window.GetType(); var invokerMethod = invokerType.GetMethod("ReadPreferences", - System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (invokerMethod != null) { @@ -505,6 +596,45 @@ static int GetDebugPort() return -1; } + + static void InstallUnityDebugger() + { + EditorUtility.DisplayProgressBar("VSCode", "Downloading Unity Debugger ...", 0.1f); + byte[] fileContent; + + try + { + using (var webClient = new System.Net.WebClient()) + { + fileContent = webClient.DownloadData(UnityDebuggerURL); + } + } + catch (Exception e) + { + if (Debug) + { + UnityEngine.Debug.Log("[VSCode] " + e.Message); + + } + + // Don't go any further if there is an error + return; + } + finally + { + EditorUtility.ClearProgressBar(); + } + + // Do we have a file to install? + if ( fileContent != null ) { + string fileName = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".vsix"; + File.WriteAllBytes(fileName, fileContent); + + CallVSCode(fileName); + } + + } + // HACK: This is in until Unity can figure out why MD keeps opening even though a different program is selected. [MenuItem("Assets/Open C# Project In Code", false, 1000)] static void MenuOpenProject() @@ -531,6 +661,11 @@ static bool ValidateMenuOpenProject() [PreferenceItem("VSCode")] static void VSCodePreferencesItem() { + if (EditorApplication.isCompiling) + { + EditorGUILayout.HelpBox("Please wait for Unity to finish compiling. \nIf the window doesn't refresh, simply click on the window or move it around to cause a repaint to happen.", MessageType.Warning); + return; + } EditorGUILayout.BeginVertical(); EditorGUILayout.HelpBox("Support development of this plugin, follow @reapazor and @dotbunny on Twitter.", MessageType.Info); @@ -538,11 +673,11 @@ static void VSCodePreferencesItem() EditorGUI.BeginChangeCheck(); Enabled = EditorGUILayout.Toggle(new GUIContent("Enable Integration", "Should the integration work its magic for you?"), Enabled); + UseUnityDebugger = EditorGUILayout.Toggle(new GUIContent("Use Unity Debugger", "Should the integration integrate with Unity's VSCode Extension (must be installed)."), UseUnityDebugger); EditorGUILayout.Space(); - - EditorGUI.BeginDisabledGroup(!Enabled); - + RevertExternalScriptEditorOnExit = EditorGUILayout.Toggle(new GUIContent("Revert Script Editor On Unload", "Should the external script editor setting be reverted to its previous setting on project unload? This is useful if you do not use Code with all your projects."),RevertExternalScriptEditorOnExit); + Debug = EditorGUILayout.Toggle(new GUIContent("Output Messages To Console", "Should informational messages be sent to Unity's Console?"), Debug); WriteLaunchFile = EditorGUILayout.Toggle(new GUIContent("Always Write Launch File", "Always write the launch.json settings when entering play mode?"), WriteLaunchFile); @@ -551,14 +686,8 @@ static void VSCodePreferencesItem() AutomaticUpdates = EditorGUILayout.Toggle(new GUIContent("Automatic Updates", "Should the plugin automatically update itself?"), AutomaticUpdates); - EditorGUI.BeginDisabledGroup(!AutomaticUpdates); - UpdateTime = EditorGUILayout.IntSlider(new GUIContent("Update Timer (Days)", "After how many days should updates be checked for?"), UpdateTime, 1, 31); - EditorGUI.EndDisabledGroup(); - - EditorGUI.EndDisabledGroup(); - EditorGUILayout.Space(); EditorGUILayout.Space(); @@ -596,6 +725,20 @@ static void VSCodePreferencesItem() EditorGUILayout.EndVertical(); return; } + EditorGUILayout.Space(); + EditorGUILayout.Space(); + + + if (UseUnityDebugger) + { + EditorGUILayout.HelpBox("In order for the \"Use Unity Debuggger\" option to function above, you need to have installed the Unity Debugger Extension for Visual Studio Code. You can do this by simply clicking the button below and it will take care of the rest.", MessageType.Warning); + if (GUILayout.Button(new GUIContent("Install Unity Debugger", "Install the Unity Debugger Extension into Code"))) + { + InstallUnityDebugger(); + EditorGUILayout.EndVertical(); + return; + } + } GUILayout.FlexibleSpace(); EditorGUILayout.BeginHorizontal(); @@ -621,7 +764,7 @@ static void VSCodePreferencesItem() [UnityEditor.Callbacks.OnOpenAssetAttribute()] static bool OnOpenedAsset(int instanceID, int line) { - // bail out if we are not on a Mac or if we don't want to use VSCode + // bail out if we are not using VSCode if (!Enabled) { return false; @@ -708,7 +851,7 @@ static string ScrubProjectContent(string content) if (content.Length == 0) return ""; -// Note: it causes OmniSharp faults on Windows, such as "not seeing UnityEngine.UI". 3.5 target works fine + // Note: it causes OmniSharp faults on Windows, such as "not seeing UnityEngine.UI". 3.5 target works fine #if !UNITY_EDITOR_WIN // Make sure our reference framework is 2.0, still the base for Unity if (content.IndexOf("v3.5") != -1) @@ -799,13 +942,25 @@ static string ScrubSolutionContent(string content) return content; } - + + /// /// Update Visual Studio Code Launch file /// static void UpdateLaunchFile() { - if (VSCode.Enabled && VSCode.WriteLaunchFile) + if ( !VSCode.Enabled ) return; + + else if ( VSCode.UseUnityDebugger ) { + if (!Directory.Exists(VSCode.SettingsFolder)) + System.IO.Directory.CreateDirectory(VSCode.SettingsFolder); + + // Write out proper formatted JSON (hence no more SimpleJSON here) + string fileContent = "{\n\t\"version\": \"0.2.0\",\n\t\"configurations\": [\n\t\t{\n\t\t\t\"name\": \"Unity Editor\",\n\t\t\t\"type\": \"unity\",\n\t\t\t\"request\": \"launch\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Windows Player\",\n\t\t\t\"type\": \"unity\",\n\t\t\t\"request\": \"launch\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"OSX Player\",\n\t\t\t\"type\": \"unity\",\n\t\t\t\"request\": \"launch\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Linux Player\",\n\t\t\t\"type\": \"unity\",\n\t\t\t\"request\": \"launch\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"iOS Player\",\n\t\t\t\"type\": \"unity\",\n\t\t\t\"request\": \"launch\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"Android Player\",\n\t\t\t\"type\": \"unity\",\n\t\t\t\"request\": \"launch\"\n\n\t\t}\n\t]\n}"; + File.WriteAllText(VSCode.LaunchPath, fileContent); + } + + else if (VSCode.WriteLaunchFile) { int port = GetDebugPort(); if (port > -1) diff --git a/README.md b/README.md index 1ad27d2..fadb9ac 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ > Seamless Visual Studio Code Integration in Unity - As seen in the [Visual Studio Code documentation!](https://code.visualstudio.com/Docs/runtimes/unity) ### Requirements -##### Unity 4.6+ -I am not sure exactly where in the 4.x cycle some of the features I'm using were introduced, but I'm guessing its around the 4.6+ mark. +##### Unity 4.5+ +I am not sure exactly where in the 4.x cycle some of the features I'm using were introduced, but I'm guessing its around the 4.5+ mark. I've checked with the latest 4.5.0f6 release. #####Visual Studio Code 0.10.1+ Get the [latest version](https://code.visualstudio.com), or have a look at the past releases of the VSCode [plugin](https://github.com/dotBunny/VSCode/releases/tag/1.6.5) for support for your version. @@ -23,7 +23,7 @@ Once the VSCode file is in place, simply navigate your way to the `Unity Prefere That's it! Your ready to go! -OK, so maybe some people need a little video explaining some of the finer details of how to use the plugin. So I shot a [quick video](https://vimeo.com/dotbunny/vscode) that highlights the ups and the downs (like Unity hanging after debugging sometimes) for people to watch. Please note this video is from a previous version of the plugin where things are in the menu, this has changed. +OK, so maybe some people need a little video explaining some of the finer details of how to use the plugin. So I shot a [quick video](https://vimeo.com/dotbunny/vscode) that highlights the ups and the downs (like Unity hanging after debugging sometimes) for people to watch. Please note this video is from a previous version of the plugin where things are in the menu, this has changed since then. ### Platform Support I use the plugin every day on a Mac (so it's battle tested there), and occasionally test it on a Windows VM. As for the recently announced Linux support, it should work just like the Mac version. I'll get around to installing the Linux editor sometime in the near future.