From 6ea7733415e1b6ae1488f0f77f5625b1245fde76 Mon Sep 17 00:00:00 2001 From: Unity Technologies Date: Wed, 24 Apr 2019 17:50:21 +0000 Subject: [PATCH 1/2] Unity 2019.2.0a13 C# reference source code --- Editor/Mono/AssetPostprocessor.cs | 63 +- .../Mixer/GUI/AudioMixerChannelStripView.cs | 48 +- Editor/Mono/BuildPipeline/AssemblyStripper.cs | 5 +- .../DesktopStandalonePostProcessor.cs | 6 + Editor/Mono/CodeEditor/CodeEditor.cs | 228 +++++ .../Mono/CodeEditor/CodeEditorProjectSync.cs | 59 ++ .../CodeEditor/DefaultExternalCodeEditor.cs | 104 +++ Editor/Mono/CodeEditor/IExternalCodeEditor.cs | 17 + Editor/Mono/CodeEditor/SyncVS.cs | 59 ++ Editor/Mono/ContainerWindow.cs | 34 +- Editor/Mono/EditorApplication.cs | 15 +- Editor/Mono/EditorGUI.cs | 12 +- Editor/Mono/EditorGUIUtility.cs | 2 +- Editor/Mono/EditorSettings.bindings.cs | 3 +- Editor/Mono/EditorUtility.bindings.cs | 4 +- Editor/Mono/EditorUtility.cs | 4 +- Editor/Mono/EditorWindow.cs | 12 +- Editor/Mono/GUI/AboutWindow.cs | 7 - Editor/Mono/GUI/ReorderableList.cs | 4 + Editor/Mono/GUI/TypeSelectionList.cs | 8 +- .../AnimationClipInfoProperties.cs | 5 + Editor/Mono/Inspector/AnimationClipEditor.cs | 5 +- Editor/Mono/Inspector/EditorElement.cs | 20 +- Editor/Mono/Inspector/GameObjectInspector.cs | 2 +- Editor/Mono/Inspector/InspectorWindow.cs | 55 +- Editor/Mono/InternalEditorUtility.bindings.cs | 4 +- Editor/Mono/PointEditor.cs | 6 +- Editor/Mono/Prefabs/PrefabImporterEditor.cs | 221 ++++- .../Prefabs/PrefabOverrides/PrefabOverride.cs | 4 +- Editor/Mono/Prefabs/PrefabUtility.bindings.cs | 2 +- Editor/Mono/Prefabs/PrefabUtility.cs | 74 +- .../PreferencesSettingsProviders.cs | 101 +-- Editor/Mono/SceneHierarchy.cs | 2 +- Editor/Mono/ScriptEditorUtility.cs | 56 +- .../Scripting/Compilers/ScriptCompilerBase.cs | 29 +- .../ScriptCompilation/CompilationPipeline.cs | 38 +- .../ScriptCompilation/CustomScriptAssembly.cs | 2 +- .../ScriptCompilation/EditorBuildRules.cs | 16 +- .../ScriptCompilation/EditorCompilation.cs | 8 +- .../ScriptCompilation/ScriptAssembly.cs | 15 +- Editor/Mono/SyncProject.cs | 454 ---------- Editor/Mono/SyncRiderProject.cs | 275 ------ .../Mono/UIElements/VisualTreeAssetEditor.cs | 3 +- .../SolutionSynchronizationSettings.cs | 288 ------ .../SolutionSynchronizer.cs | 842 ------------------ .../VisualStudioIntegration/UnityVSSupport.cs | 366 -------- .../AssetImporterEditor.bindings.cs | 2 + .../ImportSettings/AssetImporterEditor.cs | 78 +- .../ShortcutManagerEditor/ContextManager.cs | 12 +- Modules/UIElements/Panel.cs | 34 +- .../UIElements/Renderer/UIRChainBuilder.cs | 75 +- .../Renderer/UIRChainBuilderImpl.cs | 26 +- .../UIElements/Renderer/UIRLayoutUpdater.cs | 10 +- .../UIElements/Renderer/UIRRepaintUpdater.cs | 6 +- Modules/UIElements/Scheduler.cs | 28 +- Modules/UIElements/ScrollView.cs | 1 + Modules/UIElements/VisualElement.cs | 15 +- Modules/UIElements/VisualTreeLayoutUpdater.cs | 2 +- .../VisualTreeTransformClipUpdater.cs | 47 +- .../StylesDebugger.cs | 8 - .../VREditor/Mono/PlayerSettingsEditorVR.cs | 22 +- Projects/CSharp/UnityEditor.csproj | 30 +- README.md | 2 +- Runtime/Export/Time/Time.bindings.cs | 17 +- Runtime/Export/Unsafe/UnsafeUtilityPatched.cs | 16 + 65 files changed, 1286 insertions(+), 2732 deletions(-) create mode 100644 Editor/Mono/CodeEditor/CodeEditor.cs create mode 100644 Editor/Mono/CodeEditor/CodeEditorProjectSync.cs create mode 100644 Editor/Mono/CodeEditor/DefaultExternalCodeEditor.cs create mode 100644 Editor/Mono/CodeEditor/IExternalCodeEditor.cs create mode 100644 Editor/Mono/CodeEditor/SyncVS.cs delete mode 100644 Editor/Mono/SyncProject.cs delete mode 100644 Editor/Mono/SyncRiderProject.cs delete mode 100644 Editor/Mono/VisualStudioIntegration/SolutionSynchronizationSettings.cs delete mode 100644 Editor/Mono/VisualStudioIntegration/SolutionSynchronizer.cs delete mode 100644 Editor/Mono/VisualStudioIntegration/UnityVSSupport.cs diff --git a/Editor/Mono/AssetPostprocessor.cs b/Editor/Mono/AssetPostprocessor.cs index 540b9def3e..b3578cacea 100644 --- a/Editor/Mono/AssetPostprocessor.cs +++ b/Editor/Mono/AssetPostprocessor.cs @@ -87,7 +87,7 @@ static void PostprocessAllAssets(string[] importedAssets, string[] addedAssets, Profiler.BeginSample("SyncVS.PostprocessSyncProject"); ///@TODO: we need addedAssets for SyncVS. Make this into a proper API and write tests - SyncVS.PostprocessSyncProject(importedAssets, addedAssets, deletedAssets, movedAssets, movedFromPathAssets); + CodeEditorProjectSync.PostprocessSyncProject(importedAssets, addedAssets, deletedAssets, movedAssets, movedFromPathAssets); Profiler.EndSample(); } @@ -100,67 +100,6 @@ static void PreprocessAssembly(string pathName) } } - //This is undocumented, and a "safeguard" for when visualstudio gets a new release that is incompatible with ours, so that users can postprocess our csproj to fix it. - //(or just completely replace them). Hopefully we'll never need this. - static internal void CallOnGeneratedCSProjectFiles() - { - object[] args = {}; - foreach (var method in AllPostProcessorMethodsNamed("OnGeneratedCSProjectFiles")) - { - InvokeMethod(method, args); - } - } - - //This callback is used by C# code editors to modify the .sln file. - static internal string CallOnGeneratedSlnSolution(string path, string content) - { - foreach (var method in AllPostProcessorMethodsNamed("OnGeneratedSlnSolution")) - { - object[] args = { path, content }; - object returnValue = InvokeMethod(method, args); - - if (method.ReturnType == typeof(string)) - content = (string)returnValue; - } - - return content; - } - - // This callback is used by C# code editors to modify the .csproj files. - static internal string CallOnGeneratedCSProject(string path, string content) - { - foreach (var method in AllPostProcessorMethodsNamed("OnGeneratedCSProject")) - { - object[] args = { path, content }; - object returnValue = InvokeMethod(method, args); - - if (method.ReturnType == typeof(string)) - content = (string)returnValue; - } - - return content; - } - - //This callback is used by UnityVS to take over project generation from unity - static internal bool OnPreGeneratingCSProjectFiles() - { - object[] args = {}; - bool result = false; - foreach (var method in AllPostProcessorMethodsNamed("OnPreGeneratingCSProjectFiles")) - { - object returnValue = InvokeMethod(method, args); - - if (method.ReturnType == typeof(bool)) - result = result | (bool)returnValue; - } - return result; - } - - private static IEnumerable AllPostProcessorMethodsNamed(string callbackName) - { - return GetCachedAssetPostprocessorClasses().Select(assetPostprocessorClass => assetPostprocessorClass.GetMethod(callbackName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)).Where(method => method != null); - } - internal class CompareAssetImportPriority : IComparer { int IComparer.Compare(System.Object xo, System.Object yo) diff --git a/Editor/Mono/Audio/Mixer/GUI/AudioMixerChannelStripView.cs b/Editor/Mono/Audio/Mixer/GUI/AudioMixerChannelStripView.cs index fedabc757a..7f3f94bd4f 100644 --- a/Editor/Mono/Audio/Mixer/GUI/AudioMixerChannelStripView.cs +++ b/Editor/Mono/Audio/Mixer/GUI/AudioMixerChannelStripView.cs @@ -413,7 +413,7 @@ void EffectSlot(Rect effectRect, AudioMixerSnapshotController snapshot, AudioMix // Active: Enabled, background for draggable bar // Focused: Enabled, foreground for draggable bar - float level = (effect != null) ? Mathf.Clamp(effect.GetValueForMixLevel(m_Controller, snapshot), AudioMixerController.kMinVolume, AudioMixerController.kMaxEffect) : AudioMixerController.kMinVolume; + float level = GetValueForEffect(effect, p.group, m_Controller, snapshot); bool showLevel = (effect != null) && ((effect.IsSend() && effect.sendTarget != null) || effect.enableWetMix); if (evt.type == EventType.Repaint) { @@ -497,7 +497,7 @@ string GetEffectSlotName(AudioMixerEffectController effect, bool showLevel, Audi { if (m_ChangingWetMixIndex == m_IndexCounter && showLevel) { - return UnityString.Format("{0:F1} dB", effect.GetValueForMixLevel(m_Controller, snapshot)); + return UnityString.Format("{0:F1} dB", GetValueForEffect(effect, p.group, m_Controller, snapshot)); } if (effect.IsSend() && effect.sendTarget != null) @@ -683,26 +683,14 @@ private void EffectSlotDragging(Rect r, AudioMixerSnapshotController snapshot, A Undo.RecordObject(m_Controller.TargetSnapshot, "Change effect level"); if (effect.IsSend() && m_Controller.CachedSelection.Count > 1 && m_Controller.CachedSelection.Contains(p.group)) { - List changeEffects = new List(); - foreach (var g in m_Controller.CachedSelection) - foreach (var e in g.effects) - if (e.effectName == effect.effectName && e.sendTarget == effect.sendTarget) - changeEffects.Add(e); - foreach (var e in changeEffects) - if (!e.IsSend() || e.sendTarget != null) - e.SetValueForMixLevel( - m_Controller, - snapshot, - Mathf.Clamp(e.GetValueForMixLevel(m_Controller, snapshot) + deltaLevel, AudioMixerController.kMinVolume, AudioMixerController.kMaxEffect)); + foreach (var group in m_Controller.CachedSelection) + foreach (var cachedEffect in group.effects) + if (cachedEffect.effectName == effect.effectName && cachedEffect.sendTarget == effect.sendTarget) + SetValueForEffect(cachedEffect, group, m_Controller, snapshot, GetValueForEffect(cachedEffect, group, m_Controller, snapshot) + deltaLevel); } else - { - if (!effect.IsSend() || effect.sendTarget != null) - effect.SetValueForMixLevel( - m_Controller, - snapshot, - Mathf.Clamp(level + deltaLevel, AudioMixerController.kMinVolume, AudioMixerController.kMaxEffect)); - } + SetValueForEffect(effect, p.group, m_Controller, snapshot, level + deltaLevel); + InspectorWindow.RepaintAllInspectors(); } evt.Use(); @@ -1734,5 +1722,25 @@ Rect GetContentRect(List sortedGroups, bool isShowing float maxWidth = channelStripsOffset.x * 2 + (channelStripBaseWidth + channelStripSpacing) * sortedGroups.Count + (isShowingReferencedGroups ? spaceBetweenMainGroupsAndReferenced : 0f); return new Rect(0, 0, maxWidth, maxHeight); } + + static float GetValueForEffect(AudioMixerEffectController effect, AudioMixerGroupController group, AudioMixerController controller, AudioMixerSnapshotController snapshot) + { + float level = AudioMixerController.kMinVolume; + if (effect == null) + return level; + level = (effect.IsSend() && effect.sendTarget != null) ? group.GetValueForSend(controller, snapshot) : effect.GetValueForMixLevel(controller, snapshot); + return Mathf.Clamp(level, AudioMixerController.kMinVolume, AudioMixerController.kMaxEffect); + } + + static void SetValueForEffect(AudioMixerEffectController effect, AudioMixerGroupController group, AudioMixerController controller, AudioMixerSnapshotController snapshot, float level) + { + if (effect == null) + return; + level = Mathf.Clamp(level, AudioMixerController.kMinVolume, AudioMixerController.kMaxEffect); + if (effect.IsSend() && effect.sendTarget != null) + group.SetValueForSend(controller, snapshot, level); + else + effect.SetValueForMixLevel(controller, snapshot, level); + } } } diff --git a/Editor/Mono/BuildPipeline/AssemblyStripper.cs b/Editor/Mono/BuildPipeline/AssemblyStripper.cs index f9c067e66f..8f3bd86f7a 100644 --- a/Editor/Mono/BuildPipeline/AssemblyStripper.cs +++ b/Editor/Mono/BuildPipeline/AssemblyStripper.cs @@ -631,8 +631,11 @@ private static string GetMethodPreserveBlacklistContents(RuntimeClassRegistry rc return sb.ToString(); } - static public void InvokeFromBuildPlayer(BuildTarget buildTarget, RuntimeClassRegistry usedClasses, ManagedStrippingLevel managedStrippingLevel, BuildReport report) + static public void StripForMonoBackend(BuildTarget buildTarget, RuntimeClassRegistry usedClasses, ManagedStrippingLevel managedStrippingLevel, BuildReport report) { + if (managedStrippingLevel == ManagedStrippingLevel.Disabled) + return; + var stagingAreaData = Paths.Combine("Temp", "StagingArea", "Data"); var platformProvider = new BaseIl2CppPlatformProvider(buildTarget, Path.Combine(stagingAreaData, "Libraries"), report); diff --git a/Editor/Mono/BuildPipeline/DesktopStandalonePostProcessor.cs b/Editor/Mono/BuildPipeline/DesktopStandalonePostProcessor.cs index 48f8b19eb1..d8df52f482 100644 --- a/Editor/Mono/BuildPipeline/DesktopStandalonePostProcessor.cs +++ b/Editor/Mono/BuildPipeline/DesktopStandalonePostProcessor.cs @@ -252,6 +252,12 @@ private void SetupStagingArea(BuildPostProcessArgs args, HashSet filesTo ProcessIl2CppOutputForBinary(args); } } + else + { + var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(args.target); + var managedStrippingLevel = PlayerSettings.GetManagedStrippingLevel(buildTargetGroup); + AssemblyStripper.StripForMonoBackend(args.target, args.usedClassRegistry, managedStrippingLevel, args.report); + } RenameFilesInStagingArea(args); } diff --git a/Editor/Mono/CodeEditor/CodeEditor.cs b/Editor/Mono/CodeEditor/CodeEditor.cs new file mode 100644 index 0000000000..45c6ace43d --- /dev/null +++ b/Editor/Mono/CodeEditor/CodeEditor.cs @@ -0,0 +1,228 @@ +// Unity C# reference source +// Copyright (c) Unity Technologies. For terms of use, see +// https://unity3d.com/legal/licenses/Unity_Reference_Only_License + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using UnityEditor; +using UnityEditor.Callbacks; +using UnityEditor.PlatformSupport; +using UnityEditorInternal; +using UnityEngine; +using UnityEngine.Scripting; + +namespace Unity.CodeEditor +{ + public class CodeEditor + { + internal static CodeEditor Editor { get; } = new CodeEditor(); + List m_ExternalCodeEditors = new List(); + IExternalCodeEditor m_DefaultEditor = new DefaultExternalCodeEditor(); + + public struct Installation + { + public string Name; + public string Path; + } + + [RequiredByNativeCode] + static bool OpenFileAtLineColumn(string path, int line, int column) + { + return Editor.Current.OpenProject(path, line, column); + } + + [OnOpenAsset] + static bool OnOpenAsset(int instanceID, int line, int column) + { + var selected = EditorUtility.InstanceIDToObject(instanceID); + var assetPath = AssetDatabase.GetAssetPath(selected); + + var assetFilePath = Path.GetFullPath(assetPath); + if (!(selected.GetType().ToString() == "UnityEditor.MonoScript" || + selected.GetType().ToString() == "UnityEngine.Shader" || + selected.GetType().ToString() == "UnityEngine.Experimental.UIElements.VisualTreeAsset" || + selected.GetType().ToString() == "UnityEngine.StyleSheets.StyleSheet" || + GetExtensionStrings().Contains(Path.GetExtension(assetFilePath).Substring(1)) + )) + { + return false; + } + + if (string.IsNullOrEmpty(assetPath)) + { + return false; + } + return Editor.Current.OpenProject(assetPath, line, column); + } + + static List GetExtensionStrings() + { + var userExtensions = EditorSettings.projectGenerationUserExtensions; + var extensionStrings = userExtensions != null + ? userExtensions.ToList() + : new List {"ts", "bjs", "javascript", "json", "html", "shader"}; + + extensionStrings.AddRange(new[] {"template", "compute", "cginc", "hlsl", "glslinc"}); + + return extensionStrings; + } + + internal Installation EditorInstallation + { + get + { + var editorPath = EditorPrefs.GetString("kScriptsDefaultApp"); + if (string.IsNullOrEmpty(editorPath)) + { + return new Installation + { + Name = "Internal", + Path = "", + }; + } + + foreach (var codeEditor in m_ExternalCodeEditors) + { + Installation installation; + if (codeEditor.TryGetInstallationForPath(editorPath, out installation)) + { + return installation; + } + } + + // This is supporting legacy script editors until they are moved to packages + if (!string.IsNullOrEmpty(editorPath)) + return new Installation { Path = editorPath }; + + // If no script editor is set, try to use first found supported one. + var editorPaths = GetFoundScriptEditorPaths(); + + if (editorPaths.Count > 0) + return new Installation { Path = editorPaths.Keys.ToArray()[0] }; + + return new Installation(); + } + } + + internal IExternalCodeEditor Current + { + get + { + var editorPath = EditorPrefs.GetString("kScriptsDefaultApp"); + if (string.IsNullOrEmpty(editorPath)) + { + return m_DefaultEditor; + } + + foreach (var codeEditor in m_ExternalCodeEditors) + { + Installation installation; + if (codeEditor.TryGetInstallationForPath(editorPath, out installation)) + { + return codeEditor; + } + } + + return m_DefaultEditor; + } + } + + internal Dictionary GetFoundScriptEditorPaths() + { + var result = new Dictionary(); + + foreach (var installation in m_ExternalCodeEditors.SelectMany(codeEditor => codeEditor.Installations)) + { + AddIfPathExists(installation.Name, installation.Path, result); + } + + return result; + } + + static void AddIfPathExists(string name, string path, Dictionary list) + { + if (list.ContainsKey(path)) + return; + if (Directory.Exists(path)) list.Add(path, name); + else if (File.Exists(path)) list.Add(path, name); + } + + public static void SetExternalScriptEditor(string path) + { + EditorPrefs.SetString("kScriptsDefaultApp", path); + Editor.Current.Initialize(path); + InternalEditorUtility.RequestScriptReload(); + } + + public static void Register(IExternalCodeEditor externalCodeEditor) + { + Editor.m_ExternalCodeEditors.Add(externalCodeEditor); + } + + public static IExternalCodeEditor CurrentEditor => Editor.Current; + + public static string CurrentEditorInstallation => Editor.EditorInstallation.Path; + + public static string ParseArgument(string arguments, string path, int line, int column) + { + var newArgument = arguments.Replace("$(ProjectPath)", QuoteForProcessStart(Directory.GetParent(Application.dataPath).FullName)); + newArgument = newArgument.Replace("$(File)", QuoteForProcessStart(path)); + newArgument = newArgument.Replace("$(Line)", line >= 0 ? line.ToString() : "0"); + newArgument = newArgument.Replace("$(Column)", column >= 0 ? column.ToString() : "0"); + return newArgument; + } + + /// + /// Quote a string for passing as a single argument to Process.Start + /// and append it to this string builder. + /// + /// + /// On Windows, quote according to the Win32 CommandLineToArgvW API scheme, + /// used by most Windows applications (with some notable exceptions, like + /// cmd.exe and cscript.exe). On Unix, Mono uses the entirely incompatible + /// GLib g_shell_parse_argv function for converting the argument string to + /// a native Unix argument list, so quote for that instead. + /// + /// Do not use this to quote arguments for command line shells (cmd.exe + /// or POSIX shell), as these may use distinct quotation mechanisms. + /// + /// Do not append two quoted arguments without an (unquoted) separator + /// between them: Two consecutive quotation marks triggers undocumented + /// behavior in CommandLineToArgvW and possibly other argument processors. + /// + // https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/ + static string QuoteForProcessStart(string argument) + { + var sb = new StringBuilder(); + // Quote for g_shell_parse_argv when running on Unix (under Mono). + if (Application.platform != RuntimePlatform.WindowsEditor) + { + sb.Append('\''); + sb.Append(argument.Replace("\\", "\\\\").Replace("'", "\\'")); + sb.Append('\''); + return sb.ToString(); + } + + sb.Append('"'); + for (int i = 0; i < argument.Length; ++i) + { + char c = argument[i]; + if (c == '"') + { + for (int j = i - 1; j >= 0 && argument[j] == '\\'; --j) + sb.Append('\\'); + sb.Append('\\'); + } + sb.Append(c); + } + for (int j = argument.Length - 1; j >= 0 && argument[j] == '\\'; --j) + sb.Append('\\'); + sb.Append('"'); + return sb.ToString(); + } + } +} diff --git a/Editor/Mono/CodeEditor/CodeEditorProjectSync.cs b/Editor/Mono/CodeEditor/CodeEditorProjectSync.cs new file mode 100644 index 0000000000..eb7e43a839 --- /dev/null +++ b/Editor/Mono/CodeEditor/CodeEditorProjectSync.cs @@ -0,0 +1,59 @@ +// Unity C# reference source +// Copyright (c) Unity Technologies. For terms of use, see +// https://unity3d.com/legal/licenses/Unity_Reference_Only_License + +using System; +using Unity.CodeEditor; +using UnityEngine; +using UnityEngine.Scripting; +using UnityEditorInternal; + +namespace UnityEditor +{ + internal class CodeEditorProjectSync : AssetPostprocessor + { + class BuildTargetChangedHandler : Build.IActiveBuildTargetChanged + { + public int callbackOrder => 0; + + public void OnActiveBuildTargetChanged(BuildTarget oldTarget, BuildTarget newTarget) + { + CodeEditor.Editor.Current.SyncAll(); + } + } + + [RequiredByNativeCode] + public static void SyncEditorProject() + { + CodeEditor.Editor.Current.SyncAll(); + } + + // For the time being this doesn't use the callback + public static void PostprocessSyncProject( + string[] importedAssets, + string[] addedAssets, + string[] deletedAssets, + string[] movedAssets, + string[] movedFromAssetPaths) + { + CodeEditor.Editor.Current.SyncIfNeeded(addedAssets, deletedAssets, movedAssets, movedFromAssetPaths, importedAssets); + } + + [MenuItem("Assets/Open C# Project")] + static void SyncAndOpenSolution() + { + // Ensure that the mono islands are up-to-date + AssetDatabase.Refresh(); + CodeEditor.Editor.Current.SyncAll(); + OpenProjectFileUnlessInBatchMode(); + } + + static void OpenProjectFileUnlessInBatchMode() + { + if (InternalEditorUtility.inBatchMode) + return; + + CodeEditor.Editor.Current.OpenProject(); + } + } +} diff --git a/Editor/Mono/CodeEditor/DefaultExternalCodeEditor.cs b/Editor/Mono/CodeEditor/DefaultExternalCodeEditor.cs new file mode 100644 index 0000000000..e35b8f24a4 --- /dev/null +++ b/Editor/Mono/CodeEditor/DefaultExternalCodeEditor.cs @@ -0,0 +1,104 @@ +// Unity C# reference source +// Copyright (c) Unity Technologies. For terms of use, see +// https://unity3d.com/legal/licenses/Unity_Reference_Only_License + +using System.Diagnostics; +using System.IO; +using Unity.CodeEditor; +using UnityEngine; + +namespace UnityEditor +{ + internal class DefaultExternalCodeEditor : IExternalCodeEditor + { + static readonly GUIContent k_ResetArguments = EditorGUIUtility.TrTextContent("Reset argument"); + string m_ChosenInstallation; + const string k_ArgumentKey = "kScriptEditorArgs"; + const string k_DefaultArgument = "$(File)"; + + string Arguments + { + get + { + // Starting in Unity 5.5, we support setting script editor arguments on OSX and + // use then when opening the script editor. + // Before Unity 5.5, we would still save the default script editor args in EditorPrefs, + // even though we never used them. This means that the user potentially has some + // script editor args saved and once he upgrades to 5.5, they will be used when + // open the script editor. Which unintended and causes a regression in behaviour. + // So on OSX we change the key for per application for script editor args, + // to avoid reading the one from previous versions. + // The year 2021: Delete mac hack. + if (Application.platform == RuntimePlatform.OSXEditor) + { + var oldMac = EditorPrefs.GetString("kScriptEditorArgs_" + m_ChosenInstallation); + if (!string.IsNullOrEmpty(oldMac)) + { + EditorPrefs.SetString(k_ArgumentKey, oldMac); + } + } + + return EditorPrefs.GetString(k_ArgumentKey + m_ChosenInstallation, k_DefaultArgument); + } + set + { + if (Application.platform == RuntimePlatform.OSXEditor) + { + EditorPrefs.SetString("kScriptEditorArgs_" + m_ChosenInstallation, value); + } + + EditorPrefs.SetString(k_ArgumentKey + m_ChosenInstallation, value); + } + } + public CodeEditor.Installation[] Installations { get; } + public bool TryGetInstallationForPath(string editorPath, out CodeEditor.Installation installation) + { + installation = new CodeEditor.Installation + { + Name = Path.GetFileNameWithoutExtension(editorPath), + Path = editorPath + }; + return true; + } + + public void OnGUI() + { + Arguments = EditorGUILayout.TextField("External Script Editor Args", Arguments); + if (GUILayout.Button(k_ResetArguments, GUILayout.Width(120))) + { + Arguments = k_DefaultArgument; + } + } + + public void SyncIfNeeded(string[] addedFiles, string[] deletedFiles, string[] movedFiles, string[] movedFromFiles, string[] importedFiles) + { + } + + public void SyncAll() + { + } + + public void Initialize(string editorInstallationPath) + { + m_ChosenInstallation = editorInstallationPath; + } + + public bool OpenProject(string path, int line, int column) + { + string applicationPath = EditorPrefs.GetString("kScriptsDefaultApp"); + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = applicationPath, + Arguments = string.IsNullOrEmpty(applicationPath) ? "" : CodeEditor.ParseArgument(Arguments, path, line, column), + WindowStyle = ProcessWindowStyle.Hidden, + CreateNoWindow = true, + UseShellExecute = true, + } + }; + var result = process.Start(); + return result; + } + } +} diff --git a/Editor/Mono/CodeEditor/IExternalCodeEditor.cs b/Editor/Mono/CodeEditor/IExternalCodeEditor.cs new file mode 100644 index 0000000000..3c2090bc8b --- /dev/null +++ b/Editor/Mono/CodeEditor/IExternalCodeEditor.cs @@ -0,0 +1,17 @@ +// Unity C# reference source +// Copyright (c) Unity Technologies. For terms of use, see +// https://unity3d.com/legal/licenses/Unity_Reference_Only_License + +namespace Unity.CodeEditor +{ + public interface IExternalCodeEditor + { + CodeEditor.Installation[] Installations { get; } + bool TryGetInstallationForPath(string editorPath, out CodeEditor.Installation installation); + void OnGUI(); + void SyncIfNeeded(string[] addedFiles, string[] deletedFiles, string[] movedFiles, string[] movedFromFiles, string[] importedFiles); + void SyncAll(); + void Initialize(string editorInstallationPath); + bool OpenProject(string filePath = "", int line = -1, int column = -1); + } +} diff --git a/Editor/Mono/CodeEditor/SyncVS.cs b/Editor/Mono/CodeEditor/SyncVS.cs new file mode 100644 index 0000000000..800284f227 --- /dev/null +++ b/Editor/Mono/CodeEditor/SyncVS.cs @@ -0,0 +1,59 @@ +// Unity C# reference source +// Copyright (c) Unity Technologies. For terms of use, see +// https://unity3d.com/legal/licenses/Unity_Reference_Only_License + +using System; +using System.Security.Cryptography; +using System.Text; + +namespace UnityEditor +{ + class SyncVS + { + public static void SyncSolution() + { + // TODO: Rider and possibly other code editors, use reflection to call this method. + // To avoid conflicts and null reference exception, this is left as a dummy method. + Unity.CodeEditor.CodeEditor.Editor.Current.SyncAll(); + } + } + + namespace VisualStudioIntegration + { + public static class SolutionGuidGenerator + { + public static string GuidForProject(string projectName) + { + return ComputeGuidHashFor(projectName + "salt"); + } + + public static string GuidForSolution(string projectName, string sourceFileExtension) + { + if (sourceFileExtension.ToLower() == "cs") + // GUID for a C# class library: http://www.codeproject.com/Reference/720512/List-of-Visual-Studio-Project-Type-GUIDs + return "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"; + return ComputeGuidHashFor(projectName); + } + + private static string ComputeGuidHashFor(string input) + { + var hash = MD5.Create().ComputeHash(Encoding.Default.GetBytes(input)); + return HashAsGuid(HashToString(hash)); + } + + private static string HashAsGuid(string hash) + { + var guid = hash.Substring(0, 8) + "-" + hash.Substring(8, 4) + "-" + hash.Substring(12, 4) + "-" + hash.Substring(16, 4) + "-" + hash.Substring(20, 12); + return guid.ToUpper(); + } + + private static string HashToString(byte[] bs) + { + var sb = new StringBuilder(); + foreach (byte b in bs) + sb.Append(b.ToString("x2")); + return sb.ToString(); + } + } + } +} diff --git a/Editor/Mono/ContainerWindow.cs b/Editor/Mono/ContainerWindow.cs index 7e6a68192e..16c1e125b4 100644 --- a/Editor/Mono/ContainerWindow.cs +++ b/Editor/Mono/ContainerWindow.cs @@ -420,8 +420,12 @@ private bool TitleBarButton(GUIStyle style) } // Snapping windows - static Vector2 s_LastDragMousePos; - float startDragDpi; + private static Vector2 s_LastDragMousePos; + private float startDragDpi; + + // Indicates that we are using the native title bar caption dragging. + private bool m_DraggingNativeTitleBarCaption = false; + private void DragTitleBar(Rect titleBarRect) { int id = GUIUtility.GetControlID(FocusType.Passive); @@ -430,30 +434,33 @@ private void DragTitleBar(Rect titleBarRect) switch (evt.GetTypeForControl(id)) { case EventType.Repaint: + if (m_DraggingNativeTitleBarCaption) + m_DraggingNativeTitleBarCaption = false; EditorGUIUtility.AddCursorRect(titleBarRect, MouseCursor.Arrow); break; case EventType.MouseDown: // If the mouse is inside the title bar rect, we say that we're the hot control if (titleBarRect.Contains(evt.mousePosition) && GUIUtility.hotControl == 0 && evt.button == 0) { - GUIUtility.hotControl = id; - if (Application.platform != RuntimePlatform.WindowsEditor) + if (Application.platform == RuntimePlatform.WindowsEditor) { - s_LastDragMousePos = evt.mousePosition; - startDragDpi = GUIUtility.pixelsPerPoint; + Event.current.Use(); + m_DraggingNativeTitleBarCaption = true; + SendCaptionEvent(m_DraggingNativeTitleBarCaption); } else { - SendCaptionEvent(true); + GUIUtility.hotControl = id; + Event.current.Use(); + s_LastDragMousePos = evt.mousePosition; + startDragDpi = GUIUtility.pixelsPerPoint; + Unsupported.SetAllowCursorLock(false, Unsupported.DisallowCursorLockReasons.SizeMove); } - - Event.current.Use(); - Unsupported.SetAllowCursorLock(false, Unsupported.DisallowCursorLockReasons.SizeMove); } break; case EventType.MouseUp: - if (Application.platform == RuntimePlatform.WindowsEditor) - SendCaptionEvent(false); + if (m_DraggingNativeTitleBarCaption) + break; if (GUIUtility.hotControl == id) { @@ -463,6 +470,9 @@ private void DragTitleBar(Rect titleBarRect) } break; case EventType.MouseDrag: + if (m_DraggingNativeTitleBarCaption) + break; + if (GUIUtility.hotControl == id) { Vector2 mousePos = evt.mousePosition; diff --git a/Editor/Mono/EditorApplication.cs b/Editor/Mono/EditorApplication.cs index cfcdfa60b5..09d1fba52b 100644 --- a/Editor/Mono/EditorApplication.cs +++ b/Editor/Mono/EditorApplication.cs @@ -10,6 +10,7 @@ using UnityEngine.Events; using UnityEngine.Scripting; using UnityEditorInternal; +using UnityEngine.TestTools; namespace UnityEditor { @@ -37,7 +38,7 @@ public enum PauseState internal class ApplicationTitleDescriptor { - public ApplicationTitleDescriptor(string projectName, string unityVersion, string activeSceneName, string licenseType, bool previewPackageInUse, string targetName) + public ApplicationTitleDescriptor(string projectName, string unityVersion, string activeSceneName, string licenseType, bool previewPackageInUse, string targetName, bool codeCoverageEnabled) { title = ""; this.projectName = projectName; @@ -46,6 +47,7 @@ public ApplicationTitleDescriptor(string projectName, string unityVersion, strin this.licenseType = licenseType; this.previewPackageInUse = previewPackageInUse; this.targetName = targetName; + this.codeCoverageEnabled = codeCoverageEnabled; } public string title; @@ -55,6 +57,7 @@ public ApplicationTitleDescriptor(string projectName, string unityVersion, strin public string licenseType { get; private set; } public bool previewPackageInUse { get; private set; } public string targetName { get; private set; } + public bool codeCoverageEnabled { get; private set; } } public sealed partial class EditorApplication @@ -244,7 +247,7 @@ internal static string GetDefaultMainWindowTitle(ApplicationTitleDescriptor desc ? $"{desc.activeSceneName} - {desc.projectName}" : $"{desc.projectName} - {desc.activeSceneName}"; - // FUTURE: "preview packages in use" and the build target info do not belong in the title bar. they + // FUTURE: [PREVIEW PACKAGES IN USE], [CODE COVERAGE] and the build target info do not belong in the title bar. they // are there now because we want them to be always-visible to user, which normally would be a) buildconfig // bar or b) status bar, but we don't have a) and our b) needs work to support such a thing. @@ -264,6 +267,11 @@ internal static string GetDefaultMainWindowTitle(ApplicationTitleDescriptor desc title += " " + L10n.Tr("[PREVIEW PACKAGES IN USE]"); } + if (desc.codeCoverageEnabled) + { + title += " " + L10n.Tr("[CODE COVERAGE]"); + } + return title; } @@ -282,7 +290,8 @@ internal static string BuildMainWindowTitle() activeSceneName, GetLicenseType(), isPreviewPackageInUse, - BuildPipeline.GetBuildTargetGroupDisplayName(BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget)) + BuildPipeline.GetBuildTargetGroupDisplayName(BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget)), + Coverage.enabled ); desc.title = GetDefaultMainWindowTitle(desc); diff --git a/Editor/Mono/EditorGUI.cs b/Editor/Mono/EditorGUI.cs index 10237b845b..e89862e486 100644 --- a/Editor/Mono/EditorGUI.cs +++ b/Editor/Mono/EditorGUI.cs @@ -2406,7 +2406,7 @@ internal static GenericMenu FillPropertyContextMenu(SerializedProperty property, info.properties = properties; info.assetPath = AssetDatabase.GetAssetPath(sourceObject); GameObject rootObject = PrefabUtility.GetRootGameObject(sourceObject); - if (!PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(rootObject)) + if (!PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(rootObject) || EditorUtility.IsPersistent(targetObject)) pm.AddDisabledItem(menuItemContent); else pm.AddItem(menuItemContent, false, TargetChoiceHandler.ApplyPrefabPropertyOverride, info); @@ -5056,16 +5056,20 @@ internal static void RemovedComponentTitlebar(Rect position, GameObject instance GenericMenu menu = new GenericMenu(); PrefabUtility.HandleApplyRevertMenuItems( "Removed Component", - sourceComponent, + instanceGo, (menuItemContent, sourceObject) => { TargetChoiceHandler.ObjectInstanceAndSourceInfo info = new TargetChoiceHandler.ObjectInstanceAndSourceInfo(); info.instanceObject = instanceGo; Component componentToRemove = sourceComponent; - while (componentToRemove != sourceObject) + while (componentToRemove.gameObject != sourceObject) + { componentToRemove = PrefabUtility.GetCorrespondingObjectFromSource(componentToRemove); + if (componentToRemove == null) + return; + } info.correspondingObjectInSource = componentToRemove; - if (!PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(componentToRemove)) + if (!PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(componentToRemove) || EditorUtility.IsPersistent(instanceGo)) menu.AddDisabledItem(menuItemContent); else menu.AddItem(menuItemContent, false, TargetChoiceHandler.ApplyPrefabRemovedComponent, info); diff --git a/Editor/Mono/EditorGUIUtility.cs b/Editor/Mono/EditorGUIUtility.cs index d651aede68..71b63b1c6d 100644 --- a/Editor/Mono/EditorGUIUtility.cs +++ b/Editor/Mono/EditorGUIUtility.cs @@ -1091,7 +1091,7 @@ internal static float contextWidth } } - public static float currentViewWidth => GUIView.current.position.width; + public static float currentViewWidth => GUIView.current ? GUIView.current.position.width : 0; public static float labelWidth { diff --git a/Editor/Mono/EditorSettings.bindings.cs b/Editor/Mono/EditorSettings.bindings.cs index c985e2c3f7..2850f023f6 100644 --- a/Editor/Mono/EditorSettings.bindings.cs +++ b/Editor/Mono/EditorSettings.bindings.cs @@ -5,7 +5,6 @@ using System; using System.Linq; using System.Runtime.InteropServices; -using UnityEditor.VisualStudioIntegration; using UnityEngine.Bindings; using Object = UnityEngine.Object; @@ -193,7 +192,7 @@ public static string[] projectGenerationUserExtensions public static string[] projectGenerationBuiltinExtensions { - get { return SolutionSynchronizer.BuiltinSupportedExtensions.Keys.ToArray(); } + get { return new[] { "cs", "uxml", "uss", "shader", "compute", "cginc", "hlsl", "glslinc", "template" }; } } internal static extern string Internal_ProjectGenerationUserExtensions diff --git a/Editor/Mono/EditorUtility.bindings.cs b/Editor/Mono/EditorUtility.bindings.cs index d204d99db2..900393e4b2 100644 --- a/Editor/Mono/EditorUtility.bindings.cs +++ b/Editor/Mono/EditorUtility.bindings.cs @@ -53,11 +53,13 @@ public static bool DisplayDialog(string title, string message, string ok) public static extern bool IsPersistent(Object target); public static extern string SaveFilePanel(string title, string directory, string defaultName, string extension); public static extern int NaturalCompare(string a, string b); - public static extern void SetDirty([NotNull] Object target); public static extern Object InstanceIDToObject(int instanceID); public static extern void CompressTexture([NotNull] Texture2D texture, TextureFormat format, int quality); public static extern void CompressCubemapTexture([NotNull] Cubemap texture, TextureFormat format, int quality); + [FreeFunction("EditorUtility::SetDirtyObjectOrScene")] + public static extern void SetDirty([NotNull] Object target); + [FreeFunction("InvokeDiffTool")] public static extern string InvokeDiffTool(string leftTitle, string leftFile, string rightTitle, string rightFile, string ancestorTitle, string ancestorFile); diff --git a/Editor/Mono/EditorUtility.cs b/Editor/Mono/EditorUtility.cs index 5500518084..373b091d44 100644 --- a/Editor/Mono/EditorUtility.cs +++ b/Editor/Mono/EditorUtility.cs @@ -347,7 +347,7 @@ internal static void DisplayObjectContextMenu(Rect position, Object[] context, i info.instanceObject = targetComponent; info.assetPath = AssetDatabase.GetAssetPath(sourceGo); GameObject rootObject = PrefabUtility.GetRootGameObject(sourceGo); - if (!PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(rootObject)) + if (!PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(rootObject) || EditorUtility.IsPersistent(instanceGo)) pm.AddDisabledItem(menuItemContent); else pm.AddItem(menuItemContent, false, TargetChoiceHandler.ApplyPrefabAddedComponent, info); @@ -387,7 +387,7 @@ internal static void DisplayObjectContextMenu(Rect position, Object[] context, i info.instanceObject = targetObject; info.assetPath = AssetDatabase.GetAssetPath(sourceObject); GameObject rootObject = PrefabUtility.GetRootGameObject(sourceObject); - if (!PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(rootObject)) + if (!PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(rootObject) || EditorUtility.IsPersistent(targetObject)) pm.AddDisabledItem(menuItemContent); else pm.AddItem(menuItemContent, false, TargetChoiceHandler.ApplyPrefabObjectOverride, info); diff --git a/Editor/Mono/EditorWindow.cs b/Editor/Mono/EditorWindow.cs index 9080e593df..27d4491ff9 100644 --- a/Editor/Mono/EditorWindow.cs +++ b/Editor/Mono/EditorWindow.cs @@ -757,7 +757,17 @@ public static T GetWindow(string title, bool focus, params System.Type[] desi return win; } - win = CreateInstance(); + return CreateWindow(title, desiredDockNextTo); + } + + public static T CreateWindow(params System.Type[] desiredDockNextTo) where T : EditorWindow + { + return CreateWindow(null, desiredDockNextTo); + } + + public static T CreateWindow(string title, params System.Type[] desiredDockNextTo) where T : EditorWindow + { + T win = CreateInstance(); if (title != null) win.titleContent = new GUIContent(title); diff --git a/Editor/Mono/GUI/AboutWindow.cs b/Editor/Mono/GUI/AboutWindow.cs index 4ae1d5e2d0..e2bd34a49d 100644 --- a/Editor/Mono/GUI/AboutWindow.cs +++ b/Editor/Mono/GUI/AboutWindow.cs @@ -4,10 +4,6 @@ using UnityEngine; using System; -using System.Collections; -using System.Collections.Generic; -using UnityEditor; -using UnityEditor.VisualStudioIntegration; using UnityEditorInternal; namespace UnityEditor @@ -150,9 +146,6 @@ public void OnGUI() GUILayout.BeginVertical(); GUILayout.FlexibleSpace(); - var VSTUlabel = UnityVSSupport.GetAboutWindowLabel(); - if (VSTUlabel.Length > 0) - GUILayout.Label(VSTUlabel, "MiniLabel"); GUILayout.Label(InternalEditorUtility.GetUnityCopyright(), "MiniLabel"); GUILayout.EndVertical(); GUILayout.Space(10); diff --git a/Editor/Mono/GUI/ReorderableList.cs b/Editor/Mono/GUI/ReorderableList.cs index 66b15b6112..63c730632f 100644 --- a/Editor/Mono/GUI/ReorderableList.cs +++ b/Editor/Mono/GUI/ReorderableList.cs @@ -31,6 +31,7 @@ public class ReorderableList public delegate void ChangedCallbackDelegate(ReorderableList list); public delegate bool CanRemoveCallbackDelegate(ReorderableList list); public delegate bool CanAddCallbackDelegate(ReorderableList list); + public delegate void DragCallbackDelegate(ReorderableList list); // draw callbacks @@ -51,6 +52,7 @@ public class ReorderableList public AddCallbackDelegate onAddCallback; public AddDropdownCallbackDelegate onAddDropdownCallback; public RemoveCallbackDelegate onRemoveCallback; + public DragCallbackDelegate onMouseDragCallback; public SelectCallbackDelegate onMouseUpCallback; public CanRemoveCallbackDelegate onCanRemoveCallback; public CanAddCallbackDelegate onCanAddCallback; @@ -707,6 +709,8 @@ private void DoDraggingAndSelection(Rect listRect) // Set m_Dragging state on first MouseDrag event after we got hotcontrol (to prevent animating elements when deleting elements by context menu) m_Dragging = true; + onMouseDragCallback(this); + // if we are dragging, update the position UpdateDraggedY(listRect); evt.Use(); diff --git a/Editor/Mono/GUI/TypeSelectionList.cs b/Editor/Mono/GUI/TypeSelectionList.cs index a5c560bac4..d02cec9b74 100644 --- a/Editor/Mono/GUI/TypeSelectionList.cs +++ b/Editor/Mono/GUI/TypeSelectionList.cs @@ -23,6 +23,9 @@ public TypeSelectionList(Object[] objects) foreach (Object o in objects) { string typeName = ObjectNames.GetTypeName(o); + if (o is GameObject && EditorUtility.IsPersistent(o)) + typeName = "Prefab"; + if (!types.ContainsKey(typeName)) types[typeName] = new List(); types[typeName].Add(o); @@ -48,7 +51,10 @@ public TypeSelection(string typeName, Object[] objects) System.Diagnostics.Debug.Assert(objects != null && objects.Length >= 1); this.objects = objects; label = new GUIContent(objects.Length + " " + ObjectNames.NicifyVariableName(typeName) + (objects.Length > 1 ? "s" : "")); - label.image = AssetPreview.GetMiniTypeThumbnail(objects[0]); + if (objects[0] is GameObject) + label.image = EditorUtility.IsPersistent(objects[0]) ? PrefabUtility.GameObjectStyles.prefabIcon : PrefabUtility.GameObjectStyles.gameObjectIcon; + else + label.image = AssetPreview.GetMiniTypeThumbnail(objects[0]); } public int CompareTo(object o) diff --git a/Editor/Mono/ImportSettings/AnimationClipInfoProperties.cs b/Editor/Mono/ImportSettings/AnimationClipInfoProperties.cs index b98bc4aa54..887621b790 100644 --- a/Editor/Mono/ImportSettings/AnimationClipInfoProperties.cs +++ b/Editor/Mono/ImportSettings/AnimationClipInfoProperties.cs @@ -62,6 +62,11 @@ SerializedProperty Get(string property) public SerializedProperty bodyMaskProperty { get { return Get("bodyMask"); } } public SerializedProperty transformMaskProperty { get { return Get("transformMask"); } } + public void ApplyModifiedProperties() + { + m_Property.serializedObject.ApplyModifiedProperties(); + } + public bool MaskNeedsUpdating() { AvatarMask mask = maskSource; diff --git a/Editor/Mono/Inspector/AnimationClipEditor.cs b/Editor/Mono/Inspector/AnimationClipEditor.cs index 82dbb67f53..d27b66a2bc 100644 --- a/Editor/Mono/Inspector/AnimationClipEditor.cs +++ b/Editor/Mono/Inspector/AnimationClipEditor.cs @@ -3,11 +3,8 @@ // https://unity3d.com/legal/licenses/Unity_Reference_Only_License using UnityEngine; -using UnityEditor; using UnityEditor.Animations; -using UnityEditor.AnimatedValues; using System; -using System.Reflection; using System.Collections.Generic; using System.Linq; using Object = UnityEngine.Object; @@ -1674,6 +1671,7 @@ public void EventLineContextMenuAdd(object obj) EventModificationContextMenuObject context = (EventModificationContextMenuObject)obj; context.m_Info.AddEvent(context.m_Time); + context.m_Info.ApplyModifiedProperties(); SelectEvent(context.m_Info.GetEvents(), context.m_Info.GetEventCount() - 1, context.m_Info); } @@ -1693,6 +1691,7 @@ public void EventLineContextMenuDelete(object obj) { context.m_Info.RemoveEvent(context.m_Index); } + context.m_Info.ApplyModifiedProperties(); } private void CheckRectsOnMouseMove(Rect eventLineRect, AnimationEvent[] events, Rect[] hitRects) diff --git a/Editor/Mono/Inspector/EditorElement.cs b/Editor/Mono/Inspector/EditorElement.cs index 6b4aabd2a7..4a07c56d3c 100644 --- a/Editor/Mono/Inspector/EditorElement.cs +++ b/Editor/Mono/Inspector/EditorElement.cs @@ -51,6 +51,18 @@ private bool IsEditorValid() internal InspectorElement m_InspectorElement { get; private set; } IMGUIContainer m_Footer; + static class Styles + { + public static GUIStyle importedObjectsHeaderStyle = new GUIStyle("IN BigTitle"); + + static Styles() + { + importedObjectsHeaderStyle.font = EditorStyles.label.font; + importedObjectsHeaderStyle.fontSize = EditorStyles.label.fontSize; + importedObjectsHeaderStyle.alignment = TextAnchor.UpperLeft; + } + } + internal EditorElement(int editorIndex, InspectorWindow iw) { m_EditorIndex = editorIndex; @@ -267,11 +279,9 @@ bool DrawEditorLargeHeader(ref bool wasVisible) var importedObjectBarRect = GUILayoutUtility.GetRect(16, 16); importedObjectBarRect.height = 17; - // Clip the label to avoid a black border at the bottom - GUI.BeginGroup(importedObjectBarRect); - GUI.Label(new Rect(0, 0, importedObjectBarRect.width, importedObjectBarRect.height), - "Imported Object", "OL Title"); - GUI.EndGroup(); + var headerText = m_Editors[0] is PrefabImporterEditor ? "Root in Prefab Asset" : "Imported Object"; + GUILayout.Label(headerText, Styles.importedObjectsHeaderStyle, GUILayout.ExpandWidth(true)); + GUILayout.Space(-7f); // Ensures no spacing between this header and the next header } // Header diff --git a/Editor/Mono/Inspector/GameObjectInspector.cs b/Editor/Mono/Inspector/GameObjectInspector.cs index 63981c5b21..daeebdf02f 100644 --- a/Editor/Mono/Inspector/GameObjectInspector.cs +++ b/Editor/Mono/Inspector/GameObjectInspector.cs @@ -313,7 +313,7 @@ internal bool DrawInspector() private void DoPrefabButtons() { - if (!m_IsPrefabInstanceAnyRoot) + if (!m_IsPrefabInstanceAnyRoot || m_IsAsset) return; using (new EditorGUI.DisabledScope(m_PlayModeObjects)) diff --git a/Editor/Mono/Inspector/InspectorWindow.cs b/Editor/Mono/Inspector/InspectorWindow.cs index 85d6275b65..1982f54ce1 100644 --- a/Editor/Mono/Inspector/InspectorWindow.cs +++ b/Editor/Mono/Inspector/InspectorWindow.cs @@ -509,9 +509,13 @@ void ExtractPrefabComponents() return; if (m_Tracker.activeEditors[0].targets.Length != 1) return; + GameObject go = m_Tracker.activeEditors[0].target as GameObject; + if (go == null && m_Tracker.activeEditors[0] is PrefabImporterEditor) + go = m_Tracker.activeEditors[1].target as GameObject; if (go == null) return; + GameObject sourceGo = PrefabUtility.GetCorrespondingConnectedObjectFromSource(go); if (sourceGo == null) return; @@ -678,6 +682,12 @@ internal virtual void RebuildContentsContainers() var labelMustBeAdded = m_MultiEditLabel.parent != editorsElement; + // The PrefabImporterEditor can hide its imported objects if it detects missing scripts. In this case + // do not add the multi editing warning + var assetImporter = GetAssetImporter(editors); + if (assetImporter != null && !assetImporter.showImportedObject) + labelMustBeAdded = false; + if (tracker.hasComponentsWhichCannotBeMultiEdited) { Profiler.BeginSample("InspectorWindow.RebuildContentsContainers()::hasComponentsWhichCannotBeMultiEdited"); @@ -1378,13 +1388,26 @@ void DrawEditors(Editor[] editors) if (editors.Length > 0 && editors[0].GetInstanceID() != m_LastInitialEditorInstanceID) OnTrackerRebuilt(); + if (m_RemovedComponents == null) + ExtractPrefabComponents(); // needed after assembly reload (due to HashSet not being serializable) + + bool checkForRemovedComponents = m_ComponentsInPrefabSource != null; int prefabComponentIndex = -1; + int targetGameObjectIndex = -1; + GameObject targetGameObject = null; + if (checkForRemovedComponents) + { + targetGameObjectIndex = editors[0] is PrefabImporterEditor ? 1 : 0; + targetGameObject = (GameObject)editors[targetGameObjectIndex].target; + } for (int editorIndex = 0; editorIndex < editors.Length; editorIndex++) { VisualElement prefabsComponentElement = new VisualElement() { name = "PrefabComponentElement" }; - if (m_ComponentsInPrefabSource != null && editorIndex != 0) + if (checkForRemovedComponents && editorIndex > targetGameObjectIndex) { + if (prefabComponentIndex == -1) + prefabComponentIndex = 0; while (prefabComponentIndex < m_ComponentsInPrefabSource.Length) { Object target = editors[editorIndex].target; @@ -1396,15 +1419,13 @@ void DrawEditors(Editor[] editors) if (correspondingSource == nextInSource) break; - AddRemovedPrefabComponentElement(editors, nextInSource, prefabsComponentElement); + AddRemovedPrefabComponentElement(targetGameObject, nextInSource, prefabsComponentElement); } - prefabComponentIndex++; } + prefabComponentIndex++; } - prefabComponentIndex++; - if (ShouldCullEditor(editors, editorIndex)) { editors[editorIndex].isInspectorDirty = false; @@ -1433,13 +1454,13 @@ void DrawEditors(Editor[] editors) } // Make sure to display any remaining removed components that come after the last component on the GameObject. - if (m_ComponentsInPrefabSource != null) + if (checkForRemovedComponents) { VisualElement prefabsComponentElement = new VisualElement() { name = "RemainingPrefabComponentElement" }; while (prefabComponentIndex < m_ComponentsInPrefabSource.Length) { Component nextInSource = m_ComponentsInPrefabSource[prefabComponentIndex]; - AddRemovedPrefabComponentElement(editors, nextInSource, prefabsComponentElement); + AddRemovedPrefabComponentElement(targetGameObject, nextInSource, prefabsComponentElement); prefabComponentIndex++; } @@ -1452,9 +1473,8 @@ void DrawEditors(Editor[] editors) } } - void AddRemovedPrefabComponentElement(Editor[] editors, Component nextInSource, VisualElement element) + void AddRemovedPrefabComponentElement(GameObject targetGameObject, Component nextInSource, VisualElement element) { - var targetGameObject = editors[0].target as GameObject; if (ShouldDisplayRemovedComponent(targetGameObject, nextInSource)) { string missingComponentTitle = ObjectNames.GetInspectorTitle(nextInSource); @@ -1567,7 +1587,7 @@ internal bool ShouldCullEditor(Editor[] editors, int editorIndex) // Let asset importers decide if the imported object should be shown or not if (m_InspectorMode == InspectorMode.Normal && editorIndex != 0) { - AssetImporterEditor importerEditor = editors[0] as AssetImporterEditor; + AssetImporterEditor importerEditor = GetAssetImporter(editors); if (importerEditor != null && !importerEditor.showImportedObject) return true; } @@ -1607,10 +1627,23 @@ void DrawSelectionPickerList() EditorGUIUtility.SetIconSize(oldSize); } + AssetImporterEditor GetAssetImporter(Editor[] editors) + { + if (editors == null || editors.Length == 0) + return null; + + return editors[0] as AssetImporterEditor; + } + private void AddComponentButton(Editor[] editors) { + // Don't show the Add Component button if we are not showing imported objects for Asset Importers + var assetImporter = GetAssetImporter(editors); + if (assetImporter != null && !assetImporter.showImportedObject) + return; + Editor editor = InspectorWindowUtils.GetFirstNonImportInspectorEditor(editors); - if (editor != null && editor.target != null && editor.target is GameObject && editor.IsEnabled() && !EditorUtility.IsPersistent(editor.target)) + if (editor != null && editor.target != null && editor.target is GameObject && editor.IsEnabled()) { EditorGUILayout.BeginHorizontal(GUIContent.none, GUIStyle.none, GUILayout.Height(kAddComponentButtonHeight)); { diff --git a/Editor/Mono/InternalEditorUtility.bindings.cs b/Editor/Mono/InternalEditorUtility.bindings.cs index 07bc66aabf..221301c9f1 100644 --- a/Editor/Mono/InternalEditorUtility.bindings.cs +++ b/Editor/Mono/InternalEditorUtility.bindings.cs @@ -10,6 +10,7 @@ using UnityEngine.Bindings; using UnityEditor.Scripting.ScriptCompilation; using System.Globalization; +using Unity.CodeEditor; using TargetAttributes = UnityEditor.BuildTargetDiscovery.TargetAttributes; namespace UnityEditorInternal @@ -731,9 +732,10 @@ private static Bounds GetLocalBounds(GameObject gameObject) [FreeFunction("OpenScriptFile")] extern public static bool OpenFileAtLineExternal(string filename, int line, int column); + [Obsolete("Use CodeEditorUtility.Editor.Current.OpenProject()", false)] public static bool OpenFileAtLineExternal(string filename, int line) { - return OpenFileAtLineExternal(filename, line, 0); + return CodeEditor.Editor.Current.OpenProject(filename, line); } [FreeFunction("AssetDatabaseDeprecated::CanConnectToCacheServer")] diff --git a/Editor/Mono/PointEditor.cs b/Editor/Mono/PointEditor.cs index 0f801c963f..d709d6a6cc 100644 --- a/Editor/Mono/PointEditor.cs +++ b/Editor/Mono/PointEditor.cs @@ -175,8 +175,10 @@ public static bool SelectPoints(IEditablePoint points, Transform cloudTransform, // Go over all the points and add them if they are inside the rect for (int i = 0; i < points.Count; i++) { - var point = HandleUtility.WorldToGUIPoint(points.GetPosition(i)); - if (r.Contains(point)) + var point = HandleUtility.WorldToGUIPointWithDepth(points.GetPosition(i)); + + // the point has to be within the selection and in front of the camera + if (r.Contains(point) && point.z > 0.0f) { if (EditorGUI.actionKey) { diff --git a/Editor/Mono/Prefabs/PrefabImporterEditor.cs b/Editor/Mono/Prefabs/PrefabImporterEditor.cs index d31b55d9cd..1377abaa0a 100644 --- a/Editor/Mono/Prefabs/PrefabImporterEditor.cs +++ b/Editor/Mono/Prefabs/PrefabImporterEditor.cs @@ -6,6 +6,7 @@ using UnityEditor.Experimental.AssetImporters; using UnityEditor.Experimental.SceneManagement; using UnityEditor.SceneManagement; +using System.Collections.Generic; namespace UnityEditor { @@ -13,12 +14,164 @@ namespace UnityEditor [CanEditMultipleObjects] internal class PrefabImporterEditor : AssetImporterEditor { - static GUIContent s_OpenContent = EditorGUIUtility.TrTextContent("Open Prefab"); - static GUIContent s_BaseContent = EditorGUIUtility.TrTextContent("Base"); - static string s_LocalizedTitleMultiplePrefabs = L10n.Tr("Prefab Assets"); - static string s_LocalizedTitleSinglePrefab = L10n.Tr("Prefab Asset"); + static class Styles + { + public static GUIContent openContent = EditorGUIUtility.TrTextContent("Open Prefab"); + public static GUIContent openHelpText = EditorGUIUtility.TrTextContent("Open Prefab for full editing support."); + public static GUIContent missingScriptsHelpText = EditorGUIUtility.TrTextContent("Prefab has missing scripts. Open Prefab to fix the issue."); + public static GUIContent multiSelectionMissingScriptsHelpText = EditorGUIUtility.TrTextContent("Some of the selected Prefabs have missing scripts and needs to be fixed before editing them. Click to Open Prefab to fix the issue."); + public static GUIContent savingFailedHelpText = EditorGUIUtility.TrTextContent("Saving has failed. Check the Console window to get more insight into what needs to be fixed on the Prefab Asset.\n\nOpen Prefab to fix the issue."); + public static GUIContent baseContent = EditorGUIUtility.TrTextContent("Base"); + public static string localizedTitleMultiplePrefabs = L10n.Tr("Prefab Assets"); + public static string localizedTitleSinglePrefab = L10n.Tr("Prefab Asset"); + public static GUIStyle openButtonStyle = "AC Button"; + } int m_HasMixedBaseVariants = -1; + double m_NextUpdate; + List m_PrefabsWithMissingScript = new List(); + bool m_SavingHasFailed; + List m_TempComponentsResults = new List(); + + public override bool showImportedObject { get { return !hasMissingScripts; } } + + public override bool UseDefaultMargins() + { + return false; + } + + bool isTextFieldCaretShowing + { + get { return EditorGUI.IsEditingTextField() && !EditorGUIUtility.textFieldHasSelection; } + } + + bool readyToAutoSave + { + get { return !m_SavingHasFailed && !hasMissingScripts && GUIUtility.hotControl == 0 && !isTextFieldCaretShowing && !EditorApplication.isCompiling; } + } + + bool hasMissingScripts + { + get { return m_PrefabsWithMissingScript.Count > 0; } + } + + public override void OnEnable() + { + base.OnEnable(); + EditorApplication.update += Update; + } + + public override void OnDisable() + { + EditorApplication.update -= Update; + base.OnDisable(); + } + + protected override void Awake() + { + base.Awake(); + + foreach (var prefabAssetRoot in assetTargets) + { + if (PrefabUtility.HasInvalidComponent(prefabAssetRoot)) + { + m_PrefabsWithMissingScript.Add(AssetDatabase.GetAssetPath(prefabAssetRoot)); + } + } + m_PrefabsWithMissingScript.Sort(); + } + + void OnDestroy() + { + // Ensure to save unsaved changes (regardless of hotcontrol etc) + if (!m_SavingHasFailed && !hasMissingScripts) + SaveDirtyPrefabAssets(); + } + + void Update() + { + var time = EditorApplication.timeSinceStartup; + if (time > m_NextUpdate) + { + m_NextUpdate = time + 0.2; + + if (readyToAutoSave && HasDirtyPrefabAssets()) + SaveDirtyPrefabAssets(); + } + } + + // Internal for testing framework + internal void SaveDirtyPrefabAssets() + { + if (assetTargets == null) + return; + + if (assetTarget == null) + return; + + foreach (var asset in assetTargets) + { + // The asset could have been deleted when this method is called from OnDestroy(). + // E.g delete the selected prefab asset from the Project Browser. + if (asset == null) + continue; + + if (!EditorUtility.IsPersistent(asset)) + continue; + + var rootGameObject = (GameObject)asset; + if (IsDirty(rootGameObject)) + { + bool savedSuccesfully; + PrefabUtility.SavePrefabAsset(rootGameObject, out savedSuccesfully); + if (!savedSuccesfully) + { + string title = L10n.Tr("Saving Failed"); + string message = L10n.Tr("Check the Console window to get more insight into what needs to be fixed on the Prefab Asset.\n\nYou can open Prefab Mode to fix any issues on child GameObjects"); + EditorUtility.DisplayDialog(title, message, L10n.Tr("OK")); + + m_SavingHasFailed = true; + return; + } + } + } + } + + internal bool HasDirtyPrefabAssets() + { + if (assetTarget == null) + return false; + + // We just check one target since we assume that a multi-edit will + // always edit that target. So no need to spend resources on checking + // all targets in multiselection. + return IsDirty((GameObject)assetTarget); + } + + bool IsDirty(GameObject prefabAssetRoot) + { + if (prefabAssetRoot == null) + return false; + + if (EditorUtility.IsDirty(prefabAssetRoot)) + return true; + + // For Prefab Variant Asset we need to also check if the instance handle is dirty + // since this happens when the list of removed component changes + var instanceHandle = PrefabUtility.GetPrefabInstanceHandle(prefabAssetRoot); + if (instanceHandle != null) + if (EditorUtility.IsDirty(instanceHandle)) + return true; + + prefabAssetRoot.GetComponents(m_TempComponentsResults); + foreach (var component in m_TempComponentsResults) + { + if (EditorUtility.IsDirty(component)) + return true; + } + + return false; + } void CacheHasMixedBaseVariants() { @@ -43,16 +196,14 @@ void CacheHasMixedBaseVariants() protected override bool needsApplyRevert => false; - public override bool showImportedObject { get { return false; } } - internal override string targetTitle { get { if (assetTargets == null || assetTargets.Length == 1 || !m_AllowMultiObjectAccess) - return assetTarget != null ? assetTarget.name : s_LocalizedTitleSinglePrefab; + return assetTarget != null ? assetTarget.name + " (" + Styles.localizedTitleSinglePrefab + ")" : Styles.localizedTitleSinglePrefab; else - return assetTargets.Length + " " + s_LocalizedTitleMultiplePrefabs; + return assetTargets.Length + " " + Styles.localizedTitleMultiplePrefabs; } } @@ -64,7 +215,7 @@ internal override void OnHeaderControlsGUI() using (new EditorGUI.DisabledScope(true)) { CacheHasMixedBaseVariants(); - GUILayout.Label(s_BaseContent); + GUILayout.Label(Styles.baseContent); EditorGUI.showMixedValue = m_HasMixedBaseVariants == 1; EditorGUILayout.ObjectField(variantBase, typeof(GameObject), false); EditorGUI.showMixedValue = false; @@ -79,6 +230,8 @@ internal override void OnHeaderControlsGUI() public override void OnInspectorGUI() { + EditorGUILayout.BeginVertical(EditorStyles.inspectorFullWidthMargins); + // Allow opening prefab even if file is not open for edit. // For things with explicit save operations (scenes, prefabs) we allow editing // and handle the potential version control conflict at the time when the user saves. @@ -86,15 +239,63 @@ public override void OnInspectorGUI() GUI.enabled = true; using (new EditorGUI.DisabledScope(assetTargets.Length > 1)) { - if (GUILayout.Button(s_OpenContent)) + GUILayout.Space(10); + + EditorGUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + if (GUILayout.Button(Styles.openContent, Styles.openButtonStyle)) { // We only support opening one prefab at a time (so do not use 'targets') PrefabStageUtility.OpenPrefab(AssetDatabase.GetAssetPath(assetTarget), null, StageNavigationManager.Analytics.ChangeType.EnterViaAssetInspectorOpenButton); GUIUtility.ExitGUI(); } + GUILayout.FlexibleSpace(); + EditorGUILayout.EndHorizontal(); + + GUILayout.Space(5); + + if (!hasMissingScripts && !m_SavingHasFailed) + { + EditorGUILayout.HelpBox(Styles.openHelpText.text, MessageType.Info, true); + } } GUI.enabled = wasEnabled; + + if (hasMissingScripts) + { + if (assetTargets.Length > 1) + { + // List all assets that have missing scripts (but only if we have a multi-selection) + GUILayout.Space(5); + EditorGUILayout.HelpBox(Styles.multiSelectionMissingScriptsHelpText.text, MessageType.Warning, true); + using (new EditorGUILayout.HorizontalScope()) + { + GUILayout.Space(10); + + using (new EditorGUILayout.VerticalScope()) + { + foreach (var prefabAssetPath in m_PrefabsWithMissingScript) + { + if (GUILayout.Button(prefabAssetPath, EditorStyles.label)) + { + PrefabStageUtility.OpenPrefab(prefabAssetPath); + } + } + } + } + } + else + { + EditorGUILayout.HelpBox(Styles.missingScriptsHelpText.text, MessageType.Warning, true); + } + } + else if (m_SavingHasFailed) + { + EditorGUILayout.HelpBox(Styles.savingFailedHelpText.text, MessageType.Warning, true); + } + + EditorGUILayout.EndVertical(); } } } diff --git a/Editor/Mono/Prefabs/PrefabOverrides/PrefabOverride.cs b/Editor/Mono/Prefabs/PrefabOverrides/PrefabOverride.cs index 75941ca0a5..9f8e8a0e3e 100644 --- a/Editor/Mono/Prefabs/PrefabOverrides/PrefabOverride.cs +++ b/Editor/Mono/Prefabs/PrefabOverrides/PrefabOverride.cs @@ -49,7 +49,9 @@ internal void HandleApplyMenuItems(GenericMenu menu, GenericMenu.MenuFunction2 a menu.AddDisabledItem(menuItemContent); else menu.AddItem(menuItemContent, false, applyAction, prefabAssetPath); - }); + }, + false, + true); } } diff --git a/Editor/Mono/Prefabs/PrefabUtility.bindings.cs b/Editor/Mono/Prefabs/PrefabUtility.bindings.cs index 7ea7316f2a..dadd85a9b6 100644 --- a/Editor/Mono/Prefabs/PrefabUtility.bindings.cs +++ b/Editor/Mono/Prefabs/PrefabUtility.bindings.cs @@ -180,7 +180,7 @@ internal static GameObject CreateVariant(GameObject assetRoot, string path) extern private static GameObject SaveAsPrefabAssetAndConnect_Internal([NotNull] GameObject root, string path, out bool success); [StaticAccessor("PrefabUtilityBindings", StaticAccessorType.DoubleColon)] - extern private static GameObject SavePrefabAsset_Internal([NotNull] GameObject root); + extern private static GameObject SavePrefabAsset_Internal([NotNull] GameObject root, out bool success); internal static void AddGameObjectsToPrefabAndConnect(GameObject[] gameObjects, Object targetPrefab) { diff --git a/Editor/Mono/Prefabs/PrefabUtility.cs b/Editor/Mono/Prefabs/PrefabUtility.cs index b5092f6218..1d51fd2e78 100644 --- a/Editor/Mono/Prefabs/PrefabUtility.cs +++ b/Editor/Mono/Prefabs/PrefabUtility.cs @@ -286,7 +286,7 @@ private static void RegisterNewObjects(GameObject newHierarchy, HashSet hie } } - static void ThrowExceptionIfNotValidNonPersistentPrefabInstanceObject(Object prefabInstanceObject) + static void ThrowExceptionIfNotValidPrefabInstanceObject(Object prefabInstanceObject, bool isApply) { if (!(prefabInstanceObject is GameObject || prefabInstanceObject is Component)) throw new ArgumentException("Calling apply or revert methods on an object which is not a GameObject or Component is not supported.", nameof(prefabInstanceObject)); @@ -294,18 +294,21 @@ static void ThrowExceptionIfNotValidNonPersistentPrefabInstanceObject(Object pre throw new NullReferenceException("Cannot apply or revert object. Object is null."); if (!PrefabUtility.IsPartOfPrefabInstance(prefabInstanceObject)) throw new ArgumentException("Calling apply or revert methods on an object which is not part of a Prefab instance is not supported.", nameof(prefabInstanceObject)); - ThrowExceptionIfInstanceIsPersistent(prefabInstanceObject); + + // We support revert operations on Prefab Assets, but not apply operations. + if (isApply) + ThrowExceptionIfInstanceIsPersistent(prefabInstanceObject); } static void ThrowExceptionIfInstanceIsPersistent(Object prefabInstanceObject) { if (EditorUtility.IsPersistent(prefabInstanceObject)) - throw new ArgumentException("Calling apply or revert methods on an instance which is part of a Prefab Asset is not supported.", nameof(prefabInstanceObject)); + throw new ArgumentException("Calling apply methods on an instance which is part of a Prefab Asset is not supported.", nameof(prefabInstanceObject)); } public static void RevertPrefabInstance(GameObject instanceRoot, InteractionMode action) { - ThrowExceptionIfNotValidNonPersistentPrefabInstanceObject(instanceRoot); + ThrowExceptionIfNotValidPrefabInstanceObject(instanceRoot, false); bool isDisconnected = PrefabUtility.IsDisconnectedFromPrefabAsset(instanceRoot); @@ -337,7 +340,7 @@ public static void ApplyPrefabInstance(GameObject instanceRoot, InteractionMode { DateTime startTime = DateTime.UtcNow; - ThrowExceptionIfNotValidNonPersistentPrefabInstanceObject(instanceRoot); + ThrowExceptionIfNotValidPrefabInstanceObject(instanceRoot, true); GameObject prefabInstanceRoot = GetOutermostPrefabInstanceRoot(instanceRoot); var isDisconnected = GetPrefabInstanceHandle(prefabInstanceRoot) == null; @@ -397,7 +400,7 @@ public static void ApplyPropertyOverride(SerializedProperty instanceProperty, st DateTime startTime = DateTime.UtcNow; Object prefabInstanceObject = instanceProperty.serializedObject.targetObject; - ThrowExceptionIfNotValidNonPersistentPrefabInstanceObject(prefabInstanceObject); + ThrowExceptionIfNotValidPrefabInstanceObject(prefabInstanceObject, true); ApplyPropertyOverrides(prefabInstanceObject, instanceProperty, assetPath, true, action); @@ -497,13 +500,39 @@ static void ApplyPropertyOverrides(Object prefabInstanceObject, SerializedProper } } + // Ensure importing of saved Prefab Assets only kicks in after all Prefab Asset have been saved + AssetDatabase.StartAssetEditing(); + // Write modified value to prefab source object. for (int i = 0; i < serializedObjects.Count; i++) { - serializedObjects[i].ApplyModifiedProperties(); + if (serializedObjects[i].ApplyModifiedProperties()) + SaveChangesToPrefabFileIfPersistent(serializedObjects[i]); + if (action == InteractionMode.UserAction) Undo.FlushUndoRecordObjects(); // flush'es ensure that SavePrefab() on undo/redo on the source happens in the right order } + + AssetDatabase.StopAssetEditing(); + } + + static void SaveChangesToPrefabFileIfPersistent(SerializedObject serializedObject) + { + if (!EditorUtility.IsPersistent(serializedObject.targetObject)) + return; + + GameObject go = serializedObject.targetObject as GameObject; + if (go == null) + { + var cmp = serializedObject.targetObject as Component; + if (cmp != null) + go = cmp.gameObject; + } + + if (go != null) + { + SavePrefabAsset(go.transform.root.gameObject); + } } // Returns null if property is not part of array where whole array needs to be appled. @@ -670,7 +699,7 @@ static void ApplySingleProperty( public static void RevertPropertyOverride(SerializedProperty instanceProperty, InteractionMode action) { Object prefabInstanceObject = instanceProperty.serializedObject.targetObject; - ThrowExceptionIfNotValidNonPersistentPrefabInstanceObject(prefabInstanceObject); + ThrowExceptionIfNotValidPrefabInstanceObject(prefabInstanceObject, false); instanceProperty.prefabOverride = false; // Because prefabOverride changed ApplyModifiedProperties will do a prefab merge causing the revert. @@ -684,7 +713,7 @@ public static void ApplyObjectOverride(Object instanceComponentOrGameObject, str { DateTime startTime = DateTime.UtcNow; - ThrowExceptionIfNotValidNonPersistentPrefabInstanceObject(instanceComponentOrGameObject); + ThrowExceptionIfNotValidPrefabInstanceObject(instanceComponentOrGameObject, true); ApplyPropertyOverrides(instanceComponentOrGameObject, null, assetPath, false, action); @@ -700,7 +729,7 @@ public static void ApplyObjectOverride(Object instanceComponentOrGameObject, str public static void RevertObjectOverride(Object instanceComponentOrGameObject, InteractionMode action) { - ThrowExceptionIfNotValidNonPersistentPrefabInstanceObject(instanceComponentOrGameObject); + ThrowExceptionIfNotValidPrefabInstanceObject(instanceComponentOrGameObject, false); if (action == InteractionMode.UserAction) Undo.RegisterCompleteObjectUndo(instanceComponentOrGameObject, "Revert component property overrides"); @@ -771,8 +800,6 @@ public static void RevertAddedComponent(Component component, InteractionMode act if (!PrefabUtility.IsAddedComponentOverride(component)) throw new ArgumentException("Cannot revert added component. Component is not an added component override on a Prefab instance.", nameof(component)); - ThrowExceptionIfInstanceIsPersistent(component); - if (action == InteractionMode.UserAction) { string dependentComponents = string.Join( @@ -827,7 +854,7 @@ public static void ApplyRemovedComponent(GameObject instanceGameObject, Componen { DateTime startTime = DateTime.UtcNow; - ThrowExceptionIfNotValidNonPersistentPrefabInstanceObject(instanceGameObject); + ThrowExceptionIfNotValidPrefabInstanceObject(instanceGameObject, true); if (assetComponent == null) throw new ArgumentNullException(nameof(assetComponent), "Prefab source may not be null."); @@ -884,7 +911,7 @@ private static void RemoveRemovedComponentOverride(Object instanceObject, Compon public static void RevertRemovedComponent(GameObject instanceGameObject, Component assetComponent, InteractionMode action) { - ThrowExceptionIfNotValidNonPersistentPrefabInstanceObject(instanceGameObject); + ThrowExceptionIfNotValidPrefabInstanceObject(instanceGameObject, false); var actionName = "Revert Prefab removed component"; var prefabInstanceObject = PrefabUtility.GetPrefabInstanceHandle(instanceGameObject); @@ -1017,7 +1044,8 @@ internal static void HandleApplyMenuItems( string thingThatChanged, Object instanceOrAssetObject, Action addApplyMenuItemAction, - bool defaultOverrideComparedToSomeSources = false) + bool defaultOverrideComparedToSomeSources = false, + bool includeSelfAsTarget = false) { // If thingThatChanged word is empty, apply menu items directly into menu. // Otherwise, insert as sub-menu named after thingThatChanged. @@ -1026,7 +1054,7 @@ internal static void HandleApplyMenuItems( if (thingThatChanged != String.Empty) thingThatChanged += "/"; - List applyTargets = GetApplyTargets(instanceOrAssetObject, defaultOverrideComparedToSomeSources); + List applyTargets = GetApplyTargets(instanceOrAssetObject, defaultOverrideComparedToSomeSources, includeSelfAsTarget); if (applyTargets == null || applyTargets.Count == 0) return; @@ -1148,6 +1176,12 @@ public static Object CreateEmptyPrefab(string path) } public static GameObject SavePrefabAsset(GameObject asset) + { + bool savedSuccesfully; + return SavePrefabAsset(asset, out savedSuccesfully); + } + + public static GameObject SavePrefabAsset(GameObject asset, out bool savedSuccessfully) { if (asset == null) throw new ArgumentNullException("Parameter prefabAssetGameObject is null"); @@ -1167,7 +1201,7 @@ public static GameObject SavePrefabAsset(GameObject asset) if (root != asset) throw new ArgumentException("GameObject to save Prefab from must be a Prefab root"); - return SavePrefabAsset_Internal(root); + return SavePrefabAsset_Internal(root, out savedSuccessfully); } private static void ValidatePath(GameObject instanceRoot, string path) @@ -1791,7 +1825,7 @@ internal static bool IsObjectOnRootInAsset(Object componentOrGameObject, string return goInAsset.transform.root == goInAsset.transform; } - internal static List GetApplyTargets(Object instanceOrAssetObject, bool defaultOverrideComparedToSomeSources) + internal static List GetApplyTargets(Object instanceOrAssetObject, bool defaultOverrideComparedToSomeSources, bool includeSelfAsTarget = false) { List applyTargets = new List(); @@ -1800,8 +1834,8 @@ internal static List GetApplyTargets(Object instanceOrAssetObject, bool instanceGameObject = (instanceOrAssetObject as Component).gameObject; Object source = instanceOrAssetObject; - if (!EditorUtility.IsPersistent(source)) - source = PrefabUtility.GetCorrespondingObjectFromSource(instanceOrAssetObject); + if (!EditorUtility.IsPersistent(source) || !includeSelfAsTarget) + source = PrefabUtility.GetCorrespondingObjectFromSource(source); if (source == null) return applyTargets; diff --git a/Editor/Mono/PreferencesWindow/PreferencesSettingsProviders.cs b/Editor/Mono/PreferencesWindow/PreferencesSettingsProviders.cs index 0d5fbf3bda..04ce67c394 100644 --- a/Editor/Mono/PreferencesWindow/PreferencesSettingsProviders.cs +++ b/Editor/Mono/PreferencesWindow/PreferencesSettingsProviders.cs @@ -9,8 +9,10 @@ using System; using System.IO; using System.Linq; +using Unity.CodeEditor; using UnityEditor.Connect; using UnityEngine.UIElements; +using UnityEngine.TestTools; using UnityEditor.Collaboration; namespace UnityEditor @@ -58,11 +60,11 @@ internal class GeneralProperties public static readonly GUIContent[] editorSkinOptions = { EditorGUIUtility.TrTextContent("Personal"), EditorGUIUtility.TrTextContent("Professional") }; public static readonly GUIContent enableAlphaNumericSorting = EditorGUIUtility.TrTextContent("Enable Alpha Numeric Sorting"); public static readonly GUIContent asyncShaderCompilation = EditorGUIUtility.TrTextContent("Asynchronous Shader Compilation"); + public static readonly GUIContent codeCoverageEnabled = EditorGUIUtility.TrTextContent("Enable Code Coverage", "Check this to enable Code Coverage."); } internal class ExternalProperties { - public static readonly GUIContent addUnityProjeToSln = EditorGUIUtility.TrTextContent("Add .unityproj's to .sln"); public static readonly GUIContent editorAttaching = EditorGUIUtility.TrTextContent("Editor Attaching"); public static readonly GUIContent changingThisSettingRequiresRestart = EditorGUIUtility.TrTextContent("Changing this setting requires a restart to take effect."); public static readonly GUIContent revisionControlDiffMerge = EditorGUIUtility.TrTextContent("Revision Control Diff/Merge"); @@ -126,7 +128,6 @@ private struct GICacheSettings private GICacheSettings m_GICacheSettings; private RefString m_ScriptEditorPath = new RefString(""); - private string m_ScriptEditorArgs = ""; private bool m_ExternalEditorSupportsUnityProj; private RefString m_ImageAppPath = new RefString(""); private int m_DiffToolIndex; @@ -141,6 +142,7 @@ private struct GICacheSettings private static SystemLanguage[] m_stableLanguages = { SystemLanguage.English }; private bool m_AllowAlphaNumericHierarchy = false; + private bool m_EnableCodeCoverage = false; private string[] m_ScriptApps; private string[] m_ScriptAppsEditions; @@ -154,12 +156,6 @@ private struct GICacheSettings private const string kRecentScriptAppsKey = "RecentlyUsedScriptApp"; private const string kRecentImageAppsKey = "RecentlyUsedImageApp"; - private static readonly string k_ExpressNotSupportedMessage = L10n.Tr( - "Unfortunately Visual Studio Express does not allow itself to be controlled by external applications. " + - "You can still use it by manually opening the Visual Studio project file, but Unity cannot automatically open files for you when you doubleclick them. " + - "\n(This does work with Visual Studio Pro)" - ); - private const int kRecentAppsCount = 10; SortedDictionary>> s_CachedColors = null; @@ -307,17 +303,7 @@ private void ShowExternalApplications(string searchContext) // Applications FilePopup(ExternalProperties.externalScriptEditor, m_ScriptEditorPath, ref m_ScriptAppDisplayNames, ref m_ScriptApps, m_ScriptEditorPath, "internal", OnScriptEditorChanged); - var scriptEditor = GetSelectedScriptEditor(); - - if (scriptEditor == ScriptEditorUtility.ScriptEditor.Other) - { - string oldEditorArgs = m_ScriptEditorArgs; - m_ScriptEditorArgs = EditorGUILayout.TextField("External Script Editor Args", m_ScriptEditorArgs); - if (oldEditorArgs != m_ScriptEditorArgs) - OnScriptEditorArgsChanged(); - } - - DoUnityProjCheckbox(); + CodeEditor.Editor.Current.OnGUI(); bool oldValue = m_AllowAttachedDebuggingOfEditor; m_AllowAttachedDebuggingOfEditor = EditorGUILayout.Toggle(ExternalProperties.editorAttaching, m_AllowAttachedDebuggingOfEditor); @@ -328,14 +314,6 @@ private void ShowExternalApplications(string searchContext) if (m_AllowAttachedDebuggingOfEditorStateChangedThisSession) GUILayout.Label(ExternalProperties.changingThisSettingRequiresRestart, EditorStyles.helpBox); - if (GetSelectedScriptEditor() == ScriptEditorUtility.ScriptEditor.VisualStudioExpress) - { - GUILayout.BeginHorizontal(EditorStyles.helpBox); - GUILayout.Label("", Constants.warningIcon); - GUILayout.Label(k_ExpressNotSupportedMessage, Constants.errorLabel); - GUILayout.EndHorizontal(); - } - GUILayout.Space(10f); FilePopup(ExternalProperties.imageApplication, m_ImageAppPath, ref m_ImageAppDisplayNames, ref m_ImageApps, m_ImageAppPath, "internal", null); @@ -369,43 +347,9 @@ private void ShowExternalApplications(string searchContext) ApplyChangesToPrefs(); } - private void DoUnityProjCheckbox() - { - bool isConfigurable = false; - bool value = false; - - ScriptEditorUtility.ScriptEditor scriptEditor = GetSelectedScriptEditor(); - - if (scriptEditor == ScriptEditorUtility.ScriptEditor.MonoDevelop) - { - isConfigurable = true; - value = m_ExternalEditorSupportsUnityProj; - } - - using (new EditorGUI.DisabledScope(!isConfigurable)) - { - value = EditorGUILayout.Toggle(ExternalProperties.addUnityProjeToSln, value); - } - - if (isConfigurable) - m_ExternalEditorSupportsUnityProj = value; - } - - private ScriptEditorUtility.ScriptEditor GetSelectedScriptEditor() - { - return ScriptEditorUtility.GetScriptEditorFromPath(m_ScriptEditorPath.str); - } - private void OnScriptEditorChanged() { - ScriptEditorUtility.SetExternalScriptEditor(m_ScriptEditorPath); - m_ScriptEditorArgs = ScriptEditorUtility.GetExternalScriptEditorArgs(); - UnityEditor.VisualStudioIntegration.UnityVSSupport.ScriptEditorChanged(m_ScriptEditorPath.str); - } - - private void OnScriptEditorArgsChanged() - { - ScriptEditorUtility.SetExternalScriptEditorArgs(m_ScriptEditorArgs); + CodeEditor.SetExternalScriptEditor(m_ScriptEditorPath); } private void ShowUnityConnectPrefs(string searchContext) @@ -499,6 +443,11 @@ private void ShowGeneral(string searchContext) InternalEditorUtility.SetGpuDeviceAndRecreateGraphics(newGpuDeviceIndex - 1, m_GpuDevice); } } + + m_EnableCodeCoverage = EditorGUILayout.Toggle(GeneralProperties.codeCoverageEnabled, m_EnableCodeCoverage); + if (m_EnableCodeCoverage != Coverage.enabled) + EditorGUILayout.HelpBox((m_EnableCodeCoverage ? "Enabling " : "Disabling ") + "Code Coverage will not take effect until Unity is restarted.", MessageType.Warning); + ApplyChangesToPrefs(); if (oldAlphaNumeric != m_AllowAlphaNumericHierarchy) @@ -744,8 +693,7 @@ private void WriteRecentAppsList(string[] paths, string path, string prefsKey) private void WritePreferences() { - ScriptEditorUtility.SetExternalScriptEditor(m_ScriptEditorPath); - ScriptEditorUtility.SetExternalScriptEditorArgs(m_ScriptEditorArgs); + CodeEditor.SetExternalScriptEditor(m_ScriptEditorPath); EditorPrefs.SetBool("kExternalEditorSupportsUnityProj", m_ExternalEditorSupportsUnityProj); EditorPrefs.SetString("kImagesDefaultApp", m_ImageAppPath); @@ -782,6 +730,7 @@ private void WritePreferences() EditorPrefs.SetString("Editor.kEditorLocale", m_SelectedLanguage); EditorPrefs.SetBool("AllowAlphaNumericHierarchy", m_AllowAlphaNumericHierarchy); + EditorPrefs.SetBool("CodeCoverageEnabled", m_EnableCodeCoverage); EditorPrefs.SetString("GpuDeviceName", m_GpuDevice); EditorPrefs.SetBool("GICacheEnableCustomPath", m_GICacheSettings.m_EnableCustomPath); @@ -811,8 +760,7 @@ static private string GetProgramFilesFolder() private void ReadPreferences() { - m_ScriptEditorPath.str = ScriptEditorUtility.GetExternalScriptEditor(); - m_ScriptEditorArgs = ScriptEditorUtility.GetExternalScriptEditorArgs(); + m_ScriptEditorPath.str = CodeEditor.Editor.EditorInstallation.Path; m_ExternalEditorSupportsUnityProj = EditorPrefs.GetBool("kExternalEditorSupportsUnityProj", false); m_ImageAppPath.str = EditorPrefs.GetString("kImagesDefaultApp"); @@ -820,25 +768,7 @@ private void ReadPreferences() m_ScriptApps = BuildAppPathList(m_ScriptEditorPath, kRecentScriptAppsKey, "internal"); m_ScriptAppsEditions = new string[m_ScriptApps.Length]; - if (Application.platform == RuntimePlatform.WindowsEditor) - { - foreach (var vsPaths in SyncVS.InstalledVisualStudios.Values) - foreach (var vsPath in vsPaths) - { - int index = Array.IndexOf(m_ScriptApps, vsPath.Path); - if (index == -1) - { - ArrayUtility.Add(ref m_ScriptApps, vsPath.Path); - ArrayUtility.Add(ref m_ScriptAppsEditions, vsPath.Edition); - } - else - { - m_ScriptAppsEditions[index] = vsPath.Edition; - } - } - } - - var foundScriptEditorPaths = ScriptEditorUtility.GetFoundScriptEditorPaths(Application.platform); + var foundScriptEditorPaths = CodeEditor.Editor.GetFoundScriptEditorPaths(); foreach (var scriptEditorPath in foundScriptEditorPaths.Keys) { @@ -889,6 +819,7 @@ private void ReadPreferences() m_EnableEditorLocalization = EditorPrefs.GetBool("Editor.kEnableEditorLocalization", true); m_SelectedLanguage = EditorPrefs.GetString("Editor.kEditorLocale", LocalizationDatabase.GetDefaultEditorLanguage().ToString()); m_AllowAlphaNumericHierarchy = EditorPrefs.GetBool("AllowAlphaNumericHierarchy", false); + m_EnableCodeCoverage = EditorPrefs.GetBool("CodeCoverageEnabled", false); m_CompressAssetsOnImport = Unsupported.GetApplicationSettingCompressAssetsOnImport(); m_GpuDevice = EditorPrefs.GetString("GpuDeviceName"); diff --git a/Editor/Mono/SceneHierarchy.cs b/Editor/Mono/SceneHierarchy.cs index 7cd7a914d2..6efa83fa14 100644 --- a/Editor/Mono/SceneHierarchy.cs +++ b/Editor/Mono/SceneHierarchy.cs @@ -1058,7 +1058,7 @@ void CreateGameObjectContextClick(GenericMenu menu, int contextClickedItemID) info.instanceObject = go; info.assetPath = AssetDatabase.GetAssetPath(sourceGo); GameObject rootGo = PrefabUtility.GetRootGameObject(sourceGo); - if (!PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(rootGo)) + if (!PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(rootGo) || EditorUtility.IsPersistent(parentTransform)) menu.AddDisabledItem(menuItemContent); else menu.AddItem(menuItemContent, false, TargetChoiceHandler.ApplyPrefabAddedGameObject, info); diff --git a/Editor/Mono/ScriptEditorUtility.cs b/Editor/Mono/ScriptEditorUtility.cs index 1ae3f40b96..3816412c30 100644 --- a/Editor/Mono/ScriptEditorUtility.cs +++ b/Editor/Mono/ScriptEditorUtility.cs @@ -8,7 +8,9 @@ using System; using System.IO; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; +using Unity.CodeEditor; using UnityEditor.Utils; namespace UnityEditorInternal @@ -26,11 +28,13 @@ public struct Installation static readonly List> k_PathCallbacks = new List>(); + [Obsolete("Use UnityEditor.ScriptEditor.Register()", false)] public static void RegisterIde(Func pathCallBack) { k_PathCallbacks.Add(pathCallBack); } + [Obsolete("This functionality is going to be removed. See IExternalCodeEditor for more information", false)] public static ScriptEditor GetScriptEditorFromPath(string path) { string lowerCasePath = path.ToLower(); @@ -69,6 +73,7 @@ internal static bool IsVisualStudioForMac(string path) return filename.StartsWith("visualstudio") && !filename.Contains("code") && filename.EndsWith(".app"); } + #pragma warning disable 618 public static string GetExternalScriptEditor() { var editor = EditorPrefs.GetString("kScriptsDefaultApp"); @@ -85,64 +90,33 @@ public static string GetExternalScriptEditor() return string.Empty; } + [Obsolete("This method has been moved to CodeEditor.SetExternalScriptEditor", false)] public static void SetExternalScriptEditor(string path) { - EditorPrefs.SetString("kScriptsDefaultApp", path); - } - - static string GetScriptEditorArgsKey(string path) - { - // Starting in Unity 5.5, we support setting script editor arguments on OSX and - // use then when opening the script editor. - // Before Unity 5.5, we would still save the default script editor args in EditorPrefs, - // even though we never used them. This means that the user potentially has some - // script editor args saved and once he upgrades to 5.5, they will be used when - // open the script editor. Which unintended and causes a regression in behaviour. - // So on OSX we change the key for per application for script editor args, - // to avoid reading the one from previous versions. - if (Application.platform == RuntimePlatform.OSXEditor) - return "kScriptEditorArgs_" + path; - - return "kScriptEditorArgs" + path; - } - - static string GetDefaultStringEditorArgs() - { - // On OSX there is a built-in mechanism for opening files in apps. - // We use this mechanism when the external script editor args are not set. - // Which was the only support behaviour before Unity 5.5. We therefor - // default to this behavior. - // If the script editor args are set, we only launch the script editor with args - // specified and do not use the built-in mechanism for opening script files. - if (Application.platform == RuntimePlatform.OSXEditor) - return ""; - - return "\"$(File)\""; + CodeEditor.SetExternalScriptEditor(path); } + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("This functionality has been moved to the IExternalCodeEditor packages", true)] public static string GetExternalScriptEditorArgs() { - string editor = GetExternalScriptEditor(); - var scriptEditor = GetScriptEditorFromPath(editor); - - if (scriptEditor != ScriptEditor.Other) - return ""; - - return EditorPrefs.GetString(GetScriptEditorArgsKey(editor), GetDefaultStringEditorArgs()); + throw new NotSupportedException("This functionality has been moved to the IExternalCodeEditor packages"); } + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("This functionality has been moved to the IExternalCodeEditor packages", true)] public static void SetExternalScriptEditorArgs(string args) { - string editor = GetExternalScriptEditor(); - - EditorPrefs.SetString(GetScriptEditorArgsKey(editor), args); + throw new NotSupportedException("This functionality has been moved to the IExternalCodeEditor packages"); } + [Obsolete("Use UnityEditor.ScriptEditor.GetCurrentEditor()", false)] public static ScriptEditor GetScriptEditorFromPreferences() { return GetScriptEditorFromPath(GetExternalScriptEditor()); } + [Obsolete("This method is being internalized, please use UnityEditorInternal.CodeEditorUtility.GetFoundScriptEditorPaths", false)] public static Dictionary GetFoundScriptEditorPaths(RuntimePlatform platform) { var result = new Dictionary(); diff --git a/Editor/Mono/Scripting/Compilers/ScriptCompilerBase.cs b/Editor/Mono/Scripting/Compilers/ScriptCompilerBase.cs index c264f87eeb..33569da2e4 100644 --- a/Editor/Mono/Scripting/Compilers/ScriptCompilerBase.cs +++ b/Editor/Mono/Scripting/Compilers/ScriptCompilerBase.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using UnityEditor.Scripting.ScriptCompilation; +using UnityEditor.Compilation; using UnityEngine; using UnityEditor.Utils; @@ -14,15 +14,6 @@ namespace UnityEditor.Scripting.Compilers { internal abstract class ScriptCompilerBase : IDisposable { - public class ResponseFileData - { - public string[] Defines; - public string[] FullPathReferences; - public bool Unsafe; - public string[] Errors; - public string[] OtherArguments; - } - public class CompilerOption { public string Arg; @@ -115,7 +106,7 @@ protected void AddResponseFileToArguments(List arguments, string respons { var responseFileData = ParseResponseFileFromFile( responseFileName, - Application.dataPath, + Directory.GetParent(Application.dataPath).FullName.ConvertSeparatorsToUnity(), GetSystemReferenceDirectories()); foreach (var error in responseFileData.Errors) { @@ -328,18 +319,16 @@ static ResponseFileData ParseResponseFileText( continue; } - var responseReference = reference; - int index = reference.IndexOf('='); - if (index > -1) - { - var assembly = reference.Substring(index + 1); + var responseReference = index > -1 ? reference.Substring(index + 1) : reference; - responseReference = assembly; + string fullPathReference = ""; + var referencePath = responseReference; + if (Path.IsPathRooted(referencePath)) + { + fullPathReference = referencePath; } - - var fullPathReference = responseReference; - if (!Path.IsPathRooted(responseReference)) + else { foreach (var directory in systemReferenceDirectories) { diff --git a/Editor/Mono/Scripting/ScriptCompilation/CompilationPipeline.cs b/Editor/Mono/Scripting/ScriptCompilation/CompilationPipeline.cs index c209297667..5cb3113ee2 100644 --- a/Editor/Mono/Scripting/ScriptCompilation/CompilationPipeline.cs +++ b/Editor/Mono/Scripting/ScriptCompilation/CompilationPipeline.cs @@ -4,8 +4,10 @@ using System; using System.Collections.Generic; +using System.IO; using UnityEditor.Scripting.ScriptCompilation; using System.Linq; +using UnityEditor.Scripting.Compilers; using sc = UnityEditor.Scripting.ScriptCompilation; using UnityEditorInternal; @@ -21,10 +23,14 @@ public enum AssemblyFlags public class ScriptCompilerOptions { public bool AllowUnsafeCode { get; set; } + public ApiCompatibilityLevel ApiCompatibilityLevel { get; set; } + public string[] ResponseFiles { get; set; } public ScriptCompilerOptions() { AllowUnsafeCode = false; + ApiCompatibilityLevel = ApiCompatibilityLevel.NET_4_6; + ResponseFiles = new string[0]; } } @@ -91,6 +97,15 @@ public Assembly(string name, } } + public class ResponseFileData + { + public string[] Defines; + public string[] FullPathReferences; + public string[] Errors; + public string[] OtherArguments; + public bool Unsafe; + } + public struct AssemblyDefinitionPlatform { public string Name { get; private set; } @@ -174,6 +189,16 @@ internal static void SubscribeToEvents(EditorCompilation editorCompilation) }; } + public static string[] GetSystemAssemblyDirectories(ApiCompatibilityLevel apiCompatibilityLevel) + { + return MonoLibraryHelpers.GetSystemReferenceDirectories(apiCompatibilityLevel); + } + + public static ResponseFileData ParseResponseFile(string relativePath, string projectDirectory, string[] systemReferenceDirectories) + { + return ScriptCompilerBase.ParseResponseFileFromFile(relativePath, projectDirectory, systemReferenceDirectories); + } + public static Assembly[] GetAssemblies() { return GetAssemblies(AssembliesType.Editor); @@ -356,6 +381,7 @@ internal static Assembly[] ToAssemblies(ScriptAssembly[] scriptAssemblies) flags |= AssemblyFlags.EditorAssembly; var compilerOptions = scriptAssembly.CompilerOptions; + compilerOptions.ResponseFiles = scriptAssembly.GetResponseFiles(); assemblies[i] = new Assembly(name, outputPath, @@ -375,7 +401,7 @@ internal static Assembly[] ToAssemblies(ScriptAssembly[] scriptAssemblies) for (int i = 0; i < scriptAssemblies.Length; ++i) { var scriptAssembly = scriptAssemblies[i]; - var assemblyReferences = scriptAssembly.ScriptAssemblyReferences.Select(a => scriptAssemblyToAssembly[a]).ToArray(); + var assemblyReferences = scriptAssembly.ScriptAssemblyReferences.Select(a => scriptAssemblyToAssembly[a]).Where(a => !IsInternalPlugin(a.outputPath)).ToArray(); assemblies[i].assemblyReferences = assemblyReferences; } @@ -384,6 +410,16 @@ internal static Assembly[] ToAssemblies(ScriptAssembly[] scriptAssemblies) return assemblies; } + static bool IsInternalPlugin(string fullReference) + { + if (AssemblyHelper.IsInternalAssembly(fullReference)) + { + if (!Modules.ModuleUtils.GetAdditionalReferencesForEditorCsharpProject().Contains(fullReference)) + return true; + } + return false; + } + static int CompareAssemblyDefinitionPlatformByDisplayName(AssemblyDefinitionPlatform p1, AssemblyDefinitionPlatform p2) { return string.Compare(p1.DisplayName, p2.DisplayName, StringComparison.OrdinalIgnoreCase); diff --git a/Editor/Mono/Scripting/ScriptCompilation/CustomScriptAssembly.cs b/Editor/Mono/Scripting/ScriptCompilation/CustomScriptAssembly.cs index 66744323dd..5fbee2377c 100644 --- a/Editor/Mono/Scripting/ScriptCompilation/CustomScriptAssembly.cs +++ b/Editor/Mono/Scripting/ScriptCompilation/CustomScriptAssembly.cs @@ -151,7 +151,7 @@ class CustomScriptAssembly public CustomScriptAssemblyPlatform[] ExcludePlatforms { get; set; } public AssetPathMetaData AssetPathMetaData { get; set; } - public ScriptCompilerOptions CompilerOptions { get; set; } + public ScriptCompilerOptions CompilerOptions { get; set; } = new ScriptCompilerOptions(); public bool OverrideReferences { get; set; } public string[] PrecompiledReferences { get; set; } diff --git a/Editor/Mono/Scripting/ScriptCompilation/EditorBuildRules.cs b/Editor/Mono/Scripting/ScriptCompilation/EditorBuildRules.cs index 83fda37032..cf38d85e20 100644 --- a/Editor/Mono/Scripting/ScriptCompilation/EditorBuildRules.cs +++ b/Editor/Mono/Scripting/ScriptCompilation/EditorBuildRules.cs @@ -601,13 +601,6 @@ internal static ScriptAssembly[] ToScriptAssemblies(IDictionary(); diff --git a/Editor/Mono/Scripting/ScriptCompilation/ScriptAssembly.cs b/Editor/Mono/Scripting/ScriptCompilation/ScriptAssembly.cs index 755cff5b63..ce06f09e72 100644 --- a/Editor/Mono/Scripting/ScriptCompilation/ScriptAssembly.cs +++ b/Editor/Mono/Scripting/ScriptCompilation/ScriptAssembly.cs @@ -2,6 +2,7 @@ // Copyright (c) Unity Technologies. For terms of use, see // https://unity3d.com/legal/licenses/Unity_Reference_Only_License +using System; using System.Collections.Generic; using System.Linq; using UnityEditor.Scripting.Compilers; @@ -15,7 +16,6 @@ class ScriptAssemblySettings public BuildTarget BuildTarget { get; set; } public BuildTargetGroup BuildTargetGroup { get; set; } public string OutputDirectory { get; set; } - public ApiCompatibilityLevel ApiCompatibilityLevel { get; set; } public EditorScriptCompilationOptions CompilationOptions { get; set; } public ScriptCompilerOptions PredefinedAssembliesCompilerOptions { get; set; } @@ -47,7 +47,6 @@ class ScriptAssembly public AssemblyFlags Flags { get; set; } public BuildTarget BuildTarget { get; set; } public SupportedLanguage Language { get; set; } - public ApiCompatibilityLevel ApiCompatibilityLevel { get; set; } public string Filename { get; set; } public string OutputDirectory { get; set; } @@ -96,12 +95,22 @@ public MonoIsland ToMonoIsland(EditorScriptCompilationOptions options, string bu buildingForEditor, developmentBuild, CompilerOptions.AllowUnsafeCode, - ApiCompatibilityLevel, + CompilerOptions.ApiCompatibilityLevel, Files, referencesArray, Defines, outputPath, reposeFiles.ToArray()); } + + public string[] GetResponseFiles() + { + if (Language == null) + { + throw new ArgumentException("Language: not set on ScriptAssembly. Cannot resolve responsefiles"); + } + var responseFileProvider = Language.CreateResponseFileProvider(); + return responseFileProvider.Get(OriginPath).ToArray(); + } } } diff --git a/Editor/Mono/SyncProject.cs b/Editor/Mono/SyncProject.cs deleted file mode 100644 index 48c93894f9..0000000000 --- a/Editor/Mono/SyncProject.cs +++ /dev/null @@ -1,454 +0,0 @@ -// Unity C# reference source -// Copyright (c) Unity Technologies. For terms of use, see -// https://unity3d.com/legal/licenses/Unity_Reference_Only_License - -using System; -using System.IO; -using System.Linq; -using System.Collections.Generic; -using Microsoft.Win32; -using UnityEditor.Callbacks; -using UnityEditor.VisualStudioIntegration; -using UnityEngine; -using UnityEngine.Scripting; -using UnityEditorInternal; - -namespace UnityEditor -{ - internal enum VisualStudioVersion - { - Invalid = 0, - VisualStudio2008 = 9, - VisualStudio2010 = 10, - VisualStudio2012 = 11, - VisualStudio2013 = 12, - VisualStudio2015 = 14, - VisualStudio2017 = 15, - VisualStudio2019 = 16, - } - - internal class VisualStudioPath - { - public string Path { get; set; } - public string Edition { get; set; } - - public VisualStudioPath(string path, string edition = "") - { - Path = path; - Edition = edition; - } - } - - [InitializeOnLoad] - internal class SyncVS : AssetPostprocessor - { - static bool s_AlreadySyncedThisDomainReload; - - static SyncVS() - { - Synchronizer = new SolutionSynchronizer(Directory.GetParent(Application.dataPath).FullName, new SolutionSynchronizationSettings()); - try - { - InstalledVisualStudios = GetInstalledVisualStudios() as Dictionary; - } - catch (Exception ex) - { - Console.WriteLine("Error detecting Visual Studio installations: {0}{1}{2}", ex.Message, Environment.NewLine, ex.StackTrace); - InstalledVisualStudios = new Dictionary(); - } - - SetVisualStudioAsEditorIfNoEditorWasSet(); - } - - private static void SetVisualStudioAsEditorIfNoEditorWasSet() - { - var externalEditor = EditorPrefs.GetString("kScriptsDefaultApp"); - var bestVisualStudio = FindBestVisualStudio(); - if (externalEditor == "" && bestVisualStudio != null) - EditorPrefs.SetString("kScriptsDefaultApp", bestVisualStudio); - } - - public static string FindBestVisualStudio() - { - var vs = InstalledVisualStudios.OrderByDescending(kvp => kvp.Key).Select(kvp2 => kvp2.Value).FirstOrDefault(); - return vs == null ? null : vs.Last().Path; - } - - private static readonly SolutionSynchronizer Synchronizer; - internal static Dictionary InstalledVisualStudios { get; private set; } - - internal class SolutionSynchronizationSettings : DefaultSolutionSynchronizationSettings - { - public override int VisualStudioVersion - { - get - { - var vs = ScriptEditorUtility.GetExternalScriptEditor(); - if (InstalledVisualStudios.ContainsKey(UnityEditor.VisualStudioVersion.VisualStudio2008) && - (vs != String.Empty) && - PathsAreEquivalent(InstalledVisualStudios[UnityEditor.VisualStudioVersion.VisualStudio2008].Last().Path, vs)) - return 9; - - return 10; - } - } - - public override string SolutionTemplate - { - get { return EditorPrefs.GetString("VSSolutionText", base.SolutionTemplate); } - } - - public override string GetProjectHeaderTemplate(ScriptingLanguage language) - { - return EditorPrefs.GetString("VSProjectHeader", base.GetProjectHeaderTemplate(language)); - } - - public override string GetProjectFooterTemplate(ScriptingLanguage language) - { - return EditorPrefs.GetString("VSProjectFooter", base.GetProjectFooterTemplate(language)); - } - - public override string EditorAssemblyPath - { - get { return UnityEditorInternal.InternalEditorUtility.GetEditorAssemblyPath(); } - } - - public override string EngineAssemblyPath - { - get { return UnityEditorInternal.InternalEditorUtility.GetEngineAssemblyPath(); } - } - - protected override string FrameworksPath() - { - return EditorApplication.applicationContentsPath; - } - - internal static bool IsOSX - { - get { return System.Environment.OSVersion.Platform == System.PlatformID.Unix; } - } - - internal static bool IsWindows - { - get { return !IsOSX && System.IO.Path.DirectorySeparatorChar == '\\' && System.Environment.NewLine == "\r\n"; } - } - } - - public static bool ProjectExists() - { - return Synchronizer.SolutionExists(); - } - - public static void CreateIfDoesntExist() - { - if (!Synchronizer.SolutionExists()) - { - Synchronizer.Sync(); - } - } - - class BuildTargetChangedHandler : Build.IActiveBuildTargetChanged - { - public int callbackOrder { get { return 0; } } - - public void OnActiveBuildTargetChanged(BuildTarget oldTarget, BuildTarget newTarget) - { - SyncVisualStudioProjectIfItAlreadyExists(); - } - } - - [RequiredByNativeCode] - public static void SyncVisualStudioProjectIfItAlreadyExists() - { - if (Synchronizer.SolutionExists()) - { - Synchronizer.Sync(); - } - } - - // For the time being this doesn't use the callback - public static void PostprocessSyncProject( - string[] importedAssets, - string[] addedAssets, - string[] deletedAssets, - string[] movedAssets, - string[] movedFromAssetPaths) - { - Synchronizer.SyncIfNeeded(addedAssets.Union(deletedAssets.Union(movedAssets.Union(movedFromAssetPaths))), importedAssets); - } - - [MenuItem("Assets/Open C# Project")] - static void SyncAndOpenSolution() - { - SyncSolution(); - OpenProjectFileUnlessInBatchMode(); - } - - public static void SyncSolution() - { - // Ensure that the mono islands are up-to-date - AssetDatabase.Refresh(); - - Synchronizer.Sync(); - } - - public static void SyncIfFirstFileOpenSinceDomainLoad() - { - if (s_AlreadySyncedThisDomainReload) - return; - - s_AlreadySyncedThisDomainReload = true; - Synchronizer.Sync(); - } - - private static void OpenProjectFileUnlessInBatchMode() - { - if (InternalEditorUtility.inBatchMode) - return; - - InternalEditorUtility.OpenFileAtLineExternal("", -1, -1); - } - - /// - /// Detects Visual Studio installations using the Windows registry - /// - /// - /// The detected Visual Studio installations - /// - private static IDictionary GetInstalledVisualStudios() - { - var versions = new Dictionary(); - - if (SolutionSynchronizationSettings.IsWindows) - { - foreach (VisualStudioVersion version in Enum.GetValues(typeof(VisualStudioVersion))) - { - if (version > VisualStudioVersion.VisualStudio2015) - continue; - - try - { - // Try COMNTOOLS environment variable first - string key = Environment.GetEnvironmentVariable(string.Format("VS{0}0COMNTOOLS", (int)version)); - if (!string.IsNullOrEmpty(key)) - { - string path = UnityEditor.Utils.Paths.Combine(key, "..", "IDE", "devenv.exe"); - if (File.Exists(path)) - { - versions[version] = new[] { new VisualStudioPath(path) }; - continue; - } - } - - // Try the proper registry key - key = GetRegistryValue( - string.Format(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\{0}.0", (int)version), "InstallDir"); - - // Try to fallback to the 32bits hive - if (string.IsNullOrEmpty(key)) - key = GetRegistryValue( - string.Format(@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\{0}.0", (int)version), "InstallDir"); - - if (!string.IsNullOrEmpty(key)) - { - string path = UnityEditor.Utils.Paths.Combine(key, "devenv.exe"); - if (File.Exists(path)) - { - versions[version] = new[] { new VisualStudioPath(path) }; - continue; - } - } - - // Fallback to debugger key - key = GetRegistryValue( - // VS uses this key for the local debugger path - string.Format(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\{0}.0\Debugger", (int)version), "FEQARuntimeImplDll"); - if (!string.IsNullOrEmpty(key)) - { - string path = DeriveVisualStudioPath(key); - if (!string.IsNullOrEmpty(path) && File.Exists(path)) - versions[version] = new[] { new VisualStudioPath(DeriveVisualStudioPath(key)) }; - } - } - catch - { - // This can happen with a registry lookup failure - } - } - - GetInstalledVisualStudios(VisualStudioVersion.VisualStudio2017, versions); - GetInstalledVisualStudios(VisualStudioVersion.VisualStudio2019, versions); - } - - return versions; - } - - private static void GetInstalledVisualStudios(VisualStudioVersion vsVersion, Dictionary versions) - { - var requiredWorkloads = new[] { "Microsoft.VisualStudio.Workload.ManagedGame" }; - var raw = VisualStudioUtil.FindVisualStudioDevEnvPaths((int)vsVersion, requiredWorkloads); - - var visualStudioPaths = VisualStudioUtil.ParseRawDevEnvPaths(raw) - .Where(vs => !requiredWorkloads.Except(vs.Workloads).Any()) // All required workloads must be present - .Select(vs => new VisualStudioPath(vs.DevEnvPath, vs.Edition)) - .ToArray(); - - if (visualStudioPaths.Length != 0) - versions[vsVersion] = visualStudioPaths; - } - - static string GetRegistryValue(string path, string key) - { - try - { - return Microsoft.Win32.Registry.GetValue(path, key, null) as string; - } - catch (Exception) - { - return ""; - } - } - - /// - /// Derives the Visual Studio installation path from the debugger path - /// - /// - /// The Visual Studio installation path (to devenv.exe) - /// - /// - /// The debugger path from the windows registry - /// - private static string DeriveVisualStudioPath(string debuggerPath) - { - string startSentinel = DeriveProgramFilesSentinel(); - string endSentinel = "Common7"; - bool started = false; - string[] tokens = debuggerPath.Split(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries); - - string path = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); - - // Walk directories in debugger path, chop out "Program Files\INSTALLATION\PATH\HERE\Common7" - foreach (var token in tokens) - { - if (!started && string.Equals(startSentinel, token, StringComparison.OrdinalIgnoreCase)) - { - started = true; - continue; - } - if (started) - { - path = Path.Combine(path, token); - if (string.Equals(endSentinel, token, StringComparison.OrdinalIgnoreCase)) - break; - } - } - - return UnityEditor.Utils.Paths.Combine(path, "IDE", "devenv.exe"); - } - - /// - /// Derives the program files sentinel for grabbing the VS installation path. - /// - /// - /// From a path like 'c:\Archivos de programa (x86)', returns 'Archivos de programa' - /// - private static string DeriveProgramFilesSentinel() - { - string path = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) - .Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) - .LastOrDefault(); - - if (!string.IsNullOrEmpty(path)) - { - // This needs to be the "real" Program Files regardless of 64bitness - int index = path.LastIndexOf("(x86)"); - if (0 <= index) - path = path.Remove(index); - return path.TrimEnd(); - } - - return "Program Files"; - } - - /// - /// Checks whether two paths are equivalent - /// - /// - /// Whether the paths are equivalent - /// - /// - /// A path - /// - /// - /// Another path - /// - private static bool PathsAreEquivalent(string aPath, string zPath) - { - if (aPath == null && zPath == null) - return true; - if (string.IsNullOrEmpty(aPath) || string.IsNullOrEmpty(zPath)) - return false; - - aPath = Path.GetFullPath(aPath); - zPath = Path.GetFullPath(zPath); - - StringComparison comparison = StringComparison.OrdinalIgnoreCase; - if (!(SolutionSynchronizationSettings.IsOSX || SolutionSynchronizationSettings.IsWindows)) - comparison = StringComparison.Ordinal; // Linux - - aPath = aPath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); - zPath = zPath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); - - return string.Equals(aPath, zPath, comparison); - } - - internal static bool CheckVisualStudioVersion(int major, int minor, int build) - { - int haveMinor = -1; - int haveBuild = -1; - - switch (major) - { - case 11: // Visual Studio 2012, getting it's version is different from others - { - // we'll grab version from (replace 11.0 with highest found 11.*): - // HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\DevDiv\vc\Servicing\11.0\RuntimeDebug\Version - Microsoft.Win32.RegistryKey servicing = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Microsoft\DevDiv\vc\Servicing"); - if (servicing == null) return false; - foreach (string name in servicing.GetSubKeyNames()) - { - if (name.StartsWith("11.") && name.Length > 3) - try - { - int foundMinor = Convert.ToInt32(name.Substring(3)); - if (foundMinor > haveMinor) - haveMinor = foundMinor; - } - catch (System.Exception) - {} - } - if (haveMinor < 0) return false; - Microsoft.Win32.RegistryKey key = servicing.OpenSubKey(string.Format(@"11.{0}\RuntimeDebug", haveMinor)); - if (key == null) return false; - string value = key.GetValue("Version", null) as string; - if (value == null) return false; - string[] components = value.Split('.'); - if (components == null || components.Length < 3) return false; - try - { - haveBuild = Convert.ToInt32(components[2]); - } - catch (System.Exception) - { - return false; - } - } - break; - default: - return false; - } - - return haveMinor > minor || (haveMinor == minor && haveBuild >= build); - } - } -} diff --git a/Editor/Mono/SyncRiderProject.cs b/Editor/Mono/SyncRiderProject.cs deleted file mode 100644 index ab7179e363..0000000000 --- a/Editor/Mono/SyncRiderProject.cs +++ /dev/null @@ -1,275 +0,0 @@ -// Unity C# reference source -// Copyright (c) Unity Technologies. For terms of use, see -// https://unity3d.com/legal/licenses/Unity_Reference_Only_License - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Microsoft.Win32; -using UnityEditorInternal; -using UnityEngine; - -namespace UnityEditor -{ - [InitializeOnLoad] - internal class SyncRiderProject - { - static SyncRiderProject() - { - ScriptEditorUtility.RegisterIde(PathCallback); - } - - static ScriptEditorUtility.Installation[] PathCallback() - { - return RiderPathLocator.GetAllRiderPaths() - .Select(riderInfo => new ScriptEditorUtility.Installation - { - Path = riderInfo.Path, - Name = riderInfo.Presentation - }) - .ToArray(); - } - } - - /// - /// This code is a modified version of the JetBrains resharper-unity plugin listed here: - /// https://github.com/JetBrains/resharper-unity/blob/master/unity/JetBrains.Rider.Unity.Editor/EditorPlugin/RiderPathLocator.cs - /// - internal static class RiderPathLocator - { - static RiderInfo[] CollectAllRiderPathsLinux() - { - var home = Environment.GetEnvironmentVariable("HOME"); - if (string.IsNullOrEmpty(home)) - return new RiderInfo[0]; - const string pathToBuildTxt = "../../build.txt"; - //$Home/.local/share/JetBrains/Toolbox/apps/Rider/ch-0/173.3994.1125/bin/rider.sh - //$Home/.local/share/JetBrains/Toolbox/apps/Rider/ch-0/.channel.settings.json - var toolboxRiderRootPath = Path.Combine(home, @".local/share/JetBrains/Toolbox/apps/Rider"); - var paths = CollectPathsFromToolbox(toolboxRiderRootPath, "bin", "rider.sh", false) - .Select(a => new RiderInfo(GetBuildNumber(Path.Combine(a, pathToBuildTxt)), a, true)).ToList(); - - - // $Home/.local/share/applications/jetbrains-rider.desktop - var shortcut = new FileInfo(Path.Combine(home, @".local/share/applications/jetbrains-rider.desktop")); - - if (shortcut.Exists) - { - var lines = File.ReadAllLines(shortcut.FullName); - foreach (var line in lines) - { - if (!line.StartsWith("Exec=\"")) - continue; - var path = line.Split('"').Where((item, index) => index == 1).SingleOrDefault(); - if (string.IsNullOrEmpty(path)) - continue; - var buildTxtPath = Path.Combine(path, pathToBuildTxt); - var buildNumber = GetBuildNumber(buildTxtPath); - if (paths.Any(a => a.Path == path)) // avoid adding similar build as from toolbox - continue; - paths.Add(new RiderInfo(buildNumber, path, false)); - } - } - - return paths.ToArray(); - } - - static RiderInfo[] CollectRiderInfosMac() - { - var pathToBuildTxt = "Contents/Resources/build.txt"; - - // "/Applications/*Rider*.app" - var folder = new DirectoryInfo("/Applications"); - var results = folder.GetDirectories("*Rider*.app") - .Select(a => new RiderInfo(GetBuildNumber(Path.Combine(a.FullName, pathToBuildTxt)), a.FullName, false)) - .ToList(); - - // /Users/user/Library/Application Support/JetBrains/Toolbox/apps/Rider/ch-1/181.3870.267/Rider EAP.app - var home = Environment.GetEnvironmentVariable("HOME"); - if (!string.IsNullOrEmpty(home)) - { - var toolboxRiderRootPath = - Path.Combine(home, @"Library/Application Support/JetBrains/Toolbox/apps/Rider"); - var paths = CollectPathsFromToolbox(toolboxRiderRootPath, "", "Rider*.app", true) - .Select(a => new RiderInfo(GetBuildNumber(Path.Combine(a, pathToBuildTxt)), a, true)); - results.AddRange(paths); - } - - return results.ToArray(); - } - - static string GetBuildNumber(string path) - { - var file = new FileInfo(path); - if (file.Exists) - return File.ReadAllText(file.FullName); - return string.Empty; - } - - static RiderInfo[] CollectRiderInfosWindows() - { - var pathToBuildTxt = "../../build.txt"; - - var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); - var toolboxRiderRootPath = Path.Combine(localAppData, @"JetBrains\Toolbox\apps\Rider"); - var installPathsToolbox = - CollectPathsFromToolbox(toolboxRiderRootPath, "bin", "rider64.exe", false).ToList(); - var installInfosToolbox = installPathsToolbox - .Select(a => new RiderInfo(GetBuildNumber(Path.Combine(a, pathToBuildTxt)), a, true)).ToList(); - - var installPaths = new List(); - const string registryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; - CollectPathsFromRegistry(registryKey, installPaths); - const string wowRegistryKey = @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"; - CollectPathsFromRegistry(wowRegistryKey, installPaths); - - var installInfos = installPaths - .Select(a => new RiderInfo(GetBuildNumber(Path.Combine(a, pathToBuildTxt)), a, false)).ToList(); - installInfos.AddRange(installInfosToolbox); - - return installInfos.ToArray(); - } - - static void CollectPathsFromRegistry(string registryKey, List installPaths) - { - using (var key = Registry.LocalMachine.OpenSubKey(registryKey)) - { - if (key == null) return; - foreach (var subkeyName in key.GetSubKeyNames().Where(a => a.Contains("Rider"))) - { - using (var subkey = key.OpenSubKey(subkeyName)) - { - var folderObject = subkey?.GetValue("InstallLocation"); - if (folderObject == null) continue; - var folder = folderObject.ToString(); - var possiblePath = Path.Combine(folder, @"bin\rider64.exe"); - if (File.Exists(possiblePath)) - installPaths.Add(possiblePath); - } - } - } - } - - public static RiderInfo[] GetAllRiderPaths() - { - try - { - switch (SystemInfo.operatingSystemFamily) - { - case OperatingSystemFamily.Windows: - { - return CollectRiderInfosWindows(); - } - case OperatingSystemFamily.MacOSX: - { - return CollectRiderInfosMac(); - } - case OperatingSystemFamily.Linux: - { - return CollectAllRiderPathsLinux(); - } - } - } - catch (Exception e) - { - Debug.LogException(e); - } - - - return new RiderInfo[0]; - } - - static string[] CollectPathsFromToolbox( - string toolboxRiderRootPath, - string dirName, - string searchPattern, - bool isMac) - { - if (!Directory.Exists(toolboxRiderRootPath)) - return new string[0]; - - var channelFiles = Directory.GetDirectories(toolboxRiderRootPath) - .Select(b => Path.Combine(b, ".channel.settings.json")).Where(File.Exists).ToArray(); - - var paths = channelFiles.SelectMany(a => { - try - { - var channelDir = Path.GetDirectoryName(a); - var json = File.ReadAllText(a).Replace("active-application", "active_application"); - var toolbox = ToolboxInstallData.FromJson(json); - var builds = toolbox.active_application.builds; - if (builds != null && builds.Any()) - { - var build = builds.First(); - var folder = Path.Combine(Path.Combine(channelDir, build), dirName); - if (!isMac) - return new[] {Path.Combine(folder, searchPattern)}; - return new DirectoryInfo(folder).GetDirectories(searchPattern).Select(f => f.FullName); - } - - // new toolbox format doesn't have active-application block, so return all found Rider installations - return Directory.GetDirectories(channelDir) - .SelectMany(b => - { - var folder = Path.Combine(b, dirName); - if (!isMac) - return new[] {Path.Combine(folder, searchPattern)}; - return new DirectoryInfo(folder).GetDirectories(searchPattern).Select(f => f.FullName); - }) - .Where(File.Exists).ToArray(); - } - catch (Exception e) - { - Debug.LogException(e); - Debug.LogWarning("Failed to get RiderPath via .channel.settings.json"); - } - - return new string[0]; - }) - .Where(c => !string.IsNullOrEmpty(c)) - .ToArray(); - return paths; - } - - [Serializable] - class ToolboxInstallData - { - public ActiveApplication active_application = null; - - public static ToolboxInstallData FromJson(string json) - { - return JsonUtility.FromJson(json); - } - } - - [Serializable] - class ActiveApplication - { - public List builds = null; - } - - public struct RiderInfo - { - public string Presentation; - public string BuildVersion; - public string Path; - - public RiderInfo(string buildVersion, string path, bool isToolbox) - { - BuildVersion = buildVersion; - Path = new FileInfo(path).FullName; // normalize separators - - var version = string.Empty; - if (buildVersion.Length > 3) - version = buildVersion.Substring(3); - - var presentation = "Rider " + version; - if (isToolbox) - presentation += " (JetBrains Toolbox)"; - - Presentation = presentation; - } - } - } -} diff --git a/Editor/Mono/UIElements/VisualTreeAssetEditor.cs b/Editor/Mono/UIElements/VisualTreeAssetEditor.cs index 547b7c3f20..77c0fe5fc2 100644 --- a/Editor/Mono/UIElements/VisualTreeAssetEditor.cs +++ b/Editor/Mono/UIElements/VisualTreeAssetEditor.cs @@ -94,7 +94,8 @@ public void Render(VisualTreeAsset vta, Rect r, GUIStyle background) clips--; } - var desc = new RenderTextureDescriptor((int)r.width, (int)r.height, RenderTextureFormat.ARGB32, 16); + float pixelsPerPoint = EditorGUIUtility.pixelsPerPoint; + var desc = new RenderTextureDescriptor((int)(r.width * pixelsPerPoint), (int)(r.height * pixelsPerPoint), RenderTextureFormat.ARGB32, 16); var rt = RenderTexture.GetTemporary(desc); var oldRt = RenderTexture.active; RenderTexture.active = rt; diff --git a/Editor/Mono/VisualStudioIntegration/SolutionSynchronizationSettings.cs b/Editor/Mono/VisualStudioIntegration/SolutionSynchronizationSettings.cs deleted file mode 100644 index 9277eca08a..0000000000 --- a/Editor/Mono/VisualStudioIntegration/SolutionSynchronizationSettings.cs +++ /dev/null @@ -1,288 +0,0 @@ -// Unity C# reference source -// Copyright (c) Unity Technologies. For terms of use, see -// https://unity3d.com/legal/licenses/Unity_Reference_Only_License - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Security; -using System.Security.Cryptography; -using System.Xml; -using System.Text; -using System.Text.RegularExpressions; -namespace UnityEditor.VisualStudioIntegration -{ - interface ISolutionSynchronizationSettings - { - int VisualStudioVersion { get; } - string SolutionTemplate { get; } - string SolutionProjectEntryTemplate { get; } - string SolutionProjectConfigurationTemplate { get; } - string EditorAssemblyPath { get; } - string EngineAssemblyPath { get; } - string MonoLibFolder { get; } - string[] Defines { get; } - string GetProjectHeaderTemplate(ScriptingLanguage language); - string GetProjectFooterTemplate(ScriptingLanguage language); - } - - internal class DefaultSolutionSynchronizationSettings : ISolutionSynchronizationSettings - { - public virtual int VisualStudioVersion - { - get { return 9; } - } - - public virtual string SolutionTemplate - { - get - { - return string.Join("\r\n", new[] - { - @"", - @"Microsoft Visual Studio Solution File, Format Version {0}", - @"# Visual Studio {1}", - @"{2}", - @"Global", - @" GlobalSection(SolutionConfigurationPlatforms) = preSolution", - @" Debug|Any CPU = Debug|Any CPU", - @" Release|Any CPU = Release|Any CPU", - @" EndGlobalSection", - @" GlobalSection(ProjectConfigurationPlatforms) = postSolution", - @"{3}", - @" EndGlobalSection", - @" GlobalSection(SolutionProperties) = preSolution", - @" HideSolutionNode = FALSE", - @" EndGlobalSection", - @"EndGlobal", - @"" - }).Replace(" ", "\t"); - } - } - - public virtual string SolutionProjectEntryTemplate - { - get - { - return string.Join("\r\n", new[] - { - @"Project(""{{{0}}}"") = ""{1}"", ""{2}"", ""{{{3}}}""", - @"EndProject" - }).Replace(" ", "\t"); - } - } - - public virtual string SolutionProjectConfigurationTemplate - { - get - { - return string.Join("\r\n", new[] - { - @" {{{0}}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU", - @" {{{0}}}.Debug|Any CPU.Build.0 = Debug|Any CPU", - @" {{{0}}}.Release|Any CPU.ActiveCfg = Release|Any CPU", - @" {{{0}}}.Release|Any CPU.Build.0 = Release|Any CPU" - }).Replace(" ", "\t"); - } - } - - public virtual string GetProjectHeaderTemplate(ScriptingLanguage language) - { - var header = new[] - { - @"", - @"", - @" ", - @" {10}", - @" {13}", - @" {14}", - @" ", - @" ", - @" Debug", - @" AnyCPU", - @" {1}", - @" 2.0", - @" {8}", - @" {{{2}}}", - @" Library", - @" Properties", - @" {7}", - @" {9}", - @" 512", - @" {11}", - @" ", - @" ", - @" true", - @" full", - @" false", - @" Temp\bin\Debug\", - @" {5}", - @" prompt", - @" 4", - @" 0169", - @" {12}", - @" ", - @" ", - @" pdbonly", - @" true", - @" Temp\bin\Release\", - @" prompt", - @" 4", - @" 0169", - @" {12}", - @" ", - }; - - var forceExplicitReferences = new string[] - { - @" ", - @" true", - @" true", - @" false", - @" false", - @" false", - @" ", - }; - - var itemGroupStart = new[] - { - @" ", - }; - - var systemReferences = new string[] - { - @" ", - @" ", - @" ", - @" ", - @" ", - }; - - var footer = new string[] - { - @" ", - @" {3}", - @" ", - @" ", - @" {4}", - @" ", - @" ", - @" ", - @"" - }; - - string[] text; - - if (language == ScriptingLanguage.CSharp) - text = header.Concat(forceExplicitReferences).Concat(itemGroupStart).Concat(footer).ToArray(); - else - text = header.Concat(itemGroupStart).Concat(systemReferences).Concat(footer).ToArray(); - - return string.Join("\r\n", text); - } - - public virtual string GetProjectFooterTemplate(ScriptingLanguage language) - { - return string.Join("\r\n", new[] - { - @" ", - @" ", - @" ", - @"", - @"" - }); - } - - public virtual string EditorAssemblyPath - { - get { return "/Managed/UnityEditor.dll"; } - } - - public virtual string EngineAssemblyPath - { - get { return "/Managed/UnityEngine.dll"; } - } - - public virtual string MonoLibFolder - { - get { return FrameworksPath() + "/Mono/lib/mono/unity/"; } - } - - public virtual string[] Defines - { - get { return new string[0]; } - } - - protected virtual string FrameworksPath() - { - return string.Empty; - } - } - - static class VSCodeTemplates - { - public static string SettingsJson = @"{ - ""files.exclude"": - { - ""**/.DS_Store"":true, - ""**/.git"":true, - ""**/.gitignore"":true, - ""**/.gitmodules"":true, - ""**/*.booproj"":true, - ""**/*.pidb"":true, - ""**/*.suo"":true, - ""**/*.user"":true, - ""**/*.userprefs"":true, - ""**/*.unityproj"":true, - ""**/*.dll"":true, - ""**/*.exe"":true, - ""**/*.pdf"":true, - ""**/*.mid"":true, - ""**/*.midi"":true, - ""**/*.wav"":true, - ""**/*.gif"":true, - ""**/*.ico"":true, - ""**/*.jpg"":true, - ""**/*.jpeg"":true, - ""**/*.png"":true, - ""**/*.psd"":true, - ""**/*.tga"":true, - ""**/*.tif"":true, - ""**/*.tiff"":true, - ""**/*.3ds"":true, - ""**/*.3DS"":true, - ""**/*.fbx"":true, - ""**/*.FBX"":true, - ""**/*.lxo"":true, - ""**/*.LXO"":true, - ""**/*.ma"":true, - ""**/*.MA"":true, - ""**/*.obj"":true, - ""**/*.OBJ"":true, - ""**/*.asset"":true, - ""**/*.cubemap"":true, - ""**/*.flare"":true, - ""**/*.mat"":true, - ""**/*.meta"":true, - ""**/*.prefab"":true, - ""**/*.unity"":true, - ""build/"":true, - ""Build/"":true, - ""Library/"":true, - ""library/"":true, - ""obj/"":true, - ""Obj/"":true, - ""ProjectSettings/"":true, - ""temp/"":true, - ""Temp/"":true - } -}"; - } -} diff --git a/Editor/Mono/VisualStudioIntegration/SolutionSynchronizer.cs b/Editor/Mono/VisualStudioIntegration/SolutionSynchronizer.cs deleted file mode 100644 index 442b499a6f..0000000000 --- a/Editor/Mono/VisualStudioIntegration/SolutionSynchronizer.cs +++ /dev/null @@ -1,842 +0,0 @@ -// Unity C# reference source -// Copyright (c) Unity Technologies. For terms of use, see -// https://unity3d.com/legal/licenses/Unity_Reference_Only_License - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Security; -using System.Security.Cryptography; -using System.Text; -using System.Text.RegularExpressions; -using UnityEditor.Scripting; -using UnityEditor.Scripting.ScriptCompilation; -using UnityEditor.Utils; -using UnityEditorInternal; -using UnityEditor.Scripting.Compilers; -using UnityEngine.Profiling; - -using UnityEditor.Compilation; -using UnityEditor.Modules; -using UnityEngine; - -namespace UnityEditor.VisualStudioIntegration -{ - enum ScriptingLanguage - { - None, - Boo, - CSharp, - UnityScript, - } - - interface IAssemblyNameProvider - { - string GetAssemblyNameFromScriptPath(string path); - IEnumerable GetAllScriptAssemblies(Func shouldFileBePartOfSolution, string projectDirectory); - IEnumerable GetAllAssetPaths(); - } - - class AssemblyNameProvider : IAssemblyNameProvider - { - public string GetAssemblyNameFromScriptPath(string path) - { - return CompilationPipeline.GetAssemblyNameFromScriptPath(path); - } - - public IEnumerable GetAllScriptAssemblies(Func shouldFileBePartOfSolution, string projectDirectory) - { - return EditorCompilationInterface.Instance.GetAllScriptAssemblies(EditorScriptCompilationOptions.BuildingForEditor | EditorCompilationInterface.GetAdditionalEditorScriptCompilationOptions()) - .Where(i => 0 < i.Files.Length && i.Files.Any(shouldFileBePartOfSolution)) - .Select(x => x.ToMonoIsland(EditorScriptCompilationOptions.BuildingForEditor, string.Empty, projectDirectory)).ToList(); - } - - public IEnumerable GetAllAssetPaths() - { - return AssetDatabase.GetAllAssetPaths(); - } - } - - class SolutionSynchronizer - { - enum Mode - { - UnityScriptAsUnityProj, - UnityScriptAsPrecompiledAssembly - } - - public static readonly ISolutionSynchronizationSettings DefaultSynchronizationSettings = - new DefaultSolutionSynchronizationSettings(); - - static readonly string WindowsNewline = "\r\n"; - - /// - /// Map source extensions to ScriptingLanguages - /// - static internal readonly Dictionary BuiltinSupportedExtensions = new Dictionary - { - {"cs", ScriptingLanguage.CSharp}, - {"uxml", ScriptingLanguage.None}, - {"uss", ScriptingLanguage.None}, - {"shader", ScriptingLanguage.None}, - {"compute", ScriptingLanguage.None}, - {"cginc", ScriptingLanguage.None}, - {"hlsl", ScriptingLanguage.None}, - {"glslinc", ScriptingLanguage.None}, - {"template", ScriptingLanguage.None}, - {"raytrace", ScriptingLanguage.None}, - }; - - private static readonly string[] reimportSyncExtensions = new[] { ".dll", ".asmdef", ".asmref" }; - - string[] ProjectSupportedExtensions = new string[0]; - - /// - /// Map ScriptingLanguages to project extensions - /// - static readonly Dictionary ProjectExtensions = new Dictionary - { - { ScriptingLanguage.Boo, ".booproj" }, - { ScriptingLanguage.CSharp, ".csproj" }, - { ScriptingLanguage.UnityScript, ".unityproj" }, - { ScriptingLanguage.None, ".csproj" }, - }; - - public static readonly string MSBuildNamespaceUri = "http://schemas.microsoft.com/developer/msbuild/2003"; - - private readonly string _projectDirectory; - private readonly ISolutionSynchronizationSettings _settings; - private readonly string _projectName; - readonly IAssemblyNameProvider m_assemblyNameProvider; - - public SolutionSynchronizer(string projectDirectory, ISolutionSynchronizationSettings settings, IAssemblyNameProvider assemblyNameProvider) - { - _projectDirectory = projectDirectory.ConvertSeparatorsToUnity(); - _settings = settings; - _projectName = Path.GetFileName(_projectDirectory); - m_assemblyNameProvider = assemblyNameProvider; - } - - public SolutionSynchronizer(string projectDirectory, ISolutionSynchronizationSettings settings) : this(projectDirectory, settings, new AssemblyNameProvider()) - { - } - - public SolutionSynchronizer(string projectDirectory) : this(projectDirectory, DefaultSynchronizationSettings) - { - } - - private void SetupProjectSupportedExtensions() - { - ProjectSupportedExtensions = EditorSettings.projectGenerationUserExtensions; - } - - public bool ShouldFileBePartOfSolution(string file) - { - string extension = Path.GetExtension(file); - - // Exclude files coming from packages except if they are internalized. - if (IsNonInternalizedPackagePath(file)) - { - return false; - } - - // Dll's are not scripts but still need to be included.. - if (extension == ".dll") - return true; - - // Check if the file is an asmref or asmdef - if (file.Length > 7) - { - var extensionLower = file.Substring(file.Length - 7, 7).ToLower(); - - if (extensionLower.EndsWith(".asmdef")) - return true; - - if (extensionLower.EndsWith(".asmref")) - return true; - } - - return IsSupportedExtension(extension); - } - - private bool IsSupportedExtension(string extension) - { - extension = extension.TrimStart('.'); - if (BuiltinSupportedExtensions.ContainsKey(extension)) - return true; - if (ProjectSupportedExtensions.Contains(extension)) - return true; - return false; - } - - private static ScriptingLanguage ScriptingLanguageFor(MonoIsland island) - { - return ScriptingLanguageFor(island.GetExtensionOfSourceFiles()); - } - - private static ScriptingLanguage ScriptingLanguageFor(string extension) - { - ScriptingLanguage result; - if (BuiltinSupportedExtensions.TryGetValue(extension.TrimStart('.'), out result)) - return result; - - return ScriptingLanguage.None; - } - - public bool ProjectExists(MonoIsland island) - { - return File.Exists(ProjectFile(island)); - } - - public bool SolutionExists() - { - return File.Exists(SolutionFile()); - } - - private static void DumpIsland(MonoIsland island) - { - Console.WriteLine("{0} ({1})", island._output, island._api_compatibility_level); - Console.WriteLine("Files: "); - Console.WriteLine(string.Join("\n", island._files)); - Console.WriteLine("References: "); - Console.WriteLine(string.Join("\n", island._references)); - Console.WriteLine(""); - } - - /// - /// Syncs the scripting solution if any affected files are relevant. - /// - /// - /// Whether the solution was synced. - /// - /// - /// A set of files whose status has changed - /// - /// - /// A set of files that got reimported - /// - public bool SyncIfNeeded(IEnumerable affectedFiles, IEnumerable reimportedFiles) - { - SetupProjectSupportedExtensions(); - - // Don't sync if we haven't synced before - if (SolutionExists() && (affectedFiles.Any(ShouldFileBePartOfSolution) || reimportedFiles.Any(ShouldSyncOnReimportedAsset))) - { - Sync(); - return true; - } - - return false; - } - - private bool ShouldSyncOnReimportedAsset(string asset) - { - return reimportSyncExtensions.Contains(new FileInfo(asset).Extension); - } - - public void Sync() - { - Profiler.BeginSample("SolutionSynchronizerSync"); - // Do not sync solution until all Unity extensions are registered and initialized. - // Otherwise Unity might emit errors when VSTU tries to generate the solution and - // get all managed extensions, which not yet initialized. - if (!InternalEditorUtility.IsUnityExtensionsInitialized()) - { - Profiler.EndSample(); - return; - } - - SetupProjectSupportedExtensions(); - - bool externalCodeAlreadyGeneratedProjects = AssetPostprocessingInternal.OnPreGeneratingCSProjectFiles(); - - if (!externalCodeAlreadyGeneratedProjects) - { - var scriptEditor = ScriptEditorUtility.GetScriptEditorFromPreferences(); - GenerateAndWriteSolutionAndProjects(scriptEditor); - } - - AssetPostprocessingInternal.CallOnGeneratedCSProjectFiles(); - Profiler.EndSample(); - } - - internal void GenerateAndWriteSolutionAndProjects(ScriptEditorUtility.ScriptEditor scriptEditor) - { - Profiler.BeginSample("GenerateAndWriteSolutionAndProjects"); - - Profiler.BeginSample("SolutionSynchronizer.GetIslands"); - // Only synchronize islands that have associated source files and ones that we actually want in the project. - // This also filters out DLLs coming from .asmdef files in packages. - IEnumerable islands = m_assemblyNameProvider.GetAllScriptAssemblies(ShouldFileBePartOfSolution, _projectDirectory); - - Profiler.EndSample(); - - Profiler.BeginSample("GenerateAllAssetProjectParts.GetIslands"); - var allAssetProjectParts = GenerateAllAssetProjectParts(); - Profiler.EndSample(); - - var monoIslands = islands.ToList(); - - Profiler.BeginSample("SyncSolution"); - SyncSolution(monoIslands.ToList()); - Profiler.EndSample(); - - var allProjectIslands = RelevantIslandsForMode(monoIslands, ModeForCurrentExternalEditor()).ToList(); - - foreach (MonoIsland island in allProjectIslands) - { - Profiler.BeginSample("SyncProject"); - SyncProject(island, allAssetProjectParts, ParseResponseFileData(island), allProjectIslands); - Profiler.EndSample(); - } - - if (scriptEditor == ScriptEditorUtility.ScriptEditor.VisualStudioCode) - { - Profiler.BeginSample("WriteVSCodeSettingsFiles"); - WriteVSCodeSettingsFiles(); - Profiler.EndSample(); - } - - Profiler.EndSample(); - } - - IEnumerable ParseResponseFileData(MonoIsland island) - { - var systemReferenceDirectories = MonoLibraryHelpers.GetSystemReferenceDirectories(island._api_compatibility_level); - - Dictionary responseFilesData = island._responseFiles.ToDictionary(x => x, x => ScriptCompilerBase.ParseResponseFileFromFile( - x, - _projectDirectory, - systemReferenceDirectories - )); - - Dictionary responseFilesWithErrors = responseFilesData.Where(x => x.Value.Errors.Any()) - .ToDictionary(x => x.Key, x => x.Value); - - if (responseFilesWithErrors.Any()) - { - foreach (var error in responseFilesWithErrors) - foreach (var valueError in error.Value.Errors) - { - UnityEngine.Debug.LogErrorFormat("{0} Parse Error : {1}", error.Key, valueError); - } - } - - return responseFilesData.Select(x => x.Value); - } - - Dictionary GenerateAllAssetProjectParts() - { - Dictionary stringBuilders = new Dictionary(); - - foreach (string asset in m_assemblyNameProvider.GetAllAssetPaths()) - { - // Exclude files coming from packages except if they are internalized. - if (IsNonInternalizedPackagePath(asset)) - { - continue; - } - string extension = Path.GetExtension(asset); - if (IsSupportedExtension(extension) && ScriptingLanguage.None == ScriptingLanguageFor(extension)) - { - // Find assembly the asset belongs to by adding script extension and using compilation pipeline. - var assemblyName = m_assemblyNameProvider.GetAssemblyNameFromScriptPath(asset + ".cs"); - assemblyName = assemblyName ?? m_assemblyNameProvider.GetAssemblyNameFromScriptPath(asset + ".js"); - assemblyName = assemblyName ?? m_assemblyNameProvider.GetAssemblyNameFromScriptPath(asset + ".boo"); - - if (string.IsNullOrEmpty(assemblyName)) - { - continue; - } - - assemblyName = Utility.FileNameWithoutExtension(assemblyName); - - StringBuilder projectBuilder = null; - - if (!stringBuilders.TryGetValue(assemblyName, out projectBuilder)) - { - projectBuilder = new StringBuilder(); - stringBuilders[assemblyName] = projectBuilder; - } - - projectBuilder.Append(" ").Append(WindowsNewline); - } - } - - var result = new Dictionary(); - - foreach (var entry in stringBuilders) - result[entry.Key] = entry.Value.ToString(); - - return result; - } - - bool IsNonInternalizedPackagePath(string file) - { - if (UnityEditor.PackageManager.Folders.IsPackagedAssetPath(file)) - { - bool rootFolder, readOnly; - bool validPath = AssetDatabase.GetAssetFolderInfo(file, out rootFolder, out readOnly); - return (!validPath || readOnly); - } - return false; - } - - void SyncProject(MonoIsland island, - Dictionary allAssetsProjectParts, - IEnumerable responseFilesData, - List allProjectIslands) - { - SyncProjectFileIfNotChanged(ProjectFile(island), ProjectText(island, ModeForCurrentExternalEditor(), allAssetsProjectParts, responseFilesData, allProjectIslands)); - } - - static void SyncProjectFileIfNotChanged(string path, string newContents) - { - if (Path.GetExtension(path) == ".csproj") - { - newContents = AssetPostprocessingInternal.CallOnGeneratedCSProject(path, newContents); - } - - SyncFileIfNotChanged(path, newContents); - } - - static void SyncSolutionFileIfNotChanged(string path, string newContents) - { - newContents = AssetPostprocessingInternal.CallOnGeneratedSlnSolution(path, newContents); - - SyncFileIfNotChanged(path, newContents); - } - - static void LogDifference(string path, string currentContents, string newContents) - { - Console.WriteLine("[C# Project] Writing {0} because it has changed", path); - - var currentReader = new StringReader(currentContents); - var newReader = new StringReader(newContents); - - string currentLine = null; - string newLine = null; - int lineNumber = 1; - - do - { - currentLine = currentReader.ReadLine(); - newLine = newReader.ReadLine(); - - if (currentLine != null && newLine != null && currentLine != newLine) - { - Console.WriteLine("[C# Project] First difference on line {0}", lineNumber); - - Console.WriteLine("\n[C# Project] Current {0}:", path); - - for (int i = 0; - i < 5 && currentLine != null; - i++, currentLine = currentReader.ReadLine()) - { - Console.WriteLine("[C# Project] {0:D3}: {1}", lineNumber + i, currentLine); - } - - Console.WriteLine("\n[C# Project] New {0}:", path); - - for (int i = 0; - i < 5 && newLine != null; - i++, newLine = newReader.ReadLine()) - { - Console.WriteLine("[C# Project] {0:D3}: {1}", lineNumber + i, newLine); - } - - currentLine = null; - newLine = null; - } - - lineNumber++; - } - while (currentLine != null && newLine != null); - } - - private static void SyncFileIfNotChanged(string filename, string newContents) - { - if (File.Exists(filename)) - { - var currentContents = File.ReadAllText(filename); - - if (currentContents == newContents) - { - return; - } - - try - { - LogDifference(filename, currentContents, newContents); - } - catch (Exception exception) - { - Console.WriteLine("Failed to log difference of {0}\n{1}", - filename, exception); - } - } - - File.WriteAllText(filename, newContents, Encoding.UTF8); - } - - void WriteVSCodeSettingsFiles() - { - string vsCodeDirectory = Path.Combine(_projectDirectory, ".vscode"); - - if (!Directory.Exists(vsCodeDirectory)) - Directory.CreateDirectory(vsCodeDirectory); - - string vsCodeSettingsJson = Path.Combine(vsCodeDirectory, "settings.json"); - - if (!File.Exists(vsCodeSettingsJson)) - File.WriteAllText(vsCodeSettingsJson, VSCodeTemplates.SettingsJson); - } - - public static readonly Regex scriptReferenceExpression = new Regex( - @"^Library.ScriptAssemblies.(?(?.*)\.dll$)", - RegexOptions.Compiled | RegexOptions.IgnoreCase); - - static bool IsAdditionalInternalAssemblyReference(bool isBuildingEditorProject, string reference) - { - if (isBuildingEditorProject) - return Modules.ModuleUtils.GetAdditionalReferencesForEditorCsharpProject().Contains(reference); - return false; - } - - string ProjectText(MonoIsland island, - Mode mode, - Dictionary allAssetsProjectParts, - IEnumerable responseFilesData, - List allProjectIslands) - { - var projectBuilder = new StringBuilder(ProjectHeader(island, responseFilesData)); - var references = new List(); - var projectReferences = new List(); - Match match; - bool isBuildingEditorProject = island._output.EndsWith("-Editor.dll"); - - foreach (string file in island._files) - { - if (!ShouldFileBePartOfSolution(file)) - continue; - - var extension = Path.GetExtension(file).ToLower(); - var fullFile = EscapedRelativePathFor(file); - if (".dll" != extension) - { - var tagName = "Compile"; - projectBuilder.Append(" <").Append(tagName).Append(" Include=\"").Append(fullFile).Append("\" />").Append(WindowsNewline); - } - else - { - references.Add(fullFile); - } - } - - string additionalAssetsForProject; - var assemblyName = Utility.FileNameWithoutExtension(island._output); - - // Append additional non-script files that should be included in project generation. - if (allAssetsProjectParts.TryGetValue(assemblyName, out additionalAssetsForProject)) - projectBuilder.Append(additionalAssetsForProject); - - var allAdditionalReferenceFilenames = new List(); - var islandRefs = references.Union(island._references); - - foreach (string reference in islandRefs) - { - if (reference.EndsWith("/UnityEditor.dll", StringComparison.Ordinal) - || reference.EndsWith("/UnityEngine.dll", StringComparison.Ordinal) - || reference.EndsWith("\\UnityEditor.dll", StringComparison.Ordinal) - || reference.EndsWith("\\UnityEngine.dll", StringComparison.Ordinal)) - continue; - - match = scriptReferenceExpression.Match(reference); - if (match.Success) - { - var language = ScriptCompilers.GetLanguageFromExtension(island.GetExtensionOfSourceFiles()); - var targetLanguage = (ScriptingLanguage)Enum.Parse(typeof(ScriptingLanguage), language.GetLanguageName(), true); - if (mode == Mode.UnityScriptAsUnityProj || ScriptingLanguage.CSharp == targetLanguage) - { - // Add a reference to a project except if it's a reference to a script assembly - // that we are not generating a project for. This will be the case for assemblies - // coming from .assembly.json files in non-internalized packages. - var dllName = match.Groups["dllname"].Value; - if (allProjectIslands.Any(i => Path.GetFileName(i._output) == dllName)) - { - projectReferences.Add(match); - continue; - } - } - } - - string fullReference = Path.IsPathRooted(reference) ? reference : Path.Combine(_projectDirectory, reference); - if (!AssemblyHelper.IsManagedAssembly(fullReference)) - continue; - if (AssemblyHelper.IsInternalAssembly(fullReference)) - { - if (!IsAdditionalInternalAssemblyReference(isBuildingEditorProject, fullReference)) - continue; - var referenceName = Path.GetFileName(fullReference); - if (allAdditionalReferenceFilenames.Contains(referenceName)) - continue; - allAdditionalReferenceFilenames.Add(referenceName); - } - - AppendReference(fullReference, projectBuilder); - } - - var responseRefs = responseFilesData.SelectMany(x => x.FullPathReferences); - foreach (var reference in responseRefs) - { - AppendReference(reference, projectBuilder); - } - - if (0 < projectReferences.Count) - { - string referencedProject; - projectBuilder.AppendLine(" "); - projectBuilder.AppendLine(" "); - foreach (Match reference in projectReferences) - { - var targetAssembly = EditorCompilationInterface.Instance.GetTargetAssemblyDetails(reference.Groups["dllname"].Value); - ScriptingLanguage targetLanguage = ScriptingLanguage.None; - if (targetAssembly != null) - targetLanguage = (ScriptingLanguage)Enum.Parse(typeof(ScriptingLanguage), targetAssembly.Language.GetLanguageName(), true); - referencedProject = reference.Groups["project"].Value; - projectBuilder.Append(" ").Append(WindowsNewline); - projectBuilder.Append(" {").Append(ProjectGuid(Path.Combine("Temp", reference.Groups["project"].Value + ".dll"))).Append("}").Append(WindowsNewline); - projectBuilder.Append(" ").Append(referencedProject).Append("").Append(WindowsNewline); - projectBuilder.AppendLine(" "); - } - } - - projectBuilder.Append(ProjectFooter(island)); - return projectBuilder.ToString(); - } - - static void AppendReference(string fullReference, StringBuilder projectBuilder) - { - //replace \ with / and \\ with / - var escapedFullPath = SecurityElement.Escape(fullReference); - escapedFullPath = escapedFullPath.Replace("\\", "/"); - escapedFullPath = escapedFullPath.Replace("\\\\", "/"); - projectBuilder.Append(" ").Append(WindowsNewline); - projectBuilder.Append(" ").Append(escapedFullPath).Append("").Append(WindowsNewline); - projectBuilder.Append(" ").Append(WindowsNewline); - } - - public string ProjectFile(MonoIsland island) - { - ScriptingLanguage language = ScriptingLanguageFor(island); - return Path.Combine(_projectDirectory, string.Format("{0}{1}", Utility.FileNameWithoutExtension(island._output), ProjectExtensions[language])); - } - - internal string SolutionFile() - { - return Path.Combine(_projectDirectory, string.Format("{0}.sln", _projectName)); - } - - private string ProjectHeader(MonoIsland island, - IEnumerable responseFilesData) - { - string targetframeworkversion = "v3.5"; - string targetLanguageVersion = "4"; - string toolsversion = "4.0"; - string productversion = "10.0.20506"; - string baseDirectory = "."; - string cscToolPath = "$(CscToolPath)"; - string cscToolExe = "$(CscToolExe)"; - ScriptingLanguage language = ScriptingLanguageFor(island); - - if (PlayerSettingsEditor.IsLatestApiCompatibility(island._api_compatibility_level)) - { - targetframeworkversion = "v4.7.1"; - targetLanguageVersion = "latest"; - - cscToolPath = Paths.Combine(EditorApplication.applicationContentsPath, "Tools", "RoslynScripts"); - if (Application.platform == RuntimePlatform.WindowsEditor) - cscToolExe = "unity_csc.bat"; - else - cscToolExe = "unity_csc.sh"; - - cscToolPath = Paths.UnifyDirectorySeparator(cscToolPath); - } - else if (_settings.VisualStudioVersion == 9) - { - toolsversion = "3.5"; - productversion = "9.0.21022"; - } - - var arguments = new object[] - { - toolsversion, productversion, ProjectGuid(island._output), - _settings.EngineAssemblyPath, - _settings.EditorAssemblyPath, - string.Join(";", new[] { "DEBUG", "TRACE"}.Concat(island._defines).Concat(responseFilesData.SelectMany(x => x.Defines)).Distinct().ToArray()), - MSBuildNamespaceUri, - Utility.FileNameWithoutExtension(island._output), - EditorSettings.projectGenerationRootNamespace, - targetframeworkversion, - targetLanguageVersion, - baseDirectory, - island._allowUnsafeCode | responseFilesData.Any(x => x.Unsafe), - cscToolPath, - cscToolExe, - }; - - try - { - return string.Format(_settings.GetProjectHeaderTemplate(language), arguments); - } - catch (Exception) - { - throw new System.NotSupportedException("Failed creating c# project because the c# project header did not have the correct amount of arguments, which is " + arguments.Length); - } - } - - private void SyncSolution(IEnumerable islands) - { - SyncSolutionFileIfNotChanged(SolutionFile(), SolutionText(islands, ModeForCurrentExternalEditor())); - } - - private static Mode ModeForCurrentExternalEditor() - { - var scriptEditor = ScriptEditorUtility.GetScriptEditorFromPreferences(); - - if (scriptEditor == ScriptEditorUtility.ScriptEditor.VisualStudio || - scriptEditor == ScriptEditorUtility.ScriptEditor.VisualStudioExpress || - scriptEditor == ScriptEditorUtility.ScriptEditor.VisualStudioCode) - return Mode.UnityScriptAsPrecompiledAssembly; - - return EditorPrefs.GetBool("kExternalEditorSupportsUnityProj", false) ? Mode.UnityScriptAsUnityProj : Mode.UnityScriptAsPrecompiledAssembly; - } - - private string SolutionText(IEnumerable islands, Mode mode) - { - var fileversion = "11.00"; - var vsversion = "2010"; - if (_settings.VisualStudioVersion == 9) - { - fileversion = "10.00"; - vsversion = "2008"; - } - var relevantIslands = RelevantIslandsForMode(islands, mode); - string projectEntries = GetProjectEntries(relevantIslands); - string projectConfigurations = string.Join(WindowsNewline, relevantIslands.Select(i => GetProjectActiveConfigurations(ProjectGuid(i._output))).ToArray()); - return string.Format(_settings.SolutionTemplate, fileversion, vsversion, projectEntries, projectConfigurations); - } - - private static IEnumerable RelevantIslandsForMode(IEnumerable islands, Mode mode) - { - IEnumerable relevantIslands = islands.Where(i => (mode == Mode.UnityScriptAsUnityProj || ScriptingLanguage.CSharp == ScriptingLanguageFor(i))); - return relevantIslands; - } - - /// - /// Get a Project("{guid}") = "MyProject", "MyProject.unityproj", "{projectguid}" - /// entry for each relevant language - /// - internal string GetProjectEntries(IEnumerable islands) - { - var projectEntries = islands.Select(i => string.Format( - DefaultSynchronizationSettings.SolutionProjectEntryTemplate, - SolutionGuid(i), Utility.FileNameWithoutExtension(i._output), Path.GetFileName(ProjectFile(i)), ProjectGuid(i._output) - )); - - return string.Join(WindowsNewline, projectEntries.ToArray()); - } - - /// - /// Generate the active configuration string for a given project guid - /// - private string GetProjectActiveConfigurations(string projectGuid) - { - return string.Format( - DefaultSynchronizationSettings.SolutionProjectConfigurationTemplate, - projectGuid); - } - - private string EscapedRelativePathFor(string file) - { - var projectDir = _projectDirectory.ConvertSeparatorsToWindows(); - file = file.ConvertSeparatorsToWindows(); - var path = Paths.SkipPathPrefix(file, projectDir); - if (PackageManager.Folders.IsPackagedAssetPath(path.ConvertSeparatorsToUnity())) - { - // We have to normalize the path, because the PackageManagerRemapper assumes - // dir seperators will be os specific. - var absolutePath = Path.GetFullPath(path.NormalizePath()).ConvertSeparatorsToWindows(); - path = Paths.SkipPathPrefix(absolutePath, projectDir); - } - return SecurityElement.Escape(path); - } - - string ProjectGuid(string assembly) - { - return SolutionGuidGenerator.GuidForProject(_projectName + Utility.FileNameWithoutExtension(assembly)); - } - - string SolutionGuid(MonoIsland island) - { - return SolutionGuidGenerator.GuidForSolution(_projectName, island.GetExtensionOfSourceFiles()); - } - - string ProjectFooter(MonoIsland island) - { - return _settings.GetProjectFooterTemplate(ScriptingLanguageFor(island)); - } - - [Obsolete("Use AssemblyHelper.IsManagedAssembly")] - public static bool IsManagedAssembly(string file) - { - return AssemblyHelper.IsManagedAssembly(file); - } - - public static string GetProjectExtension(ScriptingLanguage language) - { - if (!ProjectExtensions.ContainsKey(language)) - throw new ArgumentException("Unsupported language", "language"); - - return ProjectExtensions[language]; - } - } - - public static class SolutionGuidGenerator - { - public static string GuidForProject(string projectName) - { - return ComputeGuidHashFor(projectName + "salt"); - } - - public static string GuidForSolution(string projectName, string sourceFileExtension) - { - if (sourceFileExtension.ToLower() == "cs") - // GUID for a C# class library: http://www.codeproject.com/Reference/720512/List-of-Visual-Studio-Project-Type-GUIDs - return "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"; - - return ComputeGuidHashFor(projectName); - } - - private static string ComputeGuidHashFor(string input) - { - var hash = MD5.Create().ComputeHash(Encoding.Default.GetBytes(input)); - return HashAsGuid(HashToString(hash)); - } - - private static string HashAsGuid(string hash) - { - var guid = hash.Substring(0, 8) + "-" + hash.Substring(8, 4) + "-" + hash.Substring(12, 4) + "-" + hash.Substring(16, 4) + "-" + hash.Substring(20, 12); - return guid.ToUpper(); - } - - private static string HashToString(byte[] bs) - { - var sb = new StringBuilder(); - foreach (byte b in bs) - sb.Append(b.ToString("x2")); - return sb.ToString(); - } - } -} diff --git a/Editor/Mono/VisualStudioIntegration/UnityVSSupport.cs b/Editor/Mono/VisualStudioIntegration/UnityVSSupport.cs deleted file mode 100644 index 9070ff0189..0000000000 --- a/Editor/Mono/VisualStudioIntegration/UnityVSSupport.cs +++ /dev/null @@ -1,366 +0,0 @@ -// Unity C# reference source -// Copyright (c) Unity Technologies. For terms of use, see -// https://unity3d.com/legal/licenses/Unity_Reference_Only_License - -using System; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using Microsoft.Win32; -using UnityEditorInternal; -using UnityEngine; -using RequiredByNativeCodeAttribute = UnityEngine.Scripting.RequiredByNativeCodeAttribute; - -namespace UnityEditor.VisualStudioIntegration -{ - internal class UnityVSSupport - { - private static bool m_ShouldUnityVSBeActive; - public static string s_UnityVSBridgeToLoad; - private static bool? s_IsUnityVSEnabled; - private static string s_AboutLabel; - - [RequiredByNativeCode] - public static void InitializeUnityVSSupport() - { - Initialize(null); - } - - public static void Initialize(string editorPath) - { - var externalEditor = editorPath ?? ScriptEditorUtility.GetExternalScriptEditor(); - - if (Application.platform == RuntimePlatform.OSXEditor) - { - InitializeVSForMac(externalEditor); - return; - } - - if (Application.platform == RuntimePlatform.WindowsEditor) - InitializeVisualStudio(externalEditor); - } - - private static void InitializeVSForMac(string externalEditor) - { - Version vsfmVersion; - if (!IsVSForMac(externalEditor, out vsfmVersion)) - return; - - m_ShouldUnityVSBeActive = true; - - var bridgeFile = GetVSForMacBridgeAssembly(externalEditor, vsfmVersion); - if (string.IsNullOrEmpty(bridgeFile) || !File.Exists(bridgeFile)) - { - Console.WriteLine("Unable to find Tools for Unity bridge dll for Visual Studio for Mac " + externalEditor); - return; - } - - s_UnityVSBridgeToLoad = bridgeFile; - InternalEditorUtility.RegisterPrecompiledAssembly(Path.GetFileNameWithoutExtension(bridgeFile), bridgeFile); - } - - private static bool IsVSForMac(string externalEditor, out Version vsfmVersion) - { - vsfmVersion = null; - - if (!ScriptEditorUtility.IsVisualStudioForMac(externalEditor)) - return false; - - // We need to extract the version used by VS for Mac - // to lookup its addin registry - try - { - return GetVSForMacVersion(externalEditor, out vsfmVersion); - } - catch (Exception e) - { - Console.WriteLine("Failed to read Visual Studio for Mac information: {0}", e); - return false; - } - } - - private static bool GetVSForMacVersion(string externalEditor, out Version vsfmVersion) - { - vsfmVersion = null; - - // Read the full VS for Mac version from the plist, it will look like this: - // - // CFBundleShortVersionString - // X.X.X.X - - var plist = Path.Combine(externalEditor, "Contents/Info.plist"); - if (!File.Exists(plist)) - return false; - - const string versionStringRegex = @"\CFBundleShortVersionString\\s+\(?\d+\.\d+\.\d+\.\d+?)\"; - - var file = File.ReadAllText(plist); - var match = Regex.Match(file, versionStringRegex); - var versionGroup = match.Groups["version"]; - if (!versionGroup.Success) - return false; - - vsfmVersion = new Version(versionGroup.Value); - return true; - } - - private static string GetVSForMacBridgeAssembly(string externalEditor, Version vsfmVersion) - { - // Check first if we're overriden - // Useful when developing UnityVS for Mac - var bridge = Environment.GetEnvironmentVariable("VSTUM_BRIDGE"); - if (!string.IsNullOrEmpty(bridge) && File.Exists(bridge)) - return bridge; - - // Look for installed addin - const string addinBridge = "Editor/SyntaxTree.VisualStudio.Unity.Bridge.dll"; - const string addinName = "MonoDevelop.Unity"; - - // Check if we're installed in the user addins repository - // ~/Library/Application Support/VisualStudio/X.0/LocalInstall/Addins - var localAddins = Path.Combine( - Environment.GetFolderPath(Environment.SpecialFolder.Personal), - "Library/Application Support/VisualStudio/" + vsfmVersion.Major + ".0" + "/LocalInstall/Addins"); - - // In the user addins repository, the addins are suffixed by their versions, like `MonoDevelop.Unity.1.0` - // When installing another local user addin, MD will remove files inside the folder - // So we browse all VSTUM addins, and return the one with a bridge, which is the one MD will load - if (Directory.Exists(localAddins)) - { - foreach (var folder in Directory.GetDirectories(localAddins, addinName + "*", SearchOption.TopDirectoryOnly)) - { - bridge = Path.Combine(folder, addinBridge); - if (File.Exists(bridge)) - return bridge; - } - } - - // Check in Visual Studio.app/ - // In that case the name of the addin is used - bridge = Path.Combine(externalEditor, "Contents/Resources/lib/monodevelop/AddIns/" + addinName + "/" + addinBridge); - if (File.Exists(bridge)) - return bridge; - - return null; - } - - private static void InitializeVisualStudio(string externalEditor) - { - if (externalEditor.EndsWith("UnityVS.OpenFile.exe")) - { - externalEditor = SyncVS.FindBestVisualStudio(); - if (externalEditor != null) - ScriptEditorUtility.SetExternalScriptEditor(externalEditor); - } - - VisualStudioVersion vsVersion; - if (!IsVisualStudio(externalEditor, out vsVersion)) - return; - - m_ShouldUnityVSBeActive = true; - - var bridgeFile = GetVstuBridgeAssembly(vsVersion); - if (bridgeFile == null) - { - Console.WriteLine("Unable to find bridge dll in registry for Microsoft Visual Studio Tools for Unity for " + externalEditor); - return; - } - if (!File.Exists(bridgeFile)) - { - Console.WriteLine("Unable to find bridge dll on disk for Microsoft Visual Studio Tools for Unity for " + bridgeFile); - return; - } - s_UnityVSBridgeToLoad = bridgeFile; - InternalEditorUtility.RegisterPrecompiledAssembly(Path.GetFileNameWithoutExtension(bridgeFile), bridgeFile); - } - - static bool IsVisualStudio(string externalEditor, out VisualStudioVersion vsVersion) - { - if (string.IsNullOrEmpty(externalEditor)) - { - vsVersion = VisualStudioVersion.Invalid; - return false; - } - - // If it's a VS found through envvars or the registry - var matches = SyncVS.InstalledVisualStudios.Where(kvp => kvp.Value.Any(v => UnityEditor.Utils.Paths.AreEqual(v.Path, externalEditor, true))).ToArray(); - if (matches.Length > 0) - { - vsVersion = matches[0].Key; - return true; - } - - // If it's a side-by-side VS selected manually - if (externalEditor.EndsWith("devenv.exe", StringComparison.OrdinalIgnoreCase)) - { - if (TryGetVisualStudioVersion(externalEditor, out vsVersion)) - return true; - } - - vsVersion = VisualStudioVersion.Invalid; - return false; - } - - private static bool TryGetVisualStudioVersion(string externalEditor, out VisualStudioVersion vsVersion) - { - switch (ProductVersion(externalEditor).Major) - { - case 9: - vsVersion = VisualStudioVersion.VisualStudio2008; - return true; - case 10: - vsVersion = VisualStudioVersion.VisualStudio2010; - return true; - case 11: - vsVersion = VisualStudioVersion.VisualStudio2012; - return true; - case 12: - vsVersion = VisualStudioVersion.VisualStudio2013; - return true; - case 14: - vsVersion = VisualStudioVersion.VisualStudio2015; - return true; - case 15: - vsVersion = VisualStudioVersion.VisualStudio2017; - return true; - case 16: - vsVersion = VisualStudioVersion.VisualStudio2019; - return true; - } - - vsVersion = VisualStudioVersion.Invalid; - return false; - } - - private static Version ProductVersion(string externalEditor) - { - try - { - return new Version(System.Diagnostics.FileVersionInfo.GetVersionInfo(externalEditor).ProductVersion); - } - catch (Exception) - { - return new Version(0, 0); - } - } - - //Called by UnityVS through reflection - static public bool ShouldUnityVSBeActive() - { - return m_ShouldUnityVSBeActive; - } - - static string GetAssemblyLocation(System.Reflection.Assembly a) - { - try - { - return a.Location; - } - catch (NotSupportedException) - { - return null; - } - } - - [RequiredByNativeCode] - static public bool IsUnityVSEnabled() - { - if (!m_ShouldUnityVSBeActive) - { - return false; - } - if (!s_IsUnityVSEnabled.HasValue) - s_IsUnityVSEnabled = AppDomain.CurrentDomain.GetAssemblies().Any(a => GetAssemblyLocation(a) == s_UnityVSBridgeToLoad); - - return s_IsUnityVSEnabled.Value; - } - - private static string GetVstuBridgeAssembly(VisualStudioVersion version) - { - try - { - var vsVersion = string.Empty; - - switch (version) - { - // Starting with VS 15, the registry key is using the VS version - // to avoid taking a dependency on the product name - case VisualStudioVersion.VisualStudio2017: - vsVersion = "15.0"; - break; - case VisualStudioVersion.VisualStudio2019: - vsVersion = "16.0"; - break; - // VS 2015 and under are still installed in the registry - // using their project names - case VisualStudioVersion.VisualStudio2015: - vsVersion = "2015"; - break; - case VisualStudioVersion.VisualStudio2013: - vsVersion = "2013"; - break; - case VisualStudioVersion.VisualStudio2012: - vsVersion = "2012"; - break; - case VisualStudioVersion.VisualStudio2010: - vsVersion = "2010"; - break; - } - - // search first for the current user with a fallback to machine wide setting - return GetVstuBridgePathFromRegistry(vsVersion, true) - ?? GetVstuBridgePathFromRegistry(vsVersion, false); - } - catch (Exception) - { - return null; - } - } - - private static string GetVstuBridgePathFromRegistry(string vsVersion, bool currentUser) - { - var registryKey = string.Format(@"{0}\Software\Microsoft\Microsoft Visual Studio {1} Tools for Unity", - currentUser ? "HKEY_CURRENT_USER" : "HKEY_LOCAL_MACHINE", - vsVersion); - - return (string)Registry.GetValue(registryKey, "UnityExtensionPath", null); - } - - public static void ScriptEditorChanged(string editorPath) - { - if (Application.platform != RuntimePlatform.OSXEditor && Application.platform != RuntimePlatform.WindowsEditor) - return; - - // We reload the domain because selecting a different editor requires loading a different UnityVS - Initialize(editorPath); - - InternalEditorUtility.RequestScriptReload(); - } - - public static string GetAboutWindowLabel() - { - if (s_AboutLabel != null) - return s_AboutLabel; - - s_AboutLabel = CalculateAboutWindowLabel(); - return s_AboutLabel; - } - - private static string CalculateAboutWindowLabel() - { - if (!IsUnityVSEnabled()) - return ""; - - var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => GetAssemblyLocation(a) == s_UnityVSBridgeToLoad); - if (assembly == null) - return ""; - - var sb = new StringBuilder("Microsoft Visual Studio Tools for Unity "); - sb.Append(assembly.GetName().Version); - sb.Append(" enabled"); - - return sb.ToString(); - } - } -} diff --git a/Modules/AssetPipelineEditor/ImportSettings/AssetImporterEditor.bindings.cs b/Modules/AssetPipelineEditor/ImportSettings/AssetImporterEditor.bindings.cs index 93e07fec99..807e5964ae 100644 --- a/Modules/AssetPipelineEditor/ImportSettings/AssetImporterEditor.bindings.cs +++ b/Modules/AssetPipelineEditor/ImportSettings/AssetImporterEditor.bindings.cs @@ -17,6 +17,8 @@ public abstract partial class AssetImporterEditor [FreeFunction] private static extern bool ReleaseInspectorCopy(int instanceID); [FreeFunction] + private static extern void FixCacheCount(int instanceID, int count); + [FreeFunction] private static extern int GetInspectorCopyCount(int instanceID); [FreeFunction("IsMetaDataSerializationEqual")] private static extern bool IsSerializedDataEqual([NotNull] Object source); diff --git a/Modules/AssetPipelineEditor/ImportSettings/AssetImporterEditor.cs b/Modules/AssetPipelineEditor/ImportSettings/AssetImporterEditor.cs index faf5c0622c..1c51209e5a 100644 --- a/Modules/AssetPipelineEditor/ImportSettings/AssetImporterEditor.cs +++ b/Modules/AssetPipelineEditor/ImportSettings/AssetImporterEditor.cs @@ -5,9 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; -using System.IO; using UnityEngine; -using UnityEngine.Experimental.AssetBundlePatching; using Object = UnityEngine.Object; namespace UnityEditor.Experimental.AssetImporters @@ -39,8 +37,19 @@ static class Styles // if they want to modify data outside the Importer serialization in the ImporterInspector. // This allow support for multiple inspectors, multiple selections and assembly reload. // See an example usage in AssemblyDefinitionImporterInspector. - protected Object[] extraDataTargets { get; private set; } - protected Object extraDataTarget => extraDataTargets[referenceTargetIndex]; + Object[] m_ExtraDataTargets; + protected Object[] extraDataTargets + { + get + { + if (!m_AllowMultiObjectAccess) + Debug.LogError("The targets array should not be used inside OnSceneGUI or OnPreviewGUI. Use the single target property instead."); + return m_ExtraDataTargets; + } + } + + protected Object extraDataTarget => m_ExtraDataTargets[referenceTargetIndex]; + SerializedObject m_ExtraDataSerializedObject; protected SerializedObject extraDataSerializedObject { @@ -48,7 +57,7 @@ protected SerializedObject extraDataSerializedObject { if (m_ExtraDataSerializedObject == null && extraDataType != null) { - m_ExtraDataSerializedObject = new SerializedObject(extraDataTargets); + m_ExtraDataSerializedObject = new SerializedObject(m_ExtraDataTargets); } return m_ExtraDataSerializedObject; } @@ -63,6 +72,7 @@ protected SerializedObject extraDataSerializedObject // we need to keep a list of unreleased instances in case the user cancel the de-selection // we are using these instances to keep the same apply/revert status with the forced re-selection static List s_UnreleasedInstances; + List m_TargetsInstanceID; // Check to make sure Users implemented their Inspector correctly for the Cancel deselection mechanism. bool m_ApplyRevertGUICalled; // Adding a check on OnEnable to make sure users call the base class, as it used to do nothing. @@ -93,25 +103,25 @@ internal sealed override void InternalSetTargets(Object[] t) if (!typeof(ScriptableObject).IsAssignableFrom(extraDataType)) { Debug.LogError("Custom Data objects needs to be ScriptableObject to support assembly reloads and Undo/Redo"); - extraDataTargets = null; + m_ExtraDataTargets = null; } else { - extraDataTargets = new Object[t.Length]; + m_ExtraDataTargets = new Object[t.Length]; } } else { - extraDataTargets = null; + m_ExtraDataTargets = null; } if (m_CopySaved) // coming back from an assembly reload or asset re-import { - if (extraDataTargets != null) // we need to recreate the user custom array + if (m_ExtraDataTargets != null) // we need to recreate the user custom array { // just get back the data from customSerializedData array, it gets serialized and reconstructed properly extraDataSerializedObject.SetIsDifferentCacheDirty(); - extraDataTargets = extraDataSerializedObject.targetObjects; + m_ExtraDataTargets = extraDataSerializedObject.targetObjects; } foreach (var index in AssetWasUpdated()) { @@ -127,39 +137,42 @@ internal sealed override void InternalSetTargets(Object[] t) int instanceID = t[i].GetInstanceID(); loadedIds.Add(instanceID); var extraData = CreateOrReloadInspectorCopy(instanceID); - if (extraDataTargets != null) + if (m_ExtraDataTargets != null) { // we got the data from another instance if (extraData != null) - extraDataTargets[i] = extraData; + m_ExtraDataTargets[i] = extraData; else { - extraDataTargets[i] = ScriptableObject.CreateInstance(extraDataType); - InitializeExtraDataInstance(extraDataTargets[i], i); - SaveUserData(instanceID, extraDataTargets[i]); + m_ExtraDataTargets[i] = ScriptableObject.CreateInstance(extraDataType); + m_ExtraDataTargets[i].hideFlags = HideFlags.DontUnloadUnusedAsset | HideFlags.DontSaveInEditor; + InitializeExtraDataInstance(m_ExtraDataTargets[i], i); + SaveUserData(instanceID, m_ExtraDataTargets[i]); } } // proceed to an editor count check to make sure we have the proper number of instances saved. // If it is not the case, then a dispose was not done properly. - var editors = Resources.FindObjectsOfTypeAll(); + var editors = Resources.FindObjectsOfTypeAll(this.GetType()).Cast(); int count = editors.Count(e => e.targets.Contains(t[i])); - if (s_UnreleasedInstances != null && s_UnreleasedInstances.Contains(instanceID)) - count++; + if (s_UnreleasedInstances != null) + { + count += s_UnreleasedInstances.Count(id => id == instanceID); + } var instances = GetInspectorCopyCount(instanceID); if (count != instances) { - // Preemptively dispose the extra instance of the object so we fall back in a correct state. - if (count == instances - 1) - ReleaseInspectorCopy(instanceID); if (!CanEditorSurviveAssemblyReload()) { - Debug.LogError($"The previous instance of {GetType()} has not been disposed correctly. Make sure {GetType()} is a valid MonoScript."); + Debug.LogError($"The previous instance of {GetType()} was not un-loaded properly. The script has to be declared in a file with the same name."); } else { Debug.LogError($"The previous instance of {GetType()} has not been disposed correctly. Make sure you are calling base.OnDisable() in your AssetImporterEditor implementation."); } + + // Fix the cache count so it does not fail anymore. + FixCacheCount(instanceID, count); } } @@ -177,6 +190,7 @@ internal sealed override void InternalSetTargets(Object[] t) } } + m_TargetsInstanceID = loadedIds; m_CopySaved = true; } } @@ -198,8 +212,8 @@ void FixImporterAssetbundleName(string arg1, string arg2) { for (int i = 0; i < targets.Length; i++) { - var importer = (AssetImporter)targets[i]; - if (importer.assetPath == arg1) + var importer = targets[i] as AssetImporter; + if (importer != null && importer.assetPath == arg1) { FixSavedAssetbundleSettings(importer.GetInstanceID(), new PropertyModification[] { @@ -338,22 +352,16 @@ public virtual void OnDisable() { s_UnreleasedInstances = new List(); } - foreach (var t in targets) + foreach (var t in m_TargetsInstanceID) { - if (t != null) - { - s_UnreleasedInstances.Add(t.GetInstanceID()); - } + s_UnreleasedInstances.Add(t); } } else { - foreach (var t in targets) + foreach (var t in m_TargetsInstanceID) { - if (t != null) - { - ReleaseInspectorCopy(t.GetInstanceID()); - } + ReleaseInspectorCopy(t); } } } @@ -470,7 +478,7 @@ private void ReloadAssetData(int index) if (extraDataSerializedObject != null) { extraDataSerializedObject.SetIsDifferentCacheDirty(); - InitializeExtraDataInstance(extraDataTargets[index], index); + InitializeExtraDataInstance(m_ExtraDataTargets[index], index); extraDataSerializedObject.Update(); } UpdateSavedData(targets[index]); diff --git a/Modules/ShortcutManagerEditor/ContextManager.cs b/Modules/ShortcutManagerEditor/ContextManager.cs index 46e2b9237f..18267bada9 100644 --- a/Modules/ShortcutManagerEditor/ContextManager.cs +++ b/Modules/ShortcutManagerEditor/ContextManager.cs @@ -33,6 +33,7 @@ internal class GlobalContext {} List m_PriorityContexts = new List(); List m_ToolContexts = new List(); + static Dictionary s_IsPriorityContextCache = new Dictionary(); public int activeContextCount => 1 + ((focusedWindow != null) ? 1 : 0) + m_PriorityContexts.Count(c => c.active) + m_ToolContexts.Count(c => c.active); @@ -60,7 +61,14 @@ static bool IsPriorityContext(IShortcutToolContext context) static bool IsPriorityContext(Type context) { - return Attribute.GetCustomAttribute(context, typeof(PriorityContextAttribute)) != null; + bool result; + if (!s_IsPriorityContextCache.TryGetValue(context, out result)) + { + result = Attribute.GetCustomAttribute(context, typeof(PriorityContextAttribute)) != null; + s_IsPriorityContextCache[context] = result; + } + + return result; } public bool DoContextsConflict(Type context1, Type context2) @@ -113,7 +121,7 @@ public void DeregisterToolContext(IShortcutToolContext context) if (context == null) return; - if (IsPriorityContext(context)) + if (m_PriorityContexts.Contains(context)) DeregisterPriorityContext(context); else { diff --git a/Modules/UIElements/Panel.cs b/Modules/UIElements/Panel.cs index a2e09caae2..1475190ed3 100644 --- a/Modules/UIElements/Panel.cs +++ b/Modules/UIElements/Panel.cs @@ -17,23 +17,24 @@ public enum ContextType [Flags] internal enum VersionChangeType { - //Some data was bound + // Some data was bound Bindings = 1 << 8, // persistent data ready ViewData = 1 << 7, // changes to hierarchy Hierarchy = 1 << 6, - // changes to layout + // changes to properties that may have an impact on layout Layout = 1 << 5, // changes to StyleSheet, USS class StyleSheet = 1 << 4, // changes to styles, colors and other render properties Styles = 1 << 3, - // transforms are invalid + // changes that may impact the world transform (e.g. laid out position, local transform) Transform = 1 << 2, - // clips (rect position or size) are invalid - Clip = 1 << 1, - // pixels in the target have been changed, just repaint, only makes sense on the Panel + // changes to the size of the element after layout has been performed, without taking the local transform into account + Size = 1 << 1, + // The visuals of the element have changed + // TODO: Rename to visuals Repaint = 1 << 0, } @@ -563,13 +564,24 @@ public override VisualElement Pick(Vector2 point) return PickAll(visualTree, point); } + private bool m_ValidatingLayout = false; public override void ValidateLayout() { - Profiler.BeginSample(m_ProfileLayoutName); - m_VisualTreeUpdater.UpdateVisualTreePhase(VisualTreeUpdatePhase.Styles); - m_VisualTreeUpdater.UpdateVisualTreePhase(VisualTreeUpdatePhase.Layout); - m_VisualTreeUpdater.UpdateVisualTreePhase(VisualTreeUpdatePhase.TransformClip); - Profiler.EndSample(); + // Reentrancy proofing: ValidateLayout() could be in the code path of updaters. + // Actual case: TransformClip update phase recomputes elements under mouse, which does a pick, which validates layout. + // Updaters use version numbers for early exit, but it may happen that an updater invalidates a subsequent updater. + if (!m_ValidatingLayout) + { + m_ValidatingLayout = true; + + Profiler.BeginSample(m_ProfileLayoutName); + m_VisualTreeUpdater.UpdateVisualTreePhase(VisualTreeUpdatePhase.Styles); + m_VisualTreeUpdater.UpdateVisualTreePhase(VisualTreeUpdatePhase.Layout); + m_VisualTreeUpdater.UpdateVisualTreePhase(VisualTreeUpdatePhase.TransformClip); + Profiler.EndSample(); + + m_ValidatingLayout = false; + } } public override void UpdateBindings() diff --git a/Modules/UIElements/Renderer/UIRChainBuilder.cs b/Modules/UIElements/Renderer/UIRChainBuilder.cs index 8350eab952..fbce76d40b 100644 --- a/Modules/UIElements/Renderer/UIRChainBuilder.cs +++ b/Modules/UIElements/Renderer/UIRChainBuilder.cs @@ -26,8 +26,8 @@ internal class RenderChain : IDisposable { RenderChainCommand m_FirstCommand; uint m_DirtyID; // A monotonically increasing ID used to avoid double processing of some elements - VisualElement m_FirstDirtyVisuals, m_FirstDirtyTransform, m_FirstDirtyClipping; - VisualElement m_LastDirtyVisuals, m_LastDirtyTransform, m_LastDirtyClipping; + VisualElement m_FirstDirtyVisuals, m_FirstDirtyTransformOrSize, m_FirstDirtyClipping; + VisualElement m_LastDirtyVisuals, m_LastDirtyTransformOrSize, m_LastDirtyClipping; Pool m_CommandPool = new Pool(); ChainBuilderStats m_Stats; uint m_StatsElementsAdded, m_StatsElementsRemoved; @@ -154,19 +154,20 @@ public void Render(Rect topRect, Matrix4x4 projection) m_FirstDirtyClipping = m_LastDirtyClipping = null; m_DirtyID++; - dirty = m_FirstDirtyTransform; + var clearDirty = ~(RenderDataDirtyTypes.Transform | RenderDataDirtyTypes.Size); + dirty = m_FirstDirtyTransformOrSize; s_TransformProcessingSampler.Begin(); while (dirty != null) { if (dirty.renderChainData.isInChain && dirty.renderChainData.dirtyID != m_DirtyID) - Implementation.RenderEvents.ProcessOnTransformChanged(this, dirty, m_DirtyID, device, ref m_Stats); - dirty.renderChainData.dirtiedTransform = false; + Implementation.RenderEvents.ProcessOnTransformOrSizeChanged(this, dirty, m_DirtyID, device, ref m_Stats); + dirty.renderChainData.dirtiedValues &= clearDirty; var old = dirty; - dirty = dirty.renderChainData.nextDirtyTransform; - old.renderChainData.nextDirtyTransform = null; + dirty = dirty.renderChainData.nextDirtyTransformOrSize; + old.renderChainData.nextDirtyTransformOrSize = null; } s_TransformProcessingSampler.End(); - m_FirstDirtyTransform = m_LastDirtyTransform = null; + m_FirstDirtyTransformOrSize = m_LastDirtyTransformOrSize = null; m_DirtyID++; dirty = m_FirstDirtyVisuals; @@ -275,10 +276,10 @@ public void UIEOnChildRemoving(VisualElement ve) var removalInfo = new Implementation.RemovalInfo(); m_StatsElementsRemoved += Implementation.RenderEvents.OnChildRemoving(this, ve, ref removalInfo); Debug.Assert(!ve.renderChainData.isInChain); - CleanupDirtyLists(removalInfo.anyDirtiedClipping, removalInfo.anyDirtiedTransform, removalInfo.anyDirtiedVisuals); + CleanupDirtyLists(removalInfo.anyDirtiedClipping, removalInfo.anyDirtiedTransformOrSize, removalInfo.anyDirtiedVisuals); } - public void CleanupDirtyLists(bool cleanClipping, bool cleanTransform, bool cleanVisuals) + public void CleanupDirtyLists(bool cleanClipping, bool cleanTransformOrSize, bool cleanVisuals) { if (cleanClipping) { @@ -309,16 +310,16 @@ public void CleanupDirtyLists(bool cleanClipping, bool cleanTransform, bool clea m_LastDirtyClipping = last; } - if (cleanTransform) + if (cleanTransformOrSize) { // Reset transform. VisualElement first = null; VisualElement last = null; - VisualElement current = m_FirstDirtyTransform; + VisualElement current = m_FirstDirtyTransformOrSize; VisualElement next = null; while (current != null) { - next = current.renderChainData.nextDirtyTransform; + next = current.renderChainData.nextDirtyTransformOrSize; if (current.renderChainData.isInChain) { first = first ?? current; @@ -327,16 +328,16 @@ public void CleanupDirtyLists(bool cleanClipping, bool cleanTransform, bool clea else { if (last != null) - last.renderChainData.nextDirtyTransform = next; - current.renderChainData.nextDirtyTransform = null; + last.renderChainData.nextDirtyTransformOrSize = next; + current.renderChainData.nextDirtyTransformOrSize = null; } current = next; m_StatsTransformListCleanup++; } - m_FirstDirtyTransform = first; - m_LastDirtyTransform = last; + m_FirstDirtyTransformOrSize = first; + m_LastDirtyTransformOrSize = last; } if (cleanVisuals) @@ -369,7 +370,11 @@ public void CleanupDirtyLists(bool cleanClipping, bool cleanTransform, bool clea } } - public void UIEOnTransformChanged(VisualElement ve) { Implementation.RenderEvents.OnTransformChanged(this, ve); } + public void UIEOnTransformOrSizeChanged(VisualElement ve, bool transformChanged, bool sizeChanged) + { + Implementation.RenderEvents.OnTransformOrSizeChanged(this, ve, transformChanged, sizeChanged); + } + public void UIEOnClippingChanged(VisualElement ve) { Implementation.RenderEvents.OnClippingChanged(this, ve); } public void UIEOnVisualsChanged(VisualElement ve, bool hierarchical) { Implementation.RenderEvents.OnVisualsChanged(this, ve, hierarchical); } #endregion @@ -461,15 +466,24 @@ internal void OnClippingChanged(VisualElement ve) else m_FirstDirtyClipping = m_LastDirtyClipping = ve; } - internal void OnTransformChanged(VisualElement ve) + internal void OnTransformOrSizeChanged(VisualElement ve, bool transformChanged, bool sizeChanged) { - ve.renderChainData.dirtiedTransform = true; - if (m_LastDirtyTransform != null) + RenderDataDirtyTypes current = ve.renderChainData.dirtiedValues; + bool isInList = (current & (RenderDataDirtyTypes.Transform | RenderDataDirtyTypes.Size)) != 0; + + ve.renderChainData.dirtiedValues = current | + (transformChanged ? RenderDataDirtyTypes.Transform : RenderDataDirtyTypes.None) | + (sizeChanged ? RenderDataDirtyTypes.Size : RenderDataDirtyTypes.None); + + if (!isInList) { - m_LastDirtyTransform.renderChainData.nextDirtyTransform = ve; - m_LastDirtyTransform = ve; + if (m_LastDirtyTransformOrSize != null) + { + m_LastDirtyTransformOrSize.renderChainData.nextDirtyTransformOrSize = ve; + m_LastDirtyTransformOrSize = ve; + } + else m_FirstDirtyTransformOrSize = m_LastDirtyTransformOrSize = ve; } - else m_FirstDirtyTransform = m_LastDirtyTransform = ve; } internal void BeforeRenderDeviceRelease() @@ -591,17 +605,26 @@ static VisualElement GetFirstElementInPanel(VisualElement ve) } + [Flags] + internal enum RenderDataDirtyTypes + { + None = 0, + Transform = 1 << 0, + Size = 1 << 1, + } + internal struct RenderChainVEData { internal VisualElement prev, next; // This is a flattened view of the visual element hierarchy internal VisualElement groupTransformAncestor, boneTransformAncestor; - internal VisualElement nextDirtyVisuals, nextDirtyTransform, nextDirtyClipping; // Embedded linked list for dirty updates + internal VisualElement nextDirtyVisuals, nextDirtyTransformOrSize, nextDirtyClipping; // Embedded linked list for dirty updates internal RenderChainCommand firstCommand, lastCommand; // Sequential for the same owner internal RenderChainCommand firstClosingCommand, lastClosingCommand; // Optional, sequential for the same owner, the presence of closing commands requires starting commands too, otherwise certain optimizations will become invalid internal bool isInChain, isStencilClipped, isHierarchyHidden; internal bool usesText, usesAtlas, disableNudging; internal byte dirtiedVisuals; // 0, 1 is for self, and 2 is hierarchical - internal bool dirtiedClipping, dirtiedTransform; + internal bool dirtiedClipping; + internal RenderDataDirtyTypes dirtiedValues; internal Implementation.ClipMethod clipMethod; internal MeshHandle data, closingData; internal Alloc transformID; diff --git a/Modules/UIElements/Renderer/UIRChainBuilderImpl.cs b/Modules/UIElements/Renderer/UIRChainBuilderImpl.cs index a37dd61a05..2c02f2c94a 100644 --- a/Modules/UIElements/Renderer/UIRChainBuilderImpl.cs +++ b/Modules/UIElements/Renderer/UIRChainBuilderImpl.cs @@ -20,7 +20,7 @@ internal enum ClipMethod struct RemovalInfo { public bool anyDirtiedClipping; - public bool anyDirtiedTransform; + public bool anyDirtiedTransformOrSize; public bool anyDirtiedVisuals; } @@ -75,10 +75,10 @@ internal static void OnClippingChanged(RenderChain renderChain, VisualElement ve renderChain.OnClippingChanged(ve); } - internal static void OnTransformChanged(RenderChain renderChain, VisualElement ve) + internal static void OnTransformOrSizeChanged(RenderChain renderChain, VisualElement ve, bool transformChanged, bool sizeChanged) { - if (ve.renderChainData.isInChain && !ve.renderChainData.dirtiedTransform) - renderChain.OnTransformChanged(ve); + if (ve.renderChainData.isInChain) + renderChain.OnTransformOrSizeChanged(ve, transformChanged, sizeChanged); } internal static void OnRestoreTransformIDs(VisualElement ve, UIRenderDevice device) @@ -116,10 +116,10 @@ internal static void ProcessOnClippingChanged(RenderChain renderChain, VisualEle DepthFirstOnClippingChanged(renderChain, ve.hierarchy.parent, ve, dirtyID, false, device, ref stats); } - internal static void ProcessOnTransformChanged(RenderChain renderChain, VisualElement ve, uint dirtyID, UIRenderDevice device, ref ChainBuilderStats stats) + internal static void ProcessOnTransformOrSizeChanged(RenderChain renderChain, VisualElement ve, uint dirtyID, UIRenderDevice device, ref ChainBuilderStats stats) { stats.recursiveTransformUpdates++; - DepthFirstOnTransformChanged(renderChain, ve.hierarchy.parent, ve, dirtyID, device, false, ref stats); + DepthFirstOnTransformOrSizeChanged(renderChain, ve.hierarchy.parent, ve, dirtyID, device, false, false, ref stats); } internal static void ProcessOnVisualsChanged(RenderChain renderChain, VisualElement ve, uint dirtyID, ref ChainBuilderStats stats) @@ -253,8 +253,8 @@ static uint DepthFirstOnChildRemoving(RenderChain renderChain, VisualElement ve, } if (ve.renderChainData.dirtiedClipping) removalInfo.anyDirtiedClipping = true; - if (ve.renderChainData.dirtiedTransform) - removalInfo.anyDirtiedTransform = true; + if ((ve.renderChainData.dirtiedValues & (RenderDataDirtyTypes.Transform | RenderDataDirtyTypes.Size)) != 0) + removalInfo.anyDirtiedTransformOrSize = true; if (ve.renderChainData.dirtiedVisuals > 0) removalInfo.anyDirtiedVisuals = true; } @@ -333,13 +333,15 @@ static void DepthFirstOnClippingChanged(RenderChain renderChain, VisualElement p DepthFirstOnClippingChanged(renderChain, ve, ve.hierarchy[i], dirtyID, evenIfUpToDate, device, ref stats); } - static void DepthFirstOnTransformChanged(RenderChain renderChain, VisualElement parent, VisualElement ve, uint dirtyID, UIRenderDevice device, bool isAncestorOfChangeSkinned, ref ChainBuilderStats stats) + static void DepthFirstOnTransformOrSizeChanged(RenderChain renderChain, VisualElement parent, VisualElement ve, uint dirtyID, UIRenderDevice device, bool isAncestorOfChangeSkinned, bool transformChanged, ref ChainBuilderStats stats) { if (dirtyID == ve.renderChainData.dirtyID) return; stats.recursiveTransformUpdatesExpanded++; + transformChanged |= (ve.renderChainData.dirtiedValues & RenderDataDirtyTypes.Transform) != 0; + bool dirtyHasBeenResolved = true; if (ve.renderChainData.allocatedTransformID) { @@ -347,6 +349,10 @@ static void DepthFirstOnTransformChanged(RenderChain renderChain, VisualElement isAncestorOfChangeSkinned = true; stats.boneTransformed++; } + else if (!transformChanged) + { + // Only the clip info had to be updated, we can skip the other cases which are for transform changes only. + } else if ((ve.renderHint & RenderHint.GroupTransform) != 0) { stats.groupTransformElementsChanged++; @@ -378,7 +384,7 @@ static void DepthFirstOnTransformChanged(RenderChain renderChain, VisualElement // Recurse on children int childrenCount = ve.hierarchy.childCount; for (int i = 0; i < childrenCount; i++) - DepthFirstOnTransformChanged(renderChain, ve, ve.hierarchy[i], dirtyID, device, isAncestorOfChangeSkinned, ref stats); + DepthFirstOnTransformOrSizeChanged(renderChain, ve, ve.hierarchy[i], dirtyID, device, isAncestorOfChangeSkinned, transformChanged, ref stats); } else renderChain.OnGroupTransformElementChangedTransform(ve); // Hack until UIE moves to TMP diff --git a/Modules/UIElements/Renderer/UIRLayoutUpdater.cs b/Modules/UIElements/Renderer/UIRLayoutUpdater.cs index 9f30c8ee4a..9f547f2170 100644 --- a/Modules/UIElements/Renderer/UIRLayoutUpdater.cs +++ b/Modules/UIElements/Renderer/UIRLayoutUpdater.cs @@ -66,17 +66,23 @@ private void UpdateSubTree(VisualElement ve, int currentLayoutPass) Rect lastRect = ve.renderData.lastLayout; bool rectChanged = false; + VersionChangeType changeType = 0; + // If the last layout rect is different than the current one we must dirty transform on children if ((lastRect.width != yogaRect.width) || (lastRect.height != yogaRect.height)) { - ve.IncrementVersion(VersionChangeType.Clip | VersionChangeType.Repaint); // Layout change require a clip update + repaint + changeType |= VersionChangeType.Size | VersionChangeType.Repaint; rectChanged = true; } if (yogaRect.position != lastRect.position) { - ve.IncrementVersion(VersionChangeType.Transform); + changeType |= VersionChangeType.Transform; rectChanged = true; } + + if (changeType != 0) + ve.IncrementVersion(changeType); + ve.renderData.lastLayout = yogaRect; // ignore clean sub trees diff --git a/Modules/UIElements/Renderer/UIRRepaintUpdater.cs b/Modules/UIElements/Renderer/UIRRepaintUpdater.cs index 189c64072f..55035dd7a8 100644 --- a/Modules/UIElements/Renderer/UIRRepaintUpdater.cs +++ b/Modules/UIElements/Renderer/UIRRepaintUpdater.cs @@ -33,8 +33,10 @@ public override void OnVersionChanged(VisualElement ve, VersionChangeType versio if (renderChain == null) return; - if ((versionChangeType & (VersionChangeType.Transform | VersionChangeType.Clip)) != 0) - renderChain.UIEOnTransformChanged(ve); + bool transformChanged = (versionChangeType & VersionChangeType.Transform) != 0; + bool sizeChanged = (versionChangeType & VersionChangeType.Size) != 0; + if (transformChanged || sizeChanged) + renderChain.UIEOnTransformOrSizeChanged(ve, transformChanged, sizeChanged); if ((versionChangeType & VersionChangeType.Repaint) != 0) renderChain.UIEOnVisualsChanged(ve, false); diff --git a/Modules/UIElements/Scheduler.cs b/Modules/UIElements/Scheduler.cs index d81c8ebda5..c38f1095f3 100644 --- a/Modules/UIElements/Scheduler.cs +++ b/Modules/UIElements/Scheduler.cs @@ -111,14 +111,6 @@ internal virtual void OnItemUnscheduled() public virtual bool ShouldUnschedule() { - if (endTimeMs > 0) - { - if (Panel.TimeSinceStartupMs() > endTimeMs) - { - return true; - } - } - if (timerUpdateStopCondition != null) { return timerUpdateStopCondition(); @@ -335,22 +327,32 @@ public void UpdateScheduledEvents() ScheduledItem scheduledItem = m_ScheduledItems[index]; + bool unscheduleItem = false; + if (currentTime - scheduledItem.delayMs >= scheduledItem.startMs) { TimerState timerState = new TimerState { start = scheduledItem.startMs, now = currentTime }; - if (!m_UnscheduleTransactions.Contains(scheduledItem)) // Don't execute items that have been amrker for future removal + if (!m_UnscheduleTransactions.Contains(scheduledItem)) // Don't execute items that have been marked for future removal scheduledItem.PerformTimerUpdate(timerState); scheduledItem.startMs = currentTime; scheduledItem.delayMs = scheduledItem.intervalMs; + + if (scheduledItem.ShouldUnschedule()) + { + unscheduleItem = true; + } } - if (scheduledItem.ShouldUnschedule() && !m_UnscheduleTransactions.Contains(scheduledItem)) - // if the scheduledItem has been unscheduled explicitly in PerformTimerUpdate then it will be in m_UnscheduleTransactions and we shouldn't - // unschedule it again + if (unscheduleItem || (scheduledItem.endTimeMs > 0 && currentTime > scheduledItem.endTimeMs)) { - Unschedule(scheduledItem); + // if the scheduledItem has been unscheduled explicitly in PerformTimerUpdate then + // it will be in m_UnscheduleTransactions and we shouldn't unschedule it again + if (!m_UnscheduleTransactions.Contains(scheduledItem)) + { + Unschedule(scheduledItem); + } } m_LastUpdatedIndex = index; diff --git a/Modules/UIElements/ScrollView.cs b/Modules/UIElements/ScrollView.cs index 2927e0d8a7..9fb9146431 100644 --- a/Modules/UIElements/ScrollView.cs +++ b/Modules/UIElements/ScrollView.cs @@ -147,6 +147,7 @@ void UpdateContentViewTransform() t.y = GUIUtility.RoundToPixelGrid(-offset.y); contentContainer.transform.position = t; + // TODO: Can we get rid of this? this.IncrementVersion(VersionChangeType.Repaint); } diff --git a/Modules/UIElements/VisualElement.cs b/Modules/UIElements/VisualElement.cs index 3f846d394d..a6eb92b142 100644 --- a/Modules/UIElements/VisualElement.cs +++ b/Modules/UIElements/VisualElement.cs @@ -263,10 +263,7 @@ Vector3 ITransform.scale if (m_Scale == value) return; m_Scale = value; - IncrementVersion(VersionChangeType.Transform); - - // This will change how we measure text - IncrementVersion(VersionChangeType.Layout); + IncrementVersion(VersionChangeType.Transform | VersionChangeType.Layout /*This will change how we measure text*/); } } @@ -320,6 +317,13 @@ internal set if (isLayoutManual && m_Layout == value) return; + Rect lastLayout = layout; + VersionChangeType changeType = 0; + if (!Mathf.Approximately(lastLayout.x, value.x) || !Mathf.Approximately(lastLayout.y, value.y)) + changeType |= VersionChangeType.Transform; + if (!Mathf.Approximately(lastLayout.width, value.width) || !Mathf.Approximately(lastLayout.height, value.height)) + changeType |= VersionChangeType.Size; + // set results so we can read straight back in get without waiting for a pass m_Layout = value; isLayoutManual = true; @@ -338,7 +342,8 @@ internal set styleAccess.width = value.width; styleAccess.height = value.height; - IncrementVersion(VersionChangeType.Transform); + if (changeType != 0) + IncrementVersion(changeType); } } diff --git a/Modules/UIElements/VisualTreeLayoutUpdater.cs b/Modules/UIElements/VisualTreeLayoutUpdater.cs index 6e3ca07e5a..102360a39a 100644 --- a/Modules/UIElements/VisualTreeLayoutUpdater.cs +++ b/Modules/UIElements/VisualTreeLayoutUpdater.cs @@ -67,7 +67,7 @@ private void UpdateSubTree(VisualElement root) { root.IncrementVersion(VersionChangeType.Transform); } - root.IncrementVersion(VersionChangeType.Clip); + root.IncrementVersion(VersionChangeType.Size); root.renderData.lastLayout = yogaRect; } diff --git a/Modules/UIElements/VisualTreeTransformClipUpdater.cs b/Modules/UIElements/VisualTreeTransformClipUpdater.cs index 61346bb308..311ded33c1 100644 --- a/Modules/UIElements/VisualTreeTransformClipUpdater.cs +++ b/Modules/UIElements/VisualTreeTransformClipUpdater.cs @@ -3,6 +3,7 @@ // https://unity3d.com/legal/licenses/Unity_Reference_Only_License using System; +using System.Diagnostics; namespace UnityEngine.UIElements { @@ -18,51 +19,45 @@ public override string description public override void OnVersionChanged(VisualElement ve, VersionChangeType versionChangeType) { - if ((versionChangeType & (VersionChangeType.Transform | VersionChangeType.Clip)) == 0) + if ((versionChangeType & (VersionChangeType.Transform | VersionChangeType.Size)) == 0) return; - if ((versionChangeType & VersionChangeType.Transform) == VersionChangeType.Transform && (!ve.isWorldTransformDirty || !ve.isWorldClipDirty)) - DirtyTransformClipHierarchy(ve); // Dirty both transform and clip when the transform changes - else if ((versionChangeType & VersionChangeType.Clip) == VersionChangeType.Clip && !ve.isWorldClipDirty) - DirtyClipHierarchy(ve); + // According to the flags, what operations must be done? + bool mustDirtyWorldTransform = (versionChangeType & VersionChangeType.Transform) != 0; + bool mustDirtyWorldClip = (versionChangeType & (VersionChangeType.Transform | VersionChangeType.Size)) != 0; + + // Are these operations already done? + mustDirtyWorldTransform = mustDirtyWorldTransform && !ve.isWorldTransformDirty; + mustDirtyWorldClip = mustDirtyWorldClip && !ve.isWorldClipDirty; + + if (mustDirtyWorldTransform || mustDirtyWorldClip) + DirtyHierarchy(ve, mustDirtyWorldTransform, mustDirtyWorldClip); DirtyBoundingBoxHierarchy(ve); ++m_Version; } - private void DirtyTransformClipHierarchy(VisualElement ve) + static void DirtyHierarchy(VisualElement ve, bool mustDirtyWorldTransform, bool mustDirtyWorldClip) { - ve.isWorldTransformDirty = true; - ve.isWorldClipDirty = true; + if (mustDirtyWorldTransform) + ve.isWorldTransformDirty = true; - int count = ve.hierarchy.childCount; - for (int i = 0; i < count; i++) - { - var child = ve.hierarchy[i]; - if (child.isWorldTransformDirty && child.isWorldClipDirty) - continue; - - DirtyTransformClipHierarchy(child); - } - } - - private void DirtyClipHierarchy(VisualElement ve) - { - ve.isWorldClipDirty = true; + if (mustDirtyWorldClip) + ve.isWorldClipDirty = true; int count = ve.hierarchy.childCount; for (int i = 0; i < count; i++) { var child = ve.hierarchy[i]; - if (child.isWorldClipDirty) - continue; - DirtyClipHierarchy(child); + if (mustDirtyWorldTransform && !child.isWorldTransformDirty || + mustDirtyWorldClip && !child.isWorldClipDirty) + DirtyHierarchy(child, mustDirtyWorldTransform, mustDirtyWorldClip); } } - private void DirtyBoundingBoxHierarchy(VisualElement ve) + static void DirtyBoundingBoxHierarchy(VisualElement ve) { ve.isBoundingBoxDirty = true; var parent = ve.hierarchy.parent; diff --git a/Modules/UIElementsDebuggerEditor/StylesDebugger.cs b/Modules/UIElementsDebuggerEditor/StylesDebugger.cs index 153780ca34..71f1ecaadf 100644 --- a/Modules/UIElementsDebuggerEditor/StylesDebugger.cs +++ b/Modules/UIElementsDebuggerEditor/StylesDebugger.cs @@ -203,7 +203,6 @@ private void DrawProperties() GUILayout.EndHorizontal(); var customProperties = m_SelectedElement.specifiedStyle.m_CustomProperties; - bool anyChanged = false; if (customProperties != null && customProperties.Any()) { @@ -345,7 +344,6 @@ private void DrawProperties() if (EditorGUI.EndChangeCheck()) { - anyChanged = true; string propertyName = field.Name; var inlineStyle = typeof(IStyle).GetProperty(propertyName); inlineStyle.SetValue(m_SelectedElement.style, val, null); @@ -373,12 +371,6 @@ private void DrawProperties() EditorGUILayout.EndHorizontal(); } - - if (anyChanged) - { - m_PanelDebug.visualTree.IncrementVersion(VersionChangeType.Styles | VersionChangeType.StyleSheet | - VersionChangeType.Layout | VersionChangeType.Transform | VersionChangeType.Repaint); - } } private void InitClassList() diff --git a/Modules/VREditor/Mono/PlayerSettingsEditorVR.cs b/Modules/VREditor/Mono/PlayerSettingsEditorVR.cs index 42742768d1..9a38343ce3 100644 --- a/Modules/VREditor/Mono/PlayerSettingsEditorVR.cs +++ b/Modules/VREditor/Mono/PlayerSettingsEditorVR.cs @@ -516,16 +516,6 @@ private float GetVRDeviceElementHeight(BuildTargetGroup target, int index) return list.elementHeight + customOptionsHeight; } - private void SelectVRDeviceElement(BuildTargetGroup target, ReorderableList list) - { - string name = (string)m_VRDeviceActiveUI[target].list[list.index]; - VRCustomOptions customOptions; - if (m_CustomOptions.TryGetValue(name, out customOptions)) - { - customOptions.IsExpanded = false; - } - } - private bool GetVRDeviceElementIsInList(BuildTargetGroup target, string deviceName) { var enabledDevices = VREditor.GetVREnabledDevicesOnTargetGroup(target); @@ -536,6 +526,16 @@ private bool GetVRDeviceElementIsInList(BuildTargetGroup target, string deviceNa return false; } + private void DragVRDeviceElement(BuildTargetGroup target, ReorderableList list) + { + string name = (string)m_VRDeviceActiveUI[target].list[list.index]; + VRCustomOptions customOptions; + if (m_CustomOptions.TryGetValue(name, out customOptions)) + { + customOptions.IsExpanded = false; + } + } + private void VRDevicesGUIOneBuildTarget(BuildTargetGroup targetGroup) { // create reorderable list for this target if needed @@ -548,7 +548,7 @@ private void VRDevicesGUIOneBuildTarget(BuildTargetGroup targetGroup) rlist.drawElementCallback = (rect, index, isActive, isFocused) => DrawVRDeviceElement(targetGroup, rect, index, isActive, isFocused); rlist.drawHeaderCallback = (rect) => GUI.Label(rect, Styles.listHeader, EditorStyles.label); rlist.elementHeightCallback = (index) => GetVRDeviceElementHeight(targetGroup, index); - rlist.onSelectCallback = (list) => SelectVRDeviceElement(targetGroup, list); + rlist.onMouseDragCallback = (list) => DragVRDeviceElement(targetGroup, list); m_VRDeviceActiveUI.Add(targetGroup, rlist); } diff --git a/Projects/CSharp/UnityEditor.csproj b/Projects/CSharp/UnityEditor.csproj index 53aad59722..2033152f8f 100644 --- a/Projects/CSharp/UnityEditor.csproj +++ b/Projects/CSharp/UnityEditor.csproj @@ -616,12 +616,6 @@ Editor\Mono\StaticOcclusionCulling.bindings.cs - - Editor\Mono\SyncProject.cs - - - Editor\Mono\SyncRiderProject.cs - Editor\Mono\TagManager.bindings.cs @@ -1210,6 +1204,21 @@ Editor\Mono\CloudBuild\CloudBuild.cs + + Editor\Mono\CodeEditor\CodeEditor.cs + + + Editor\Mono\CodeEditor\CodeEditorProjectSync.cs + + + Editor\Mono\CodeEditor\DefaultExternalCodeEditor.cs + + + Editor\Mono\CodeEditor\IExternalCodeEditor.cs + + + Editor\Mono\CodeEditor\SyncVS.cs + Editor\Mono\Collab\AssetAccess.cs @@ -3556,15 +3565,6 @@ Editor\Mono\VersionControl\VCTask.bindings.cs - - Editor\Mono\VisualStudioIntegration\SolutionSynchronizationSettings.cs - - - Editor\Mono\VisualStudioIntegration\SolutionSynchronizer.cs - - - Editor\Mono\VisualStudioIntegration\UnityVSSupport.cs - Editor\Mono\WebViewEditorWindow\WebViewEditorStaticWindow.cs diff --git a/README.md b/README.md index 1d348086b4..2b546e1668 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## Unity 2019.2.0a11 C# reference source code +## Unity 2019.2.0a13 C# reference source code The C# part of the Unity engine and editor source code. May be used for reference purposes only. diff --git a/Runtime/Export/Time/Time.bindings.cs b/Runtime/Export/Time/Time.bindings.cs index 22eb7f8386..1098056661 100644 --- a/Runtime/Export/Time/Time.bindings.cs +++ b/Runtime/Export/Time/Time.bindings.cs @@ -64,8 +64,21 @@ public class Time [NativeProperty("Realtime")] public static extern float realtimeSinceStartup { get; } - // If /captureFramerate/ is set to a value larger than 0, time will advance in - public static extern int captureFramerate { get; set; } + // If /captureDeltaTime/ is set to a value larger than 0, time will advance by that increment. + public static extern float captureDeltaTime { get; set; } + + // /captureFramerate/ is a convenience (and backwards compatible) accessor for the reciprocal of /captureDeltaTime/ rounded to the nearest integer. + public static int captureFramerate + { + get + { + return captureDeltaTime == 0.0f ? 0 : (int)Mathf.Round(1.0f / captureDeltaTime); + } + set + { + captureDeltaTime = value == 0 ? 0.0f : 1.0f / value; + } + } // Returns true if inside a fixed time step callback such as FixedUpdate, otherwise false. public static extern bool inFixedTimeStep diff --git a/Runtime/Export/Unsafe/UnsafeUtilityPatched.cs b/Runtime/Export/Unsafe/UnsafeUtilityPatched.cs index 36d95d2996..dbcac70ce4 100644 --- a/Runtime/Export/Unsafe/UnsafeUtilityPatched.cs +++ b/Runtime/Export/Unsafe/UnsafeUtilityPatched.cs @@ -13,14 +13,30 @@ namespace Unity.Collections.LowLevel.Unsafe public static partial class UnsafeUtility { // Copies sizeof(T) bytes from ptr to output + [MethodImpl(256)] // AggressiveInlining unsafe public static void CopyPtrToStructure(void* ptr, out T output) where T : struct + { + if (ptr == null) + throw new ArgumentNullException(); + InternalCopyPtrToStructure(ptr, out output); + } + + unsafe static void InternalCopyPtrToStructure(void* ptr, out T output) where T : struct { // @patched at compile time throw new NotImplementedException("Patching this method failed"); } // Copies sizeof(T) bytes from output to ptr + [MethodImpl(256)] // AggressiveInlining unsafe public static void CopyStructureToPtr(ref T input, void* ptr) where T : struct + { + if (ptr == null) + throw new ArgumentNullException(); + InternalCopyStructureToPtr(ref input, ptr); + } + + unsafe static void InternalCopyStructureToPtr(ref T input, void* ptr) where T : struct { // @patched at compile time throw new NotImplementedException("Patching this method failed"); From 72264a688201fc3276e7af89a33dd6d949658638 Mon Sep 17 00:00:00 2001 From: Unity Technologies Date: Wed, 1 May 2019 17:59:12 +0000 Subject: [PATCH 2/2] Unity 2019.2.0a14 C# reference source code --- .../2D/SpriteAtlas/SpriteAtlasInspector.cs | 2 +- .../Mono/Annotation/SceneViewCameraWindow.cs | 2 +- .../Mixer/GUI/AudioMixerChannelStripView.cs | 2 +- .../GUI/AudioMixerExposedParametersPopup.cs | 2 +- .../Mixer/GUI/AudioMixerGroupViewList.cs | 2 +- .../Audio/Mixer/GUI/AudioMixerSnapshotView.cs | 2 +- .../Mono/Audio/Mixer/GUI/AudioMixerWindow.cs | 4 +- .../Audio/Mixer/GUI/AudioMixersTreeView.cs | 4 +- Editor/Mono/BuildPlayerWindow.cs | 4 +- Editor/Mono/CodeEditor/CodeEditor.cs | 11 +- Editor/Mono/CustomInspectorStubs.cs | 1 + .../EditorGUI.EnumMaskField.deprecated.cs | 2 +- Editor/Mono/EditorMode/ModeService.cs | 28 ++-- Editor/Mono/EditorResources.cs | 7 +- Editor/Mono/GUI/MaskFieldGUI.cs | 2 +- .../IHVImageFormatImporterInspector.cs | 2 +- .../TextureImporterInspector.cs | 6 +- Editor/Mono/Inspector/AnimationClipEditor.cs | 2 +- Editor/Mono/Inspector/AudioClipInspector.cs | 152 ++++++++---------- .../Mono/Inspector/AudioManagerInspector.cs | 4 +- Editor/Mono/Inspector/AudioSourceInspector.cs | 2 +- .../Inspector/Avatar/AvatarMappingEditor.cs | 4 +- Editor/Mono/Inspector/AvatarMaskInspector.cs | 4 +- Editor/Mono/Inspector/BoxColliderEditor.cs | 2 +- Editor/Mono/Inspector/CameraEditor.cs | 8 +- Editor/Mono/Inspector/Collider2DEditorBase.cs | 2 +- Editor/Mono/Inspector/CubemapInspector.cs | 2 +- .../Mono/Inspector/EditorSettingsInspector.cs | 4 +- Editor/Mono/Inspector/InspectorWindow.cs | 4 + .../Inspector/LightProbeGroupInspector.cs | 9 +- .../Inspector/LightProbeProxyVolumeEditor.cs | 6 +- .../Inspector/LightingSettingsInspector.cs | 2 +- Editor/Mono/Inspector/LineRendererEditor.cs | 2 +- Editor/Mono/Inspector/MaterialEditor.cs | 26 +-- .../PlayerSettingsEditor.cs | 8 +- .../PlayerSettingsSplashScreenEditor.cs | 2 +- .../Mono/Inspector/QualitySettingsEditor.cs | 2 +- Editor/Mono/Inspector/RectTransformEditor.cs | 2 +- .../Mono/Inspector/ReflectionProbeEditor.cs | 2 +- Editor/Mono/Inspector/RenderTextureEditor.cs | 4 +- Editor/Mono/Inspector/SpriteRendererEditor.cs | 2 +- Editor/Mono/Inspector/TimeManagerInspector.cs | 2 +- .../PlayerConnection/AttachToPlayerGUI.cs | 2 +- Editor/Mono/ObjectSelector.cs | 2 +- .../PreferencesSettingsProviders.cs | 2 +- .../Mono/ProjectWindow/ProjectWindowUtil.cs | 4 +- .../LightingWindowBakeSettings.cs | 10 +- .../SceneModeWindows/LightmapPreviewWindow.cs | 2 +- .../Mono/SceneModeWindows/NavigationWindow.cs | 2 +- .../OcclusionCullingWindow.cs | 2 +- .../SceneModeWindows/PhysicsDebugWindow.cs | 2 +- .../Implementations/ExposedReferenceDrawer.cs | 2 +- .../APIUpdater/APIUpdaterManager.bindings.cs | 2 +- Editor/Mono/SettingsWindow/FogEditor.cs | 2 +- .../SettingsWindow/GraphicsSettingsEditors.cs | 4 +- Editor/Mono/Sprites/SpriteUtilityWindow.cs | 6 +- Editor/Mono/UIElements/Controls/MaskField.cs | 2 +- .../ImportSettings/ModelImporterClipEditor.cs | 2 +- .../ModelImporterModelEditor.cs | 2 +- .../ImportSettings/ModelImporterRigEditor.cs | 6 +- .../Elements/Blackboard/Blackboard.cs | 5 + .../Editor/UI/PackageDetails.cs | 29 +++- .../Editor/UI/PackageManagerPrefs.cs | 7 + .../CollisionModuleUI.cs | 2 +- .../ParticleSystemModules/InitialModuleUI.cs | 4 +- .../ParticleSystemModules/TriggerModuleUI.cs | 4 +- .../ParticleSystemModules/UVModuleUI.cs | 2 +- .../ProfilerDetailedCallsView.cs | 4 +- .../ShortcutController.cs | 5 +- .../Mono/SketchUpImporterModelEditor.cs | 2 +- .../PaintTools/CreateTerrainTool.cs | 2 +- Modules/TerrainEditor/PaintTools/StampTool.cs | 2 +- Modules/TerrainEditor/TerrainInspector.cs | 6 +- Modules/TreeEditor/TreeEditor.cs | 6 +- .../Renderer/UIRChainBuilderImpl.cs | 8 +- .../VREditor/Mono/PlayerSettingsEditorVR.cs | 2 +- .../VideoEditor/Editor/VideoPlayerEditor.cs | 2 +- README.md | 2 +- 78 files changed, 266 insertions(+), 226 deletions(-) diff --git a/Editor/Mono/2D/SpriteAtlas/SpriteAtlasInspector.cs b/Editor/Mono/2D/SpriteAtlas/SpriteAtlasInspector.cs index 951f61703b..db10617930 100644 --- a/Editor/Mono/2D/SpriteAtlas/SpriteAtlasInspector.cs +++ b/Editor/Mono/2D/SpriteAtlas/SpriteAtlasInspector.cs @@ -64,7 +64,7 @@ class Styles public readonly GUIContent packButton = EditorGUIUtility.TrTextContent("Pack Preview", "Pack this atlas."); public readonly GUIContent disabledPackLabel = EditorGUIUtility.TrTextContent("Sprite Atlas packing is disabled. Enable it in Edit > Settings > Editor.", null, EditorGUIUtility.GetHelpIcon(MessageType.Info)); - public readonly GUIContent packableListLabel = EditorGUIUtility.TrTextContent("Objects for Packing", "Only accept Folder, Sprite Sheet(Texture) and Sprite."); + public readonly GUIContent packableListLabel = EditorGUIUtility.TrTextContent("Objects for Packing", "Only accept Folder, Sprite Sheet (Texture) and Sprite."); public readonly GUIContent notPowerOfTwoWarning = EditorGUIUtility.TrTextContent("This scale will produce a Sprite Atlas variant with a packed texture that is NPOT (non - power of two). This may cause visual artifacts in certain compression/texture formats."); diff --git a/Editor/Mono/Annotation/SceneViewCameraWindow.cs b/Editor/Mono/Annotation/SceneViewCameraWindow.cs index cb87c982ae..c33e3ab5b8 100644 --- a/Editor/Mono/Annotation/SceneViewCameraWindow.cs +++ b/Editor/Mono/Annotation/SceneViewCameraWindow.cs @@ -66,7 +66,7 @@ public SceneViewCameraWindow(SceneView sceneView) m_FieldOfView = EditorGUIUtility.TrTextContent("Field of View", "The height of the camera's view angle. Measured in degrees vertically, or along the local Y axis."); m_DynamicClip = EditorGUIUtility.TrTextContent("Dynamic Clipping", "Check this to enable camera's near and far clipping planes to be calculated relative to the viewport size of the Scene."); m_OcclusionCulling = EditorGUIUtility.TrTextContent("Occlusion Culling", "Check this to enable occlusion culling in the Scene view. Occlusion culling disables rendering of objects when they\'re not currently seen by the camera because they\'re hidden (occluded) by other objects."); - m_EasingEnabled = EditorGUIUtility.TrTextContent("Camera Easing", "Check this to enable camera movement easing. This makes the camera ease in when it starts moving, and ease out when it stops."); + m_EasingEnabled = EditorGUIUtility.TrTextContent("Camera Easing", "Check this to enable camera movement easing. This makes the camera ease in when it starts moving and ease out when it stops."); m_EasingDuration = EditorGUIUtility.TrTextContent("Duration", "How long it takes for the speed of the camera to accelerate to its initial full speed. Measured in seconds."); } diff --git a/Editor/Mono/Audio/Mixer/GUI/AudioMixerChannelStripView.cs b/Editor/Mono/Audio/Mixer/GUI/AudioMixerChannelStripView.cs index 7f3f94bd4f..bd9e8245a9 100644 --- a/Editor/Mono/Audio/Mixer/GUI/AudioMixerChannelStripView.cs +++ b/Editor/Mono/Audio/Mixer/GUI/AudioMixerChannelStripView.cs @@ -1286,7 +1286,7 @@ void DoTotaldB(ChannelStripParams p) GUI.Label(rect, string.Format(CultureInfo.InvariantCulture.NumberFormat, "{0:F1} dB", vu_level), styles.totalVULevel); } - GUIContent addText = EditorGUIUtility.TrTextContent("Add.."); + GUIContent addText = EditorGUIUtility.TrTextContent("Add..."); void DoEffectList(ChannelStripParams p, bool selected, ref int highlightEffectIndex, ref Dictionary patchslots, bool showBusConnectionsOfSelection) { Event evt = Event.current; diff --git a/Editor/Mono/Audio/Mixer/GUI/AudioMixerExposedParametersPopup.cs b/Editor/Mono/Audio/Mixer/GUI/AudioMixerExposedParametersPopup.cs index b06409045d..804643e2ef 100644 --- a/Editor/Mono/Audio/Mixer/GUI/AudioMixerExposedParametersPopup.cs +++ b/Editor/Mono/Audio/Mixer/GUI/AudioMixerExposedParametersPopup.cs @@ -23,7 +23,7 @@ internal static void Popup(AudioMixerController controller, GUIStyle style, para } // Cache to prevent constructing string on every event - static GUIContent m_ButtonContent = EditorGUIUtility.TrTextContent("", "Audio Mixer parameters can be exposed to scripting. Select an Audio Mixer Group, right click one of its properties in the Inspector and select 'Expose ..'."); + static GUIContent m_ButtonContent = EditorGUIUtility.TrTextContent("", "Audio Mixer parameters can be exposed to scripting. Select an Audio Mixer Group, right click one of its properties in the Inspector and select 'Expose'."); static int m_LastNumExposedParams = -1; static GUIContent GetButtonContent(AudioMixerController controller) { diff --git a/Editor/Mono/Audio/Mixer/GUI/AudioMixerGroupViewList.cs b/Editor/Mono/Audio/Mixer/GUI/AudioMixerGroupViewList.cs index 6823fca5d3..baab4b27d8 100644 --- a/Editor/Mono/Audio/Mixer/GUI/AudioMixerGroupViewList.cs +++ b/Editor/Mono/Audio/Mixer/GUI/AudioMixerGroupViewList.cs @@ -21,7 +21,7 @@ internal class AudioMixerGroupViewList class Styles { - public GUIContent header = EditorGUIUtility.TrTextContent("Views", "A view is the saved visiblity state of the current Mixer Groups. Use views to setup often used combinations of Mixer Groups."); + public GUIContent header = EditorGUIUtility.TrTextContent("Views", "A view is the saved visibility state of the current Mixer Groups. Use views to setup often used combinations of Mixer Groups."); public GUIContent addButton = new GUIContent("+"); public Texture2D viewsIcon = EditorGUIUtility.FindTexture("AudioMixerView Icon"); } diff --git a/Editor/Mono/Audio/Mixer/GUI/AudioMixerSnapshotView.cs b/Editor/Mono/Audio/Mixer/GUI/AudioMixerSnapshotView.cs index c021ab5a4c..5140a0f16c 100644 --- a/Editor/Mono/Audio/Mixer/GUI/AudioMixerSnapshotView.cs +++ b/Editor/Mono/Audio/Mixer/GUI/AudioMixerSnapshotView.cs @@ -22,7 +22,7 @@ internal class AudioMixerSnapshotListView class Styles { public GUIContent starIcon = new GUIContent(EditorGUIUtility.FindTexture("Favorite"), "Start snapshot"); - public GUIContent header = EditorGUIUtility.TrTextContent("Snapshots", "A snapshot is a set of values for all parameters in the mixer. When using the mixer you modify parameters in the selected snapshot. Blend between multiple snapshots at runtime."); + public GUIContent header = EditorGUIUtility.TrTextContent("Snapshots", "A snapshot is a set of values for all parameters in the mixer. When using the mixer, you modify parameters in the selected snapshot. Blend between multiple snapshots at runtime."); public GUIContent addButton = new GUIContent("+"); public Texture2D snapshotsIcon = EditorGUIUtility.FindTexture(typeof(UnityEngine.Audio.AudioMixerSnapshot)); } diff --git a/Editor/Mono/Audio/Mixer/GUI/AudioMixerWindow.cs b/Editor/Mono/Audio/Mixer/GUI/AudioMixerWindow.cs index c0172d22f3..ba9ada5dac 100644 --- a/Editor/Mono/Audio/Mixer/GUI/AudioMixerWindow.cs +++ b/Editor/Mono/Audio/Mixer/GUI/AudioMixerWindow.cs @@ -120,10 +120,10 @@ class GUIContents public GUIContents() { rms = EditorGUIUtility.TrTextContent("RMS", "Switches between RMS (Root Mean Square) metering and peak metering. RMS is closer to the energy level and perceived loudness of the sound (hence lower than the peak meter), while peak-metering is useful for monitoring spikes in the signal that can cause clipping."); - editSnapShots = EditorGUIUtility.TrTextContent("Edit in Play Mode", "Edit in playmode and your changes are automatically saved. Note when editting is disabled then live values are shown.", EditorGUIUtility.TrIconContent("Animation.Record", "Are scene and inspector changes recorded into the animation curves?").image); + editSnapShots = EditorGUIUtility.TrTextContent("Edit in Play Mode", "Edit in playmode and your changes are automatically saved. Note when editing is disabled, live values are shown.", EditorGUIUtility.TrIconContent("Animation.Record", "Are scene and inspector changes recorded into the animation curves?").image); infoText = EditorGUIUtility.TrTextContent("Create an AudioMixer asset from the Project Browser to get started"); selectAudioMixer = EditorGUIUtility.TrTextContent("", "Select an Audio Mixer"); - output = EditorGUIUtility.TrTextContent("Output", "Select an Audio Mixer Group from another Audio Mixer to output to. If 'None' is selected then output is routed directly to the Audio Listener."); + output = EditorGUIUtility.TrTextContent("Output", "Select an Audio Mixer Group from another Audio Mixer to output to. If 'None' is selected, then output is routed directly to the Audio Listener."); } } private static GUIContents s_GuiContents; diff --git a/Editor/Mono/Audio/Mixer/GUI/AudioMixersTreeView.cs b/Editor/Mono/Audio/Mixer/GUI/AudioMixersTreeView.cs index 94c6603ce1..aa06dc1127 100644 --- a/Editor/Mono/Audio/Mixer/GUI/AudioMixersTreeView.cs +++ b/Editor/Mono/Audio/Mixer/GUI/AudioMixersTreeView.cs @@ -528,8 +528,8 @@ internal class AudioMixersTreeView class Styles { - public GUIContent header = EditorGUIUtility.TrTextContent("Mixers", "All mixers in the project are shown here. By default a mixer outputs to the AudioListener but mixers can also route their output to other mixers. Each mixer shows where it outputs (in parenthesis). To reroute a mixer simply drag the mixer upon another mixer and select a group from the popup."); - public GUIContent addText = EditorGUIUtility.TrTextContent("+", "Add mixer asset. The asset will be saved in the same folder as the current selected mixer or if none is selected saved in the Assets folder."); + public GUIContent header = EditorGUIUtility.TrTextContent("Mixers", "All mixers in the project are shown here. By default, a mixer outputs to the AudioListener but mixers can also route their output to other mixers. Each mixer shows where it outputs (in parenthesis). To reroute a mixer simply drag the mixer upon another mixer and select a group from the popup."); + public GUIContent addText = EditorGUIUtility.TrTextContent("+", "Add mixer asset. The asset will be saved in the same folder as the current selected mixer or, if none is selected, saved in the Assets folder."); public Texture2D audioMixerIcon = EditorGUIUtility.FindTexture(typeof(AudioMixerController)); } static Styles s_Styles; diff --git a/Editor/Mono/BuildPlayerWindow.cs b/Editor/Mono/BuildPlayerWindow.cs index f7967bed89..803aef6bc1 100644 --- a/Editor/Mono/BuildPlayerWindow.cs +++ b/Editor/Mono/BuildPlayerWindow.cs @@ -26,8 +26,8 @@ public partial class BuildPlayerWindow : EditorWindow { class Styles { - public GUIContent invalidColorSpaceMessage = EditorGUIUtility.TrTextContent("In order to build a player go to 'Player Settings...' to resolve the incompatibility between the Color Space and the current settings.", EditorGUIUtility.GetHelpIcon(MessageType.Warning)); - public GUIContent invalidLightmapEncodingMessage = EditorGUIUtility.TrTextContent("In order to build a player go to 'Player Settings...' to resolve the incompatibility between the selected Lightmap Encoding and the current settings.", EditorGUIUtility.GetHelpIcon(MessageType.Warning)); + public GUIContent invalidColorSpaceMessage = EditorGUIUtility.TrTextContent("In order to build a player, go to 'Player Settings...' to resolve the incompatibility between the Color Space and the current settings.", EditorGUIUtility.GetHelpIcon(MessageType.Warning)); + public GUIContent invalidLightmapEncodingMessage = EditorGUIUtility.TrTextContent("In order to build a player, go to 'Player Settings...' to resolve the incompatibility between the selected Lightmap Encoding and the current settings.", EditorGUIUtility.GetHelpIcon(MessageType.Warning)); public GUIStyle selected = "OL SelectedRow"; public GUIStyle box = "OL Box"; public GUIStyle title = EditorStyles.boldLabel; diff --git a/Editor/Mono/CodeEditor/CodeEditor.cs b/Editor/Mono/CodeEditor/CodeEditor.cs index 45c6ace43d..2a9c60abf6 100644 --- a/Editor/Mono/CodeEditor/CodeEditor.cs +++ b/Editor/Mono/CodeEditor/CodeEditor.cs @@ -41,6 +41,11 @@ static bool OnOpenAsset(int instanceID, int line, int column) var selected = EditorUtility.InstanceIDToObject(instanceID); var assetPath = AssetDatabase.GetAssetPath(selected); + if (string.IsNullOrEmpty(assetPath)) + { + return false; + } + var assetFilePath = Path.GetFullPath(assetPath); if (!(selected.GetType().ToString() == "UnityEditor.MonoScript" || selected.GetType().ToString() == "UnityEngine.Shader" || @@ -52,11 +57,7 @@ static bool OnOpenAsset(int instanceID, int line, int column) return false; } - if (string.IsNullOrEmpty(assetPath)) - { - return false; - } - return Editor.Current.OpenProject(assetPath, line, column); + return Editor.Current.OpenProject(assetFilePath, line, column); } static List GetExtensionStrings() diff --git a/Editor/Mono/CustomInspectorStubs.cs b/Editor/Mono/CustomInspectorStubs.cs index 824cd94150..8645e8b7e0 100644 --- a/Editor/Mono/CustomInspectorStubs.cs +++ b/Editor/Mono/CustomInspectorStubs.cs @@ -17,6 +17,7 @@ private PhysicsManager() {} // Exposed as internal, editor-only, because we only need it do make a custom inspector [NativeClass(null)] + [ExcludeFromPreset] internal sealed class AudioManager : ProjectSettingsBase { private AudioManager() {} diff --git a/Editor/Mono/EditorGUI.EnumMaskField.deprecated.cs b/Editor/Mono/EditorGUI.EnumMaskField.deprecated.cs index 62abcbfe63..df06043570 100644 --- a/Editor/Mono/EditorGUI.EnumMaskField.deprecated.cs +++ b/Editor/Mono/EditorGUI.EnumMaskField.deprecated.cs @@ -397,7 +397,7 @@ internal static int DoMaskField(Rect position, int controlID, int mask, string[] mask = ~0; } else - buttonContent = EditorGUIUtility.TempContent("Mixed ..."); + buttonContent = EditorGUIUtility.TempContent("Mixed..."); break; } } diff --git a/Editor/Mono/EditorMode/ModeService.cs b/Editor/Mono/EditorMode/ModeService.cs index 30948226af..0185125161 100644 --- a/Editor/Mono/EditorMode/ModeService.cs +++ b/Editor/Mono/EditorMode/ModeService.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using UnityEditor.ShortcutManagement; using UnityEngine; using UnityEngine.Internal; using UnityEngine.UIElements; @@ -205,7 +206,13 @@ internal static void Refresh(CommandExecuteContext c) internal static void RaiseModeChanged(int prevIndex, int nextIndex) { modeChanged?.Invoke(new ModeChangedArgs { prevIndex = prevIndex, nextIndex = nextIndex }); - EditorUtility.Internal_UpdateAllMenus(); + + // Not required when you start the editor in the default mode. + if (prevIndex != -1 || nextIndex != 0) + { + EditorUtility.Internal_UpdateAllMenus(); + ShortcutIntegration.instance.RebuildShortcuts(); + } } internal static bool IsValidModeId(string id) @@ -216,7 +223,9 @@ internal static bool IsValidModeId(string id) private static void ScanModes() { var modesData = new Dictionary { [k_DefaultModeId] = new Dictionary { [k_LabelSectionName] = "Default" } }; - var modeFilePaths = AssetDatabase.GetAllAssetPaths().Where(IsEditorModeDescriptor).OrderBy(path => - new FileInfo(path).Length); + var modeFilePaths = AssetDatabase.FindAssets("t:DefaultAsset") + .Select(AssetDatabase.GUIDToAssetPath) + .Where(IsEditorModeDescriptor).OrderBy(path => - new FileInfo(path).Length); foreach (var modeFilePath in modeFilePaths) { var json = SJSON.Load(modeFilePath); @@ -224,16 +233,17 @@ private static void ScanModes() foreach (var rawModeId in json.Keys) { var modeId = ((string)rawModeId).ToLower(); - if (!IsValidModeId(modeId)) + if (IsValidModeId(modeId)) { - Debug.Log($"Invalid Mode Id: {modeId} contains non alphanumeric characters."); - continue; + if (modesData.ContainsKey(modeId)) + modesData[modeId] = JsonUtils.DeepMerge(modesData[modeId] as JSONObject, json[modeId] as JSONObject); + else + modesData[modeId] = json[modeId]; } - - if (modesData.ContainsKey(modeId)) - modesData[modeId] = JsonUtils.DeepMerge(modesData[modeId] as JSONObject, json[modeId] as JSONObject); else - modesData[modeId] = json[modeId]; + { + Debug.LogWarning($"Invalid Mode Id: {modeId} contains non alphanumeric characters."); + } } } diff --git a/Editor/Mono/EditorResources.cs b/Editor/Mono/EditorResources.cs index c06dc22de6..c4b14caa25 100644 --- a/Editor/Mono/EditorResources.cs +++ b/Editor/Mono/EditorResources.cs @@ -21,7 +21,6 @@ public partial class EditorResources static EditorResources() { styleCatalog = new StyleCatalog(); - styleCatalog.Load(GetDefaultStyleCatalogPaths()); } private static bool CanEnableExtendedStyles() @@ -57,7 +56,7 @@ internal static void BuildCatalog() { styleCatalog = new StyleCatalog(); var paths = GetDefaultStyleCatalogPaths(); - foreach (var editorUssPath in AssetDatabase.GetAllAssetPaths().Where(IsEditorStyleSheet)) + foreach (var editorUssPath in AssetDatabase.FindAssets("t:StyleSheet").Select(AssetDatabase.GUIDToAssetPath).Where(IsEditorStyleSheet)) paths.Add(editorUssPath); styleCatalog.Load(paths); @@ -67,7 +66,9 @@ internal static void BuildCatalog() var skin = GUIUtility.GetDefaultSkin(); if (skin != null) { - ConverterUtils.ResetSkinToPristine(skin, EditorGUIUtility.isProSkin ? SkinTarget.Dark : SkinTarget.Light); + // TODO: Emit OnStyleCatalogLoaded + if (Path.GetFileName(Path.GetDirectoryName(Application.dataPath)) == "editor_resources") + ConverterUtils.ResetSkinToPristine(skin, EditorGUIUtility.isProSkin ? SkinTarget.Dark : SkinTarget.Light); UpdateGUIStyleProperties(skin); } } diff --git a/Editor/Mono/GUI/MaskFieldGUI.cs b/Editor/Mono/GUI/MaskFieldGUI.cs index 1a667890de..2d5ea383eb 100644 --- a/Editor/Mono/GUI/MaskFieldGUI.cs +++ b/Editor/Mono/GUI/MaskFieldGUI.cs @@ -172,7 +172,7 @@ internal static void GetMenuOptions(int mask, string[] flagNames, int[] flagValu var flagEndIndex = flagStartIndex + flagCount; // Button text - buttonText = "Mixed ..."; + buttonText = "Mixed..."; if (mask == 0) buttonText = nothingName; else if (mask == ~0) diff --git a/Editor/Mono/ImportSettings/IHVImageFormatImporterInspector.cs b/Editor/Mono/ImportSettings/IHVImageFormatImporterInspector.cs index d7984454a5..88c0808163 100644 --- a/Editor/Mono/ImportSettings/IHVImageFormatImporterInspector.cs +++ b/Editor/Mono/ImportSettings/IHVImageFormatImporterInspector.cs @@ -29,7 +29,7 @@ internal class Styles public static readonly GUIContent sRGBTexture = EditorGUIUtility.TrTextContent("sRGB (Color Texture)", "Texture content is stored in gamma space. Non-HDR color textures should enable this flag (except if used for IMGUI)."); public static readonly GUIContent wrapMode = EditorGUIUtility.TrTextContent("Wrap Mode"); public static readonly GUIContent filterMode = EditorGUIUtility.TrTextContent("Filter Mode"); - public static readonly GUIContent streamingMipmaps = EditorGUIUtility.TrTextContent("Streaming Mip Maps", "Only load larger mip maps as needed to render the current game cameras."); + public static readonly GUIContent streamingMipmaps = EditorGUIUtility.TrTextContent("Streaming Mipmaps", "Only load larger mipmaps as needed to render the current game cameras."); public static readonly GUIContent streamingMipmapsPriority = EditorGUIUtility.TrTextContent("Mip Map Priority", "Mip map streaming priority when there's contention for resources. Positive numbers represent higher priority. Valid range is -128 to 127."); public static readonly int[] filterModeValues = diff --git a/Editor/Mono/ImportSettings/TextureImporterInspector.cs b/Editor/Mono/ImportSettings/TextureImporterInspector.cs index 3a4c5614e3..277a7f420a 100644 --- a/Editor/Mono/ImportSettings/TextureImporterInspector.cs +++ b/Editor/Mono/ImportSettings/TextureImporterInspector.cs @@ -225,7 +225,7 @@ internal class Styles public readonly GUIContent[] cubemapOptions = { EditorGUIUtility.TrTextContent("Auto"), - EditorGUIUtility.TrTextContent("6 Frames Layout (Cubic Environment)", "Texture contains 6 images arranged in one of the standard cubemap layouts - cross or sequence (+x,-x, +y, -y, +z, -z). Texture can be in vertical or horizontal orientation."), + EditorGUIUtility.TrTextContent("6 Frames Layout (Cubic Environment)", "Texture contains 6 images arranged in one of the standard cubemap layouts - cross or sequence (+x, -x, +y, -y, +z, -z). Texture can be in vertical or horizontal orientation."), EditorGUIUtility.TrTextContent("Latitude-Longitude Layout (Cylindrical)", "Texture contains an image of a ball unwrapped such that latitude and longitude are mapped to horizontal and vertical dimensions (as on a globe)."), EditorGUIUtility.TrTextContent("Mirrored Ball (Spheremap)", "Texture contains an image of a mirrored ball.") }; @@ -258,7 +258,7 @@ internal class Styles public readonly GUIContent mipmapFadeOutToggle = EditorGUIUtility.TrTextContent("Fadeout Mip Maps"); public readonly GUIContent mipmapFadeOut = EditorGUIUtility.TrTextContent("Fade Range"); public readonly GUIContent readWrite = EditorGUIUtility.TrTextContent("Read/Write Enabled", "Enable to be able to access the raw pixel data from code."); - public readonly GUIContent streamingMipmaps = EditorGUIUtility.TrTextContent("Streaming Mip Maps", "Only load larger mip maps as needed to render the current game cameras. Requires texture streaming to be enabled in quality settings."); + public readonly GUIContent streamingMipmaps = EditorGUIUtility.TrTextContent("Streaming Mipmaps", "Only load larger mipmaps as needed to render the current game cameras. Requires texture streaming to be enabled in quality settings."); public readonly GUIContent streamingMipmapsPriority = EditorGUIUtility.TrTextContent("Mip Map Priority", "Mip map streaming priority when there's contention for resources. Positive numbers represent higher priority. Valid range is -128 to 127."); public readonly GUIContent alphaSource = EditorGUIUtility.TrTextContent("Alpha Source", "How is the alpha generated for the imported texture."); @@ -298,7 +298,7 @@ internal class Styles EditorGUIUtility.TrTextContent("Box"), EditorGUIUtility.TrTextContent("Kaiser"), }; - public readonly GUIContent npot = EditorGUIUtility.TrTextContent("Non Power of 2", "How non-power-of-two textures are scaled on import."); + public readonly GUIContent npot = EditorGUIUtility.TrTextContent("Non-Power of 2", "How non-power-of-two textures are scaled on import."); public readonly GUIContent generateCubemap = EditorGUIUtility.TrTextContent("Generate Cubemap"); public readonly GUIContent compressionQuality = EditorGUIUtility.TrTextContent("Compressor Quality"); diff --git a/Editor/Mono/Inspector/AnimationClipEditor.cs b/Editor/Mono/Inspector/AnimationClipEditor.cs index d27b66a2bc..083203825a 100644 --- a/Editor/Mono/Inspector/AnimationClipEditor.cs +++ b/Editor/Mono/Inspector/AnimationClipEditor.cs @@ -45,7 +45,7 @@ private static class Styles public static GUIContent HasAdditiveReferencePose = EditorGUIUtility.TrTextContent("Additive Reference Pose", "Enable to define the additive reference pose frame."); public static GUIContent AdditiveReferencePoseFrame = EditorGUIUtility.TrTextContent("Pose Frame", "Pose Frame."); - public static GUIContent LoopTime = EditorGUIUtility.TrTextContent("Loop Time", "Enable to make the animation plays through and then restarts when the end is reached."); + public static GUIContent LoopTime = EditorGUIUtility.TrTextContent("Loop Time", "Enable to make the animation play through and then restart when the end is reached."); public static GUIContent LoopPose = EditorGUIUtility.TrTextContent("Loop Pose", "Enable to make the animation loop seamlessly."); public static GUIContent LoopCycleOffset = EditorGUIUtility.TrTextContent("Cycle Offset", "Offset to the cycle of a looping animation, if we want to start it at a different time."); public static GUIContent RootTransformRotation = EditorGUIUtility.TrTextContent("Root Transform Rotation"); diff --git a/Editor/Mono/Inspector/AudioClipInspector.cs b/Editor/Mono/Inspector/AudioClipInspector.cs index 4c0a30c4a4..560bb3c8da 100644 --- a/Editor/Mono/Inspector/AudioClipInspector.cs +++ b/Editor/Mono/Inspector/AudioClipInspector.cs @@ -11,19 +11,19 @@ namespace UnityEditor internal class AudioClipInspector : Editor { private PreviewRenderUtility m_PreviewUtility; - - // Any number of AudioClip inspectors can be docked in addition to the object browser, and they are all showing and modifying the same shared state. - static AudioClipInspector m_PlayingInspector; - static AudioClip m_PlayingClip; - static bool playing { get { return m_PlayingClip != null && AudioUtil.IsClipPlaying(m_PlayingClip); } } - static bool m_bAutoPlay; - static bool m_bLoop; - + private AudioClip m_Clip; + private bool playing => s_PlayingInstance == this && AudioUtil.IsClipPlaying(m_Clip); Vector2 m_Position = Vector2.zero; - Rect m_wantedRect; + private bool m_MultiEditing; static GUIStyle s_PreButton; + static Rect s_WantedRect; + static bool s_AutoPlay; + static bool s_Loop; + static bool s_PlayFirst; + static AudioClipInspector s_PlayingInstance; + static GUIContent[] s_PlayIcons = {null, null}; static GUIContent[] s_AutoPlayIcons = {null, null}; static GUIContent[] s_LoopIcons = {null, null}; @@ -32,8 +32,10 @@ internal class AudioClipInspector : Editor private Material m_HandleLinesMaterial; - override public void OnInspectorGUI() + public override void OnInspectorGUI() { + // We can't always check this from preview methods + m_MultiEditing = targets.Length > 1; // Override with inspector that doesn't show anything } @@ -43,7 +45,8 @@ static void Init() return; s_PreButton = "preButton"; - m_bAutoPlay = EditorPrefs.GetBool("AutoPlayAudio", false); + s_AutoPlay = EditorPrefs.GetBool("AutoPlayAudio", false); + s_Loop = false; s_AutoPlayIcons[0] = EditorGUIUtility.TrIconContent("preAudioAutoPlayOff", "Turn Auto Play on"); s_AutoPlayIcons[1] = EditorGUIUtility.TrIconContent("preAudioAutoPlayOn", "Turn Auto Play off"); @@ -57,14 +60,13 @@ static void Init() public void OnDisable() { - // This check is necessary because the order of OnEnable/OnDisable varies depending on whether the inspector is embedded in the project browser or object selector. - if (m_PlayingInspector == this) + if (s_PlayingInstance == this) { AudioUtil.StopAllClips(); - m_PlayingClip = null; + s_PlayingInstance = null; } - EditorPrefs.SetBool("AutoPlayAudio", m_bAutoPlay); + EditorPrefs.SetBool("AutoPlayAudio", s_AutoPlay); if (m_PreviewUtility != null) { @@ -77,11 +79,9 @@ public void OnDisable() public void OnEnable() { - AudioUtil.StopAllClips(); - m_PlayingClip = null; - m_PlayingInspector = this; - - m_bAutoPlay = EditorPrefs.GetBool("AutoPlayAudio", false); + s_AutoPlay = EditorPrefs.GetBool("AutoPlayAudio", false); + if (s_AutoPlay) + s_PlayFirst = true; m_HandleLinesMaterial = EditorGUIUtility.LoadRequired("SceneView/HandleLines.mat") as Material; } @@ -119,64 +119,42 @@ public override void OnPreviewSettings() if (s_DefaultIcon == null) Init(); AudioClip clip = target as AudioClip; - - bool isEditingMultipleObjects = targets.Length > 1; + m_MultiEditing = targets.Length > 1; using (new EditorGUI.DisabledScope(AudioUtil.IsMovieAudio(clip))) { - bool oldAutoPlay = m_bAutoPlay; - bool newAutoPlay = PreviewGUI.CycleButton(oldAutoPlay ? 1 : 0, s_AutoPlayIcons) != 0; - if (oldAutoPlay != newAutoPlay) + using (new EditorGUI.DisabledScope(m_MultiEditing)) { - m_bAutoPlay = newAutoPlay; - InspectorWindow.RepaintAllInspectors(); + s_AutoPlay = s_AutoPlay && !m_MultiEditing; + s_AutoPlay = PreviewGUI.CycleButton(s_AutoPlay ? 1 : 0, s_AutoPlayIcons) != 0; } - bool oldLoop = m_bLoop; - bool newLoop = PreviewGUI.CycleButton(oldLoop ? 1 : 0, s_LoopIcons) != 0; - if (oldLoop != newLoop) - { - m_bLoop = newLoop; - if (playing) - AudioUtil.LoopClip(clip, newLoop); - InspectorWindow.RepaintAllInspectors(); - } + bool loop = s_Loop; + s_Loop = PreviewGUI.CycleButton(s_Loop ? 1 : 0, s_LoopIcons) != 0; + if ((loop != s_Loop) && playing) + AudioUtil.LoopClip(clip, s_Loop); - using (new EditorGUI.DisabledScope(isEditingMultipleObjects && !playing && m_PlayingInspector != this)) + using (new EditorGUI.DisabledScope(m_MultiEditing && !playing)) { - bool curPlaying = m_PlayingInspector == this && playing; - bool newPlaying = PreviewGUI.CycleButton(curPlaying ? 1 : 0, s_PlayIcons) != 0; + bool newPlaying = PreviewGUI.CycleButton(playing ? 1 : 0, s_PlayIcons) != 0; - if (newPlaying != curPlaying) + if (newPlaying != playing) { - AudioUtil.StopAllClips(); - m_PlayingClip = null; - m_PlayingInspector = null; - - if (newPlaying && !isEditingMultipleObjects) - { - AudioUtil.PlayClip(clip, 0, m_bLoop); - m_PlayingClip = clip; - m_PlayingInspector = this; - } + if (newPlaying) + PlayClip(clip, 0, s_Loop); + else + m_Clip = null; } } } + } - // autoplay start? - if (m_bAutoPlay && m_PlayingClip != clip && m_PlayingInspector == this && !isEditingMultipleObjects) - { - AudioUtil.StopAllClips(); - m_PlayingClip = null; - m_PlayingInspector = null; - - if (!isEditingMultipleObjects) - { - AudioUtil.PlayClip(clip, 0, m_bLoop); - m_PlayingClip = clip; - m_PlayingInspector = this; - } - } + void PlayClip(AudioClip clip, int startSample = 0, bool loop = false) + { + AudioUtil.StopAllClips(); + AudioUtil.PlayClip(clip, startSample, loop); + m_Clip = clip; + s_PlayingInstance = this; } // Passing in clip and importer separately as we're not completely done with the asset setup at the time we're asked to generate the preview. @@ -228,8 +206,6 @@ public override void OnPreviewGUI(Rect r, GUIStyle background) Event evt = Event.current; if (evt.type != EventType.Repaint && evt.type != EventType.Layout && evt.type != EventType.Used) { - int px2sample = (AudioUtil.GetSampleCount(clip) / (int)r.width); - switch (evt.type) { case EventType.MouseDrag: @@ -237,14 +213,11 @@ public override void OnPreviewGUI(Rect r, GUIStyle background) { if (r.Contains(evt.mousePosition) && !AudioUtil.IsMovieAudio(clip)) { - if (m_PlayingClip != clip || !AudioUtil.IsClipPlaying(clip)) - { - AudioUtil.StopAllClips(); - AudioUtil.PlayClip(clip, 0, m_bLoop); - m_PlayingClip = clip; - m_PlayingInspector = this; - } - AudioUtil.SetClipSamplePosition(clip, px2sample * (int)evt.mousePosition.x); + var startSample = (int)(evt.mousePosition.x * (AudioUtil.GetSampleCount(clip) / (int)r.width)); + if (!AudioUtil.IsClipPlaying(clip) || clip != m_Clip) + PlayClip(clip, startSample, s_Loop); + else + AudioUtil.SetClipSamplePosition(clip, startSample); evt.Use(); } } @@ -257,8 +230,8 @@ public override void OnPreviewGUI(Rect r, GUIStyle background) background.Draw(r, false, false, false, false); int c = AudioUtil.GetChannelCount(clip); - m_wantedRect = new Rect(r.x, r.y , r.width, r.height); - float sec2px = ((float)m_wantedRect.width / clip.length); + s_WantedRect = new Rect(r.x, r.y , r.width, r.height); + float sec2px = ((float)s_WantedRect.width / clip.length); bool previewAble = AudioUtil.HasPreview(clip) || !(AudioUtil.IsTrackerFile(clip) || AudioUtil.IsMovieAudio(clip)); if (!previewAble) @@ -284,50 +257,57 @@ public override void OnPreviewGUI(Rect r, GUIStyle background) EditorGUI.DropShadowLabel(new Rect(r.x, labelY, r.width, 20), "Can not show PCM data for this file"); } - if (m_PlayingInspector == this && m_PlayingClip == clip) + if (m_Clip == clip) { float t = AudioUtil.GetClipPosition(clip); System.TimeSpan ts = new System.TimeSpan(0, 0, 0, 0, (int)(t * 1000.0f)); - EditorGUI.DropShadowLabel(new Rect(m_wantedRect.x, m_wantedRect.y, m_wantedRect.width, 20), string.Format("Playing - {0:00}:{1:00}.{2:000}", ts.Minutes, ts.Seconds, ts.Milliseconds)); + EditorGUI.DropShadowLabel(new Rect(s_WantedRect.x, s_WantedRect.y, s_WantedRect.width, 20), string.Format("Playing - {0:00}:{1:00}.{2:000}", ts.Minutes, ts.Seconds, ts.Milliseconds)); } } else { - PreviewGUI.BeginScrollView(m_wantedRect, m_Position, m_wantedRect, "PreHorizontalScrollbar", "PreHorizontalScrollbarThumb"); + PreviewGUI.BeginScrollView(s_WantedRect, m_Position, s_WantedRect, "PreHorizontalScrollbar", "PreHorizontalScrollbarThumb"); if (Event.current.type == EventType.Repaint) { - DoRenderPreview(true, clip, AudioUtil.GetImporterFromClip(clip), m_wantedRect, 1.0f); + DoRenderPreview(true, clip, AudioUtil.GetImporterFromClip(clip), s_WantedRect, 1.0f); } for (int i = 0; i < c; ++i) { if (c > 1 && r.width > 64) { - var labelRect = new Rect(m_wantedRect.x + 5, m_wantedRect.y + (m_wantedRect.height / c) * i, 30, 20); + var labelRect = new Rect(s_WantedRect.x + 5, s_WantedRect.y + (s_WantedRect.height / c) * i, 30, 20); EditorGUI.DropShadowLabel(labelRect, "ch " + (i + 1).ToString()); } } - if (m_PlayingInspector == this && m_PlayingClip == clip) + if (m_Clip == clip) { float t = AudioUtil.GetClipPosition(clip); System.TimeSpan ts = new System.TimeSpan(0, 0, 0, 0, (int)(t * 1000.0f)); - GUI.DrawTexture(new Rect(m_wantedRect.x + (int)(sec2px * t), m_wantedRect.y, 2, m_wantedRect.height), EditorGUIUtility.whiteTexture); + GUI.DrawTexture(new Rect(s_WantedRect.x + (int)(sec2px * t), s_WantedRect.y, 2, s_WantedRect.height), EditorGUIUtility.whiteTexture); if (r.width > 64) - EditorGUI.DropShadowLabel(new Rect(m_wantedRect.x, m_wantedRect.y, m_wantedRect.width, 20), string.Format("{0:00}:{1:00}.{2:000}", ts.Minutes, ts.Seconds, ts.Milliseconds)); + EditorGUI.DropShadowLabel(new Rect(s_WantedRect.x, s_WantedRect.y, s_WantedRect.width, 20), string.Format("{0:00}:{1:00}.{2:000}", ts.Minutes, ts.Seconds, ts.Milliseconds)); else - EditorGUI.DropShadowLabel(new Rect(m_wantedRect.x, m_wantedRect.y, m_wantedRect.width, 20), string.Format("{0:00}:{1:00}", ts.Minutes, ts.Seconds)); + EditorGUI.DropShadowLabel(new Rect(s_WantedRect.x, s_WantedRect.y, s_WantedRect.width, 20), string.Format("{0:00}:{1:00}", ts.Minutes, ts.Seconds)); } - PreviewGUI.EndScrollView(); } + + if (!m_MultiEditing && (s_PlayFirst || (s_AutoPlay && m_Clip != clip))) + { + // Autoplay preview + PlayClip(clip, 0, s_Loop); + s_PlayFirst = false; + } + // force update GUI if (playing) GUIView.current.Repaint(); diff --git a/Editor/Mono/Inspector/AudioManagerInspector.cs b/Editor/Mono/Inspector/AudioManagerInspector.cs index 814440c843..517d27e005 100644 --- a/Editor/Mono/Inspector/AudioManagerInspector.cs +++ b/Editor/Mono/Inspector/AudioManagerInspector.cs @@ -21,11 +21,11 @@ private class Styles public static GUIContent SampleRate = EditorGUIUtility.TrTextContent("System Sample Rate", "Sample rate at which the output device of the audio system runs. Individual sounds may run at different sample rates and will be slowed down/sped up accordingly to match the output rate."); public static GUIContent DSPBufferSize = EditorGUIUtility.TrTextContent("DSP Buffer Size", "Length of mixing buffer. This determines the output latency of the game."); public static GUIContent VirtualVoiceCount = EditorGUIUtility.TrTextContent("Max Virtual Voices", "Maximum number of sounds managed by the system. Even though at most RealVoiceCount of the loudest sounds will be physically playing, the remaining sounds will still be updating their play position."); - public static GUIContent RealVoiceCount = EditorGUIUtility.TrTextContent("Max Real Voices", "Maximum number of actual simultanously playing sounds."); + public static GUIContent RealVoiceCount = EditorGUIUtility.TrTextContent("Max Real Voices", "Maximum number of actual simultaneously playing sounds."); public static GUIContent SpatializerPlugin = EditorGUIUtility.TrTextContent("Spatializer Plugin", "Native audio plugin performing spatialized filtering of 3D sources."); public static GUIContent AmbisonicDecoderPlugin = EditorGUIUtility.TrTextContent("Ambisonic Decoder Plugin", "Native audio plugin performing ambisonic-to-binaural filtering of sources."); public static GUIContent DisableAudio = EditorGUIUtility.TrTextContent("Disable Unity Audio", "Prevent allocating the output device in the runtime. Use this if you want to use other sound systems than the built-in one."); - public static GUIContent VirtualizeEffects = EditorGUIUtility.TrTextContent("Virtualize Effects", "When enabled dynamically turn off effects and spatializers on AudioSources that are culled in order to save CPU."); + public static GUIContent VirtualizeEffects = EditorGUIUtility.TrTextContent("Virtualize Effects", "When enabled, dynamically turn off effects and spatializers on AudioSources that are culled in order to save CPU."); public static GUIContent DSPBufferSizeInfo = EditorGUIUtility.TrTextContent("The requested buffer size ({0}) has been overridden to {1} by the operating system"); } diff --git a/Editor/Mono/Inspector/AudioSourceInspector.cs b/Editor/Mono/Inspector/AudioSourceInspector.cs index 428a8ee663..d30de59e14 100644 --- a/Editor/Mono/Inspector/AudioSourceInspector.cs +++ b/Editor/Mono/Inspector/AudioSourceInspector.cs @@ -87,7 +87,7 @@ internal static class Styles public static GUIContent rolloffLabel = EditorGUIUtility.TrTextContent("Volume Rolloff", "Which type of rolloff curve to use"); public static string controlledByCurveLabel = "Controlled by curve"; public static GUIContent audioClipLabel = EditorGUIUtility.TrTextContent("AudioClip", "The AudioClip asset played by the AudioSource. Can be undefined if the AudioSource is generating a live stream of audio via OnAudioFilterRead."); - public static GUIContent panStereoLabel = EditorGUIUtility.TrTextContent("Stereo Pan", "Only valid for Mono and Stereo AudioClips. Mono sounds will be panned at constant power left and right. Stereo sounds will Stereo sounds have each left/right value faded up and down according to the specified pan value."); + public static GUIContent panStereoLabel = EditorGUIUtility.TrTextContent("Stereo Pan", "Only valid for Mono and Stereo AudioClips. Mono sounds will be panned at constant power left and right. Stereo sounds will have each left/right value faded up and down according to the specified pan value."); public static GUIContent spatialBlendLabel = EditorGUIUtility.TrTextContent("Spatial Blend", "Sets how much this AudioSource is treated as a 3D source. 3D sources are affected by spatial position and spread. If 3D Pan Level is 0, all spatial attenuation is ignored."); public static GUIContent reverbZoneMixLabel = EditorGUIUtility.TrTextContent("Reverb Zone Mix", "Sets how much of the signal this AudioSource is mixing into the global reverb associated with the zones. [0, 1] is a linear range (like volume) while [1, 1.1] lets you boost the reverb mix by 10 dB."); public static GUIContent dopplerLevelLabel = EditorGUIUtility.TrTextContent("Doppler Level", "Specifies how much the pitch is changed based on the relative velocity between AudioListener and AudioSource."); diff --git a/Editor/Mono/Inspector/Avatar/AvatarMappingEditor.cs b/Editor/Mono/Inspector/Avatar/AvatarMappingEditor.cs index 9cf9bfb61a..0a401c9782 100644 --- a/Editor/Mono/Inspector/Avatar/AvatarMappingEditor.cs +++ b/Editor/Mono/Inspector/Avatar/AvatarMappingEditor.cs @@ -58,8 +58,8 @@ internal class Styles public GUIContent enforceTPose = EditorGUIUtility.TrTextContent("Enforce T-Pose"); public GUIContent bipedPose = EditorGUIUtility.TrTextContent("Biped Pose"); - public GUIContent ShowError = EditorGUIUtility.TrTextContent("Show Error (s)..."); - public GUIContent CloseError = EditorGUIUtility.TrTextContent("Close Error (s)"); + public GUIContent ShowError = EditorGUIUtility.TrTextContent("Show Error(s)..."); + public GUIContent CloseError = EditorGUIUtility.TrTextContent("Close Error(s)"); public GUIContent dotFill = EditorGUIUtility.IconContent("AvatarInspector/DotFill"); public GUIContent dotFrame = EditorGUIUtility.IconContent("AvatarInspector/DotFrame"); diff --git a/Editor/Mono/Inspector/AvatarMaskInspector.cs b/Editor/Mono/Inspector/AvatarMaskInspector.cs index 833754b968..8e26aacf61 100644 --- a/Editor/Mono/Inspector/AvatarMaskInspector.cs +++ b/Editor/Mono/Inspector/AvatarMaskInspector.cs @@ -162,10 +162,10 @@ internal class AvatarMaskInspector : Editor private static class Styles { // Model Importer related options - public static GUIContent MaskDefinition = EditorGUIUtility.TrTextContent("Definition", "Choose between Create From This Model, Copy From Other Avatar. The first one create a Mask for this file and the second one use a Mask from another file to import animation."); + public static GUIContent MaskDefinition = EditorGUIUtility.TrTextContent("Definition", "Choose between Create From This Model, Copy From Other Avatar. The first one creates a Mask for this file and the second one uses a Mask from another file to import animation."); public static GUIContent[] MaskDefinitionOpt = { - EditorGUIUtility.TrTextContent("Create From This Model", "Create a Mask based on the model from this file. For Humanoid rig all the human transform are always imported and converted to muscle curve, thus they cannot be unchecked."), + EditorGUIUtility.TrTextContent("Create From This Model", "Create a Mask based on the model from this file. For Humanoid rig all the human transforms are always imported and converted to muscle curve, thus they cannot be unchecked."), EditorGUIUtility.TrTextContent("Copy From Other Mask", "Copy a Mask from another file to import animation clip."), EditorGUIUtility.TrTextContent("None ", " Import Everything") }; diff --git a/Editor/Mono/Inspector/BoxColliderEditor.cs b/Editor/Mono/Inspector/BoxColliderEditor.cs index f799393a69..8abf235907 100644 --- a/Editor/Mono/Inspector/BoxColliderEditor.cs +++ b/Editor/Mono/Inspector/BoxColliderEditor.cs @@ -15,7 +15,7 @@ internal class BoxColliderEditor : PrimitiveCollider3DEditor SerializedProperty m_Size; private readonly BoxBoundsHandle m_BoundsHandle = new BoxBoundsHandle(); - protected GUIContent centerContent = EditorGUIUtility.TrTextContent("Center", "The position of the Collider in the object’s local space."); + protected GUIContent centerContent = EditorGUIUtility.TrTextContent("Center", "The position of the Collider in the object's local space."); protected GUIContent sizeContent = EditorGUIUtility.TrTextContent("Size", "The size of the Collider in the X, Y, Z directions."); diff --git a/Editor/Mono/Inspector/CameraEditor.cs b/Editor/Mono/Inspector/CameraEditor.cs index 1a1ca5eec8..dd8e4bf066 100644 --- a/Editor/Mono/Inspector/CameraEditor.cs +++ b/Editor/Mono/Inspector/CameraEditor.cs @@ -29,17 +29,17 @@ private static class Styles public static GUIContent background = EditorGUIUtility.TrTextContent("Background", "The Camera clears the screen to this color before rendering."); public static GUIContent projection = EditorGUIUtility.TrTextContent("Projection", "How the Camera renders perspective.\n\nChoose Perspective to render objects with perspective.\n\nChoose Orthographic to render objects uniformly, with no sense of perspective."); public static GUIContent size = EditorGUIUtility.TrTextContent("Size", "The vertical size of the camera view."); - public static GUIContent fieldOfView = EditorGUIUtility.TrTextContent("Field of View", "The camera’s view angle measured in degrees along the selected axis."); - public static GUIContent viewportRect = EditorGUIUtility.TrTextContent("Viewport Rect", "Four values that indicate where on the screen this camera view will be drawn. Measured in Viewport Coordinates (values 0–1)."); + public static GUIContent fieldOfView = EditorGUIUtility.TrTextContent("Field of View", "The camera's view angle measured in degrees along the selected axis."); + public static GUIContent viewportRect = EditorGUIUtility.TrTextContent("Viewport Rect", "Four values that indicate where on the screen this camera view will be drawn. Measured in Viewport Coordinates (values 0-1)."); public static GUIContent sensorSize = EditorGUIUtility.TrTextContent("Sensor Size", "The size of the camera sensor in millimeters."); public static GUIContent lensShift = EditorGUIUtility.TrTextContent("Lens Shift", "Offset from the camera sensor. Use these properties to simulate a shift lens. Measured as a multiple of the sensor size."); public static GUIContent physicalCamera = EditorGUIUtility.TrTextContent("Physical Camera", "Enables Physical camera mode. When checked, the field of view is calculated from properties for simulating physical attributes (focal length, sensor size, and lens shift)"); public static GUIContent cameraType = EditorGUIUtility.TrTextContent("Sensor Type", "Common sensor sizes. Choose an item to set Sensor Size, or edit Sensor Size for your custom settings."); - public static GUIContent renderingPath = EditorGUIUtility.TrTextContent("Rendering Path", "Choose a rendering method for this camera.\n\nUse Graphics Settings to use the rendering path specified in Player settings.\n\nUse Forward to render all objects with one pass per material.\n\nUse Deferred to draw all objects once without lighting and then draw the lighting of all objects at the end of the render queue.\n\nUse Legacy Vertex Lit to to render all lights in a single pass, calculated in vertices.\n\nLegacy Deferred has been deprecated."); + public static GUIContent renderingPath = EditorGUIUtility.TrTextContent("Rendering Path", "Choose a rendering method for this camera.\n\nUse Graphics Settings to use the rendering path specified in Player settings.\n\nUse Forward to render all objects with one pass per material.\n\nUse Deferred to draw all objects once without lighting and then draw the lighting of all objects at the end of the render queue.\n\nUse Legacy Vertex Lit to render all lights in a single pass, calculated in vertices.\n\nLegacy Deferred has been deprecated."); public static GUIContent focalLength = EditorGUIUtility.TrTextContent("Focal Length", "The simulated distance between the lens and the sensor of the physical camera. Larger values give a narrower field of view."); public static GUIContent allowOcclusionCulling = EditorGUIUtility.TrTextContent("Occlusion Culling", "Occlusion Culling means that objects that are hidden behind other objects are not rendered, for example if they are behind walls."); public static GUIContent allowHDR = EditorGUIUtility.TrTextContent("HDR", "High Dynamic Range gives you a wider range of light intensities, so your lighting looks more realistic. With it, you can still see details and experience less saturation even with bright light."); - public static GUIContent allowMSAA = EditorGUIUtility.TrTextContent("MSAA", "Use Multi Sample Anti-Aliasing to reduce aliasing."); + public static GUIContent allowMSAA = EditorGUIUtility.TrTextContent("MSAA", "Use Multi Sample Anti-aliasing to reduce aliasing."); public static GUIContent gateFit = EditorGUIUtility.TrTextContent("Gate Fit", "Determines how the rendered area (resolution gate) fits into the sensor area (film gate)."); public static GUIContent allowDynamicResolution = EditorGUIUtility.TrTextContent("Allow Dynamic Resolution", "Scales render textures to support dynamic resolution if the target platform/graphics API supports it."); public static GUIContent FOVAxisMode = EditorGUIUtility.TrTextContent("FOV Axis", "Field of view axis."); diff --git a/Editor/Mono/Inspector/Collider2DEditorBase.cs b/Editor/Mono/Inspector/Collider2DEditorBase.cs index afe94e682a..3ffd2c3f36 100644 --- a/Editor/Mono/Inspector/Collider2DEditorBase.cs +++ b/Editor/Mono/Inspector/Collider2DEditorBase.cs @@ -16,7 +16,7 @@ internal abstract class Collider2DEditorBase : ColliderEditorBase protected class Styles { public static readonly GUIContent s_ColliderEditDisableHelp = EditorGUIUtility.TrTextContent("Collider cannot be edited because it is driven by SpriteRenderer's tiling properties."); - public static readonly GUIContent s_AutoTilingLabel = EditorGUIUtility.TrTextContent("Auto Tiling ", " When enabled, the collider's shape will update automaticaly based on the SpriteRenderer's tiling properties"); + public static readonly GUIContent s_AutoTilingLabel = EditorGUIUtility.TrTextContent("Auto Tiling ", " When enabled, the collider's shape will update automatically based on the SpriteRenderer's tiling properties"); } private SerializedProperty m_Density; diff --git a/Editor/Mono/Inspector/CubemapInspector.cs b/Editor/Mono/Inspector/CubemapInspector.cs index 0749b6d37f..5c9236f8df 100644 --- a/Editor/Mono/Inspector/CubemapInspector.cs +++ b/Editor/Mono/Inspector/CubemapInspector.cs @@ -109,7 +109,7 @@ public override void OnInspectorGUI() bool streamingMipmaps = TextureUtil.GetCubemapStreamingMipmaps(c); if (useMipMap) { - streamingMipmaps = EditorGUILayout.Toggle(EditorGUIUtility.TrTextContent("Streaming Mip Maps", "Don't load image data immediately, but wait till image data is requested from script."), streamingMipmaps); + streamingMipmaps = EditorGUILayout.Toggle(EditorGUIUtility.TrTextContent("Streaming Mipmaps", "Don't load image data immediately but wait till image data is requested from script."), streamingMipmaps); } bool linear = TextureUtil.GetLinearSampled(c); diff --git a/Editor/Mono/Inspector/EditorSettingsInspector.cs b/Editor/Mono/Inspector/EditorSettingsInspector.cs index 4c9291dca7..709b9a0c50 100644 --- a/Editor/Mono/Inspector/EditorSettingsInspector.cs +++ b/Editor/Mono/Inspector/EditorSettingsInspector.cs @@ -37,7 +37,7 @@ class Content public static GUIContent assetPipeline = EditorGUIUtility.TrTextContent("Asset Pipeline (experimental)"); public static GUIContent cacheServer = EditorGUIUtility.TrTextContent("Cache Server"); public static GUIContent assetSerialization = EditorGUIUtility.TrTextContent("Asset Serialization"); - public static GUIContent defaultBehaviorMode = EditorGUIUtility.TrTextContent("Default Behavior Mode"); + public static GUIContent defaultBehaviorMode = EditorGUIUtility.TrTextContent("Default Behaviour Mode"); public static GUIContent graphics = EditorGUIUtility.TrTextContent("Graphics"); public static GUIContent showLightmapResolutionOverlay = EditorGUIUtility.TrTextContent("Show Lightmap Resolution Overlay"); @@ -49,7 +49,7 @@ class Content public static GUIContent rootNamespace = EditorGUIUtility.TrTextContent("Root namespace"); public static GUIContent etcTextureCompressor = EditorGUIUtility.TrTextContent("ETC Texture Compressor"); - public static GUIContent behavior = EditorGUIUtility.TrTextContent("Behavior"); + public static GUIContent behavior = EditorGUIUtility.TrTextContent("Behaviour"); public static GUIContent fast = EditorGUIUtility.TrTextContent("Fast"); public static GUIContent normal = EditorGUIUtility.TrTextContent("Normal"); public static GUIContent best = EditorGUIUtility.TrTextContent("Best"); diff --git a/Editor/Mono/Inspector/InspectorWindow.cs b/Editor/Mono/Inspector/InspectorWindow.cs index 1982f54ce1..02bd44361b 100644 --- a/Editor/Mono/Inspector/InspectorWindow.cs +++ b/Editor/Mono/Inspector/InspectorWindow.cs @@ -1580,6 +1580,10 @@ internal bool ShouldCullEditor(Editor[] editors, int editorIndex) Object currentTarget = editors[editorIndex].target; + // Editors that should always be hidden + if (currentTarget is ParticleSystemRenderer) + return true; + // Hide regular AssetImporters (but not inherited types) if (currentTarget != null && currentTarget.GetType() == typeof(AssetImporter)) return true; diff --git a/Editor/Mono/Inspector/LightProbeGroupInspector.cs b/Editor/Mono/Inspector/LightProbeGroupInspector.cs index d8fbafac9b..81570a0575 100644 --- a/Editor/Mono/Inspector/LightProbeGroupInspector.cs +++ b/Editor/Mono/Inspector/LightProbeGroupInspector.cs @@ -294,6 +294,8 @@ public bool OnSceneGUI(Transform transform) if (!m_Group.enabled) return m_Editing; + int id = GUIUtility.GetControlID(FocusType.Passive); + if (Event.current.type == EventType.Layout) { //If the group has moved / scaled since last frame need to retetra);) @@ -307,11 +309,16 @@ public bool OnSceneGUI(Transform transform) m_LastPosition = m_Group.transform.position; m_LastRotation = m_Group.transform.rotation; m_LastScale = m_Group.transform.localScale; + + // Tell the handles system that we're the default tool (the one that should get focus when user clicks on nothing else.) + HandleUtility.AddDefaultControl(id); } //See if we should enter edit mode! bool firstSelect = false; - if (Event.current.type == EventType.MouseDown && Event.current.button == 0) + + // make sure we are the closest tool, so that the user is not clicking the handles + if ((Event.current.type == EventType.MouseDown) && (HandleUtility.nearestControl == id) && (Event.current.button == 0)) { //We have no probes selected and have clicked the mouse... Did we click a probe if (SelectedCount == 0) diff --git a/Editor/Mono/Inspector/LightProbeProxyVolumeEditor.cs b/Editor/Mono/Inspector/LightProbeProxyVolumeEditor.cs index b849130b70..747aaa9f79 100644 --- a/Editor/Mono/Inspector/LightProbeProxyVolumeEditor.cs +++ b/Editor/Mono/Inspector/LightProbeProxyVolumeEditor.cs @@ -44,7 +44,7 @@ static Styles() } public static GUIStyle richTextMiniLabel = new GUIStyle(EditorStyles.miniLabel); - public static GUIContent volumeResolutionText = EditorGUIUtility.TrTextContent("Proxy Volume Resolution", "Specifies the resolution of the 3D grid of interpolated light probes. Higher resolution/density means better lighting but the CPU cost will increase."); + public static GUIContent volumeResolutionText = EditorGUIUtility.TrTextContent("Proxy Volume Resolution", "Specifies the resolution of the 3D grid of interpolated light probes. Higher resolution/density means better lighting, but the CPU cost will increase."); public static GUIContent resolutionXText = new GUIContent("X"); public static GUIContent resolutionYText = new GUIContent("Y"); public static GUIContent resolutionZText = new GUIContent("Z"); @@ -52,10 +52,10 @@ static Styles() public static GUIContent bbSettingsText = EditorGUIUtility.TrTextContent("Bounding Box Settings"); public static GUIContent originText = EditorGUIUtility.TrTextContent("Origin"); public static GUIContent bbModeText = EditorGUIUtility.TrTextContent("Bounding Box Mode", "The mode in which the bounding box is computed. A 3D grid of interpolated light probes will be generated inside this bounding box.\n\nAutomatic Local - the local-space bounding box of the Renderer is used.\n\nAutomatic Global - a bounding box is computed which encloses the current Renderer and all the Renderers down the hierarchy that have the Light Probes property set to Use Proxy Volume. The bounding box will be world-space aligned.\n\nCustom - a custom bounding box is used. The bounding box is specified in the local-space of the game object."); - public static GUIContent resModeText = EditorGUIUtility.TrTextContent("Resolution Mode", "The mode in which the resolution of the 3D grid of interpolated light probes is specified:\n\nAutomatic - the resolution on each axis is computed using a user-specified number of interpolated light probes per unit area(Density).\n\nCustom - the user can specify a different resolution on each axis."); + public static GUIContent resModeText = EditorGUIUtility.TrTextContent("Resolution Mode", "The mode in which the resolution of the 3D grid of interpolated light probes is specified:\n\nAutomatic - the resolution on each axis is computed using a user-specified number of interpolated light probes per unit area (Density).\n\nCustom - the user can specify a different resolution on each axis."); public static GUIContent probePositionText = EditorGUIUtility.TrTextContent("Probe Position Mode", "The mode in which the interpolated probe positions are generated.\n\nCellCorner - divide the volume in cells and generate interpolated probe positions in the corner/edge of the cells.\n\nCellCenter - divide the volume in cells and generate interpolated probe positions in the center of the cells."); public static GUIContent refreshModeText = EditorGUIUtility.TrTextContent("Refresh Mode"); - public static GUIContent qualityText = EditorGUIUtility.TrTextContent("Quality", "Affects the total number of evaluated Spherical Harmonics(SH) bands for Renderers that use a Light Probe Proxy Volume:\n\nLow Quality - uses only 2 bands(L0 and L1) sampled from a LPPV texture. This option might improve the performance by not breaking batching.\n\nNormal Quality - uses all the bands to evaluate the SH. L0 and L1 are sampled from a LPPV texture and L2 is constant per Renderer."); + public static GUIContent qualityText = EditorGUIUtility.TrTextContent("Quality", "Affects the total number of evaluated Spherical Harmonics(SH) bands for Renderers that use a Light Probe Proxy Volume:\n\nLow Quality - uses only 2 bands (L0 and L1) sampled from a LPPV texture. This option might improve the performance by not breaking batching.\n\nNormal Quality - uses all the bands to evaluate the SH. L0 and L1 are sampled from a LPPV texture and L2 is constant per Renderer."); public static GUIContent[] bbMode = (Enum.GetNames(typeof(LightProbeProxyVolume.BoundingBoxMode)).Select(x => ObjectNames.NicifyVariableName(x)).ToArray()).Select(x => new GUIContent(x)).ToArray(); public static GUIContent[] resMode = (Enum.GetNames(typeof(LightProbeProxyVolume.ResolutionMode)).Select(x => ObjectNames.NicifyVariableName(x)).ToArray()).Select(x => new GUIContent(x)).ToArray(); public static GUIContent[] probePositionMode = (Enum.GetNames(typeof(LightProbeProxyVolume.ProbePositionMode)).Select(x => ObjectNames.NicifyVariableName(x)).ToArray()).Select(x => new GUIContent(x)).ToArray(); diff --git a/Editor/Mono/Inspector/LightingSettingsInspector.cs b/Editor/Mono/Inspector/LightingSettingsInspector.cs index 22679222dc..822fe7ede3 100644 --- a/Editor/Mono/Inspector/LightingSettingsInspector.cs +++ b/Editor/Mono/Inspector/LightingSettingsInspector.cs @@ -36,7 +36,7 @@ static class Styles public static readonly GUIContent MinimumChartSize = EditorGUIUtility.TrTextContent("Min Chart Size", "Specifies the minimum texel size used for a UV chart. If stitching is required, a value of 4 will create a chart of 4x4 texels to store lighting and directionality. If stitching is not required, a value of 2 will reduce the texel density and provide better lighting build times and run time performance."); public static readonly GUIContent ImportantGI = EditorGUIUtility.TrTextContent("Prioritize Illumination", "When enabled, the object will be marked as a priority object and always included in lighting calculations. Useful for objects that will be strongly emissive to make sure that other objects will be illuminated by this object."); public static readonly GUIContent StitchLightmapSeams = EditorGUIUtility.TrTextContent("Stitch Seams", "When enabled, seams in baked lightmaps will get smoothed."); - public static readonly GUIContent AutoUVMaxDistance = EditorGUIUtility.TrTextContent("Max Distance", "Specifies the maximum worldspace distance to be used for UV chart simplification. If charts are within this distance they will be simplified for optimization purposes."); + public static readonly GUIContent AutoUVMaxDistance = EditorGUIUtility.TrTextContent("Max Distance", "Specifies the maximum worldspace distance to be used for UV chart simplification. If charts are within this distance, they will be simplified for optimization purposes."); public static readonly GUIContent AutoUVMaxAngle = EditorGUIUtility.TrTextContent("Max Angle", "Specifies the maximum angle in degrees between faces sharing a UV edge. If the angle between the faces is below this value, the UV charts will be simplified."); public static readonly GUIContent LightmapParameters = EditorGUIUtility.TrTextContent("Lightmap Parameters", "Allows the adjustment of advanced parameters that affect the process of generating a lightmap for an object using global illumination."); public static readonly GUIContent AtlasTilingX = EditorGUIUtility.TrTextContent("Tiling X"); diff --git a/Editor/Mono/Inspector/LineRendererEditor.cs b/Editor/Mono/Inspector/LineRendererEditor.cs index d4381006b0..4a4ce72976 100644 --- a/Editor/Mono/Inspector/LineRendererEditor.cs +++ b/Editor/Mono/Inspector/LineRendererEditor.cs @@ -26,7 +26,7 @@ class Styles public static readonly GUIContent normalOffset = EditorGUIUtility.TrTextContent("Offset", "The offset applied to created points either from the scene camera or raycast normal, when using physics."); public static readonly GUIContent numCapVertices = EditorGUIUtility.TrTextContent("End Cap Vertices", "How many vertices to add at each end."); public static readonly GUIContent numCornerVertices = EditorGUIUtility.TrTextContent("Corner Vertices", "How many vertices to add for each corner."); - public static readonly GUIContent pointSeparation = EditorGUIUtility.TrTextContent("Min Vertex Distance", "When dragging the mouse a new point will be created after the distance has been exceeded."); + public static readonly GUIContent pointSeparation = EditorGUIUtility.TrTextContent("Min Vertex Distance", "When dragging the mouse, a new point will be created after the distance has been exceeded."); public static readonly GUIContent positions = EditorGUIUtility.TrTextContent("Positions"); public static readonly GUIContent propertyMenuContent = EditorGUIUtility.TrTextContent("Delete Selected Array Elements"); public static readonly GUIContent showWireframe = EditorGUIUtility.TrTextContent("Show Wireframe", "Show the wireframe visualizing the line."); diff --git a/Editor/Mono/Inspector/MaterialEditor.cs b/Editor/Mono/Inspector/MaterialEditor.cs index 528c3b6613..8f6d5f1ec6 100644 --- a/Editor/Mono/Inspector/MaterialEditor.cs +++ b/Editor/Mono/Inspector/MaterialEditor.cs @@ -1542,25 +1542,31 @@ public bool DidModifyAnimationModeMaterialProperty(MaterialProperty property, in static Renderer[] GetAssociatedRenderersFromInspector() { - List renderers = new List(); var imguicontainer = UIElementsUtility.GetCurrentIMGUIContainer(); if (imguicontainer != null) { var editorElement = imguicontainer.GetFirstAncestorOfType(); if (editorElement != null) { - foreach (var editor in editorElement.Editors) - { - foreach (Object target in editor.targets) - { - var renderer = target as Renderer; - if (renderer) - renderers.Add(renderer); - } - } + return GetAssociatedRenderersFromEditors(editorElement.Editors); } } + return new Renderer[0]; + } + + internal static Renderer[] GetAssociatedRenderersFromEditors(IEnumerable editors) + { + List renderers = new List(); + foreach (var editor in editors) + { + foreach (Object target in editor.targets) + { + var renderer = target as Renderer; + if (renderer) + renderers.Add(renderer); + } + } return renderers.ToArray(); } diff --git a/Editor/Mono/Inspector/PlayerSettingsEditor/PlayerSettingsEditor.cs b/Editor/Mono/Inspector/PlayerSettingsEditor/PlayerSettingsEditor.cs index 7507d834bf..91028fdb26 100644 --- a/Editor/Mono/Inspector/PlayerSettingsEditor/PlayerSettingsEditor.cs +++ b/Editor/Mono/Inspector/PlayerSettingsEditor/PlayerSettingsEditor.cs @@ -60,7 +60,7 @@ class SettingsContent public static readonly GUIContent cursorHotspot = EditorGUIUtility.TrTextContent("Cursor Hotspot"); public static readonly GUIContent defaultCursor = EditorGUIUtility.TrTextContent("Default Cursor"); public static readonly GUIContent defaultIcon = EditorGUIUtility.TrTextContent("Default Icon"); - public static readonly GUIContent vertexChannelCompressionMask = EditorGUIUtility.TrTextContent("Vertex Compression*", "Select which vertex channels should be compressed. Compression can save memory and bandwidth but precision will be lower."); + public static readonly GUIContent vertexChannelCompressionMask = EditorGUIUtility.TrTextContent("Vertex Compression*", "Select which vertex channels should be compressed. Compression can save memory and bandwidth, but precision will be lower."); public static readonly GUIContent iconTitle = EditorGUIUtility.TrTextContent("Icon"); public static readonly GUIContent resolutionPresentationTitle = EditorGUIUtility.TrTextContent("Resolution and Presentation"); @@ -144,7 +144,7 @@ class SettingsContent public static readonly GUIContent graphicsJobsMode = EditorGUIUtility.TrTextContent("Graphics Jobs Mode*"); public static readonly GUIContent applicationBuildNumber = EditorGUIUtility.TrTextContent("Build"); public static readonly GUIContent appleDeveloperTeamID = EditorGUIUtility.TrTextContent("iOS Developer Team ID", "Developers can retrieve their Team ID by visiting the Apple Developer site under Account > Membership."); - public static readonly GUIContent useOnDemandResources = EditorGUIUtility.TrTextContent("Use on demand resources*"); + public static readonly GUIContent useOnDemandResources = EditorGUIUtility.TrTextContent("Use on-demand resources*"); public static readonly GUIContent gcIncremental = EditorGUIUtility.TrTextContent("Use incremental GC (Experimental)", "With incremental Garbage Collection, the Garbage Collector will try to time-slice the collection task into multiple steps, to avoid long GC times preventing content from running smoothly."); public static readonly GUIContent accelerometerFrequency = EditorGUIUtility.TrTextContent("Accelerometer Frequency*"); public static readonly GUIContent cameraUsageDescription = EditorGUIUtility.TrTextContent("Camera Usage Description*", "String shown to the user when requesting permission to use the device camera. Written to the NSCameraUsageDescription field in Xcode project's info.plist file"); @@ -189,8 +189,8 @@ class SettingsContent public static readonly GUIContent[] activeInputHandlingOptions = new GUIContent[] { EditorGUIUtility.TrTextContent("Input Manager"), EditorGUIUtility.TrTextContent("Input System (Preview)"), EditorGUIUtility.TrTextContent("Both") }; public static readonly GUIContent lightmapEncodingLabel = EditorGUIUtility.TrTextContent("Lightmap Encoding", "Affects the encoding scheme and compression format of the lightmaps."); public static readonly GUIContent[] lightmapEncodingNames = { EditorGUIUtility.TrTextContent("Low Quality"), EditorGUIUtility.TrTextContent("Normal Quality"), EditorGUIUtility.TrTextContent("High Quality")}; - public static readonly GUIContent lightmapStreamingEnabled = EditorGUIUtility.TrTextContent("Lightmap Streaming Enabled", "Only load larger lightmap mip maps as needed to render the current game cameras. Requires texture streaming to be enabled in quality settings. This value is applied to the light map textures as they are generated."); - public static readonly GUIContent lightmapStreamingPriority = EditorGUIUtility.TrTextContent("Streaming Priority", "Lightmap mip map streaming priority when there's contention for resources. Positive numbers represent higher priority. Valid range is -128 to 127. This value is applied to the light map textures as they are generated."); + public static readonly GUIContent lightmapStreamingEnabled = EditorGUIUtility.TrTextContent("Lightmap Streaming Enabled", "Only load larger lightmap mipmaps as needed to render the current game cameras. Requires texture streaming to be enabled in quality settings. This value is applied to the light map textures as they are generated."); + public static readonly GUIContent lightmapStreamingPriority = EditorGUIUtility.TrTextContent("Streaming Priority", "Lightmap mipmap streaming priority when there's contention for resources. Positive numbers represent higher priority. Valid range is -128 to 127. This value is applied to the light map textures as they are generated."); public static readonly GUIContent lightmapQualityAndroidWarning = EditorGUIUtility.TrTextContent("The selected Lightmap Encoding requires OpenGL ES 3.0 or Vulkan. Uncheck 'Automatic Graphics API' and remove OpenGL ES 2 API. Additionally, 'Minimum API Level' must be at least Android 4.3"); public static readonly GUIContent lightmapQualityIOSWarning = EditorGUIUtility.TrTextContent("The selected Lightmap Encoding requires Metal API only. Uncheck 'Automatic Graphics API' and remove OpenGL ES APIs."); public static readonly GUIContent monoNotSupportediOS11WarningGUIContent = EditorGUIUtility.TrTextContent("Mono is not supported on iOS11 and above."); diff --git a/Editor/Mono/Inspector/PlayerSettingsEditor/PlayerSettingsSplashScreenEditor.cs b/Editor/Mono/Inspector/PlayerSettingsEditor/PlayerSettingsSplashScreenEditor.cs index 0e4130b7d1..bd8995a8ca 100644 --- a/Editor/Mono/Inspector/PlayerSettingsEditor/PlayerSettingsSplashScreenEditor.cs +++ b/Editor/Mono/Inspector/PlayerSettingsEditor/PlayerSettingsSplashScreenEditor.cs @@ -77,7 +77,7 @@ class Texts { public GUIContent animate = EditorGUIUtility.TrTextContent("Animation"); public GUIContent backgroundColor = EditorGUIUtility.TrTextContent("Background Color", "Background color when no background image is used."); - public GUIContent backgroundImage = EditorGUIUtility.TrTextContent("Background Image", "Image to be used in landscape and portrait(when portrait image is not set)."); + public GUIContent backgroundImage = EditorGUIUtility.TrTextContent("Background Image", "Image to be used in landscape and portrait (when portrait image is not set)."); public GUIContent backgroundPortraitImage = EditorGUIUtility.TrTextContent("Alternate Portrait Image*", "Optional image to be used in portrait mode."); public GUIContent backgroundTitle = EditorGUIUtility.TrTextContent("Background*"); public GUIContent backgroundZoom = EditorGUIUtility.TrTextContent("Background Zoom"); diff --git a/Editor/Mono/Inspector/QualitySettingsEditor.cs b/Editor/Mono/Inspector/QualitySettingsEditor.cs index a233b16d0f..ceda524753 100644 --- a/Editor/Mono/Inspector/QualitySettingsEditor.cs +++ b/Editor/Mono/Inspector/QualitySettingsEditor.cs @@ -21,7 +21,7 @@ private class Content public static readonly GUIContent kStreamingMipmapsActive = EditorGUIUtility.TrTextContent("Texture Streaming", "Enable to use texture mipmap streaming."); public static readonly GUIContent kStreamingMipmapsMemoryBudget = EditorGUIUtility.TrTextContent("Memory Budget", "Texture Streaming Budget in MB."); public static readonly GUIContent kStreamingMipmapsRenderersPerFrame = EditorGUIUtility.TrTextContent("Renderers Per Frame", "Number of renderers to process each frame. A lower number will decrease the CPU load at the cost of delaying the mipmap loading."); - public static readonly GUIContent kStreamingMipmapsAddAllCameras = EditorGUIUtility.TrTextContent("Add All Cameras", "Adds all cameras to texture streaming system even if it lacks a StreamingController component. If a camera has the StreamingController component that will control whether its processed or not."); + public static readonly GUIContent kStreamingMipmapsAddAllCameras = EditorGUIUtility.TrTextContent("Add All Cameras", "Adds all cameras to texture streaming system even if it lacks a StreamingController component. If a camera has the StreamingController component, that will control whether it is processed or not."); public static readonly GUIContent kStreamingMipmapsMaxLevelReduction = EditorGUIUtility.TrTextContent("Max Level Reduction", "This is the maximum number of mipmap levels a texture should drop."); public static readonly GUIContent kStreamingMipmapsMaxFileIORequests = EditorGUIUtility.TrTextContent("Max IO Requests", "Maximum number of texture file IO calls active from the texture streaming system at any time."); diff --git a/Editor/Mono/Inspector/RectTransformEditor.cs b/Editor/Mono/Inspector/RectTransformEditor.cs index 95cb889406..dc117a14cb 100644 --- a/Editor/Mono/Inspector/RectTransformEditor.cs +++ b/Editor/Mono/Inspector/RectTransformEditor.cs @@ -41,7 +41,7 @@ class Styles public GUIContent anchorsContent = EditorGUIUtility.TrTextContent("Anchors"); public GUIContent anchorMinContent = EditorGUIUtility.TrTextContent("Min", "The normalized position in the parent rectangle that the lower left corner is anchored to."); public GUIContent anchorMaxContent = EditorGUIUtility.TrTextContent("Max", "The normalized position in the parent rectangle that the upper right corner is anchored to."); - public GUIContent pivotContent = EditorGUIUtility.TrTextContent("Pivot", "The pivot point specified in normalized values between 0 and 1. The pivot point is the origin of this rectangle. Rotation and scaling is around this point."); + public GUIContent pivotContent = EditorGUIUtility.TrTextContent("Pivot", "The pivot point specified in normalized values between 0 and 1. The pivot point is the origin of this rectangle. Rotation and scaling are around this point."); public GUIContent transformScaleContent = EditorGUIUtility.TrTextContent("Scale", "The local scaling of this Game Object relative to the parent. This scales everything including image borders and text."); public GUIContent rawEditContent; public GUIContent blueprintContent; diff --git a/Editor/Mono/Inspector/ReflectionProbeEditor.cs b/Editor/Mono/Inspector/ReflectionProbeEditor.cs index c9563ffd04..a36d13a86d 100644 --- a/Editor/Mono/Inspector/ReflectionProbeEditor.cs +++ b/Editor/Mono/Inspector/ReflectionProbeEditor.cs @@ -108,7 +108,7 @@ static Styles() public static GUIContent timeSlicing = EditorGUIUtility.TrTextContent("Time Slicing", "If enabled this probe will update over several frames, to help reduce the impact on the frame rate"); public static GUIContent refreshMode = EditorGUIUtility.TrTextContent("Refresh Mode", "Controls how this probe refreshes in the Player"); - public static GUIContent typeText = EditorGUIUtility.TrTextContent("Type", "'Baked Cubemap' uses the 'Auto Baking' mode from the Lighting window. If it is enabled then baking is automatic otherwise manual bake is needed (use the bake button below). \n'Custom' can be used if a custom cubemap is wanted. \n'Realtime' can be used to dynamically re-render the cubemap during runtime (via scripting)."); + public static GUIContent typeText = EditorGUIUtility.TrTextContent("Type", "'Baked Cubemap' uses the 'Auto Baking' mode from the Lighting window. If it is enabled, then baking is automatic otherwise manual bake is needed (use the bake button below). \n'Custom' can be used if a custom cubemap is wanted. \n'Realtime' can be used to dynamically re-render the cubemap during runtime (via scripting)."); public static GUIContent[] reflectionProbeMode = { EditorGUIUtility.TrTextContent("Baked"), EditorGUIUtility.TrTextContent("Custom"), EditorGUIUtility.TrTextContent("Realtime") }; public static int[] reflectionProbeModeValues = { (int)ReflectionProbeMode.Baked, (int)ReflectionProbeMode.Custom, (int)ReflectionProbeMode.Realtime }; diff --git a/Editor/Mono/Inspector/RenderTextureEditor.cs b/Editor/Mono/Inspector/RenderTextureEditor.cs index 08827238c4..66b84d5869 100644 --- a/Editor/Mono/Inspector/RenderTextureEditor.cs +++ b/Editor/Mono/Inspector/RenderTextureEditor.cs @@ -16,14 +16,14 @@ private class Styles { public readonly GUIContent size = EditorGUIUtility.TrTextContent("Size", "Size of the render texture in pixels."); public readonly GUIContent cross = EditorGUIUtility.TextContent("x"); - public readonly GUIContent antiAliasing = EditorGUIUtility.TrTextContent("Anti-Aliasing", "Number of anti-aliasing samples."); + public readonly GUIContent antiAliasing = EditorGUIUtility.TrTextContent("Anti-aliasing", "Number of anti-aliasing samples."); public readonly GUIContent colorFormat = EditorGUIUtility.TrTextContent("Color Format", "Format of the color buffer."); public readonly GUIContent depthBuffer = EditorGUIUtility.TrTextContent("Depth Buffer", "Format of the depth buffer."); public readonly GUIContent enableCompatibleFormat = EditorGUIUtility.TrTextContent("Enable Compatible Color Format", "Lets the color format be changed to compatible and supported formats for the target platform automatically, if the target platform doesn't support the input format."); public readonly GUIContent dimension = EditorGUIUtility.TrTextContent("Dimension", "Is the texture 2D, Cube or 3D?"); public readonly GUIContent enableMipmaps = EditorGUIUtility.TrTextContent("Enable Mip Maps", "This render texture will have Mip Maps."); public readonly GUIContent bindMS = EditorGUIUtility.TrTextContent("Bind multisampled", "If enabled, the texture will not go through an AA resolve if bound to a shader."); - public readonly GUIContent autoGeneratesMipmaps = EditorGUIUtility.TrTextContent("Auto generate Mip Maps", "This render texture automatically generate its Mip Maps."); + public readonly GUIContent autoGeneratesMipmaps = EditorGUIUtility.TrTextContent("Auto generate Mip Maps", "This render texture automatically generates its Mip Maps."); public readonly GUIContent sRGBTexture = EditorGUIUtility.TrTextContent("sRGB (Color RenderTexture)", "RenderTexture content is stored in gamma space. Non-HDR color textures should enable this flag."); public readonly GUIContent useDynamicScale = EditorGUIUtility.TrTextContent("Dynamic Scaling", "Allow the texture to be automatically resized by ScalableBufferManager, to support dynamic resolution."); diff --git a/Editor/Mono/Inspector/SpriteRendererEditor.cs b/Editor/Mono/Inspector/SpriteRendererEditor.cs index a6afd7e753..db054b9259 100644 --- a/Editor/Mono/Inspector/SpriteRendererEditor.cs +++ b/Editor/Mono/Inspector/SpriteRendererEditor.cs @@ -24,7 +24,7 @@ class Styles public static readonly GUIContent flipYLabel = EditorGUIUtility.TrTextContent("Y", "Sprite vertical flipping"); public static readonly int flipToggleHash = "FlipToggleHash".GetHashCode(); - public static readonly GUIContent fullTileLabel = EditorGUIUtility.TrTextContent("Tile Mode", "Specify the 9 slice tiling behaviour"); + public static readonly GUIContent fullTileLabel = EditorGUIUtility.TrTextContent("Tile Mode", "Specify the 9-slice tiling behaviour"); public static readonly GUIContent fullTileThresholdLabel = EditorGUIUtility.TrTextContent("Stretch Value", "This value defines how much the center portion will stretch before it tiles."); public static readonly GUIContent drawModeLabel = EditorGUIUtility.TrTextContent("Draw Mode", "Specify the draw mode for the sprite"); public static readonly GUIContent widthLabel = EditorGUIUtility.TrTextContent("Width", "The width dimension value for the sprite"); diff --git a/Editor/Mono/Inspector/TimeManagerInspector.cs b/Editor/Mono/Inspector/TimeManagerInspector.cs index 4d7aa39df1..a125354939 100644 --- a/Editor/Mono/Inspector/TimeManagerInspector.cs +++ b/Editor/Mono/Inspector/TimeManagerInspector.cs @@ -12,7 +12,7 @@ internal class TimeManagerEditor : Editor class Content { public static readonly GUIContent fixedTimestepLabel = EditorGUIUtility.TrTextContent("Fixed Timestep", "A framerate-independent interval that dictates when physics calculations and FixedUpdate() events are performed."); - public static readonly GUIContent maxAllowedTimestepLabel = EditorGUIUtility.TrTextContent("Maximum Allowed Timestep", "A framerate-independent interval that caps the worst case scenario when framerate is low. Physics calculations and FixedUpdate() events will not be performed for longer time than specified."); + public static readonly GUIContent maxAllowedTimestepLabel = EditorGUIUtility.TrTextContent("Maximum Allowed Timestep", "A framerate-independent interval that caps the worst-case scenario when framerate is low. Physics calculations and FixedUpdate() events will not be performed for longer time than specified."); public static readonly GUIContent timeScaleLabel = EditorGUIUtility.TrTextContent("Time Scale", "The speed at which time progresses. Change this value to simulate bullet-time effects. A value of 1 means real-time. A value of .5 means half speed; a value of 2 is double speed."); public static readonly GUIContent maxParticleTimestepLabel = EditorGUIUtility.TrTextContent("Maximum Particle Timestep", "The maximum time that should be allowed to process particles for a frame."); } diff --git a/Editor/Mono/Networking/PlayerConnection/AttachToPlayerGUI.cs b/Editor/Mono/Networking/PlayerConnection/AttachToPlayerGUI.cs index fddc7584ed..6e9ba45ecf 100644 --- a/Editor/Mono/Networking/PlayerConnection/AttachToPlayerGUI.cs +++ b/Editor/Mono/Networking/PlayerConnection/AttachToPlayerGUI.cs @@ -80,7 +80,7 @@ static class Content { public static readonly GUIContent EnterIPText = UnityEditor.EditorGUIUtility.TrTextContent(""); public static readonly GUIContent AutoconnectedPlayer = UnityEditor.EditorGUIUtility.TrTextContent("(Autoconnected Player)"); - public static readonly GUIContent ConnectingToPlayerMessage = UnityEditor.EditorGUIUtility.TrTextContent("Connecting to player...(this can take a while)"); + public static readonly GUIContent ConnectingToPlayerMessage = UnityEditor.EditorGUIUtility.TrTextContent("Connecting to player... (this can take a while)"); public static readonly string LocalHostProhibited = L10n.Tr(" (Localhost prohibited)"); public static readonly string VersionMismatch = L10n.Tr(" (Version mismatch)"); diff --git a/Editor/Mono/ObjectSelector.cs b/Editor/Mono/ObjectSelector.cs index 4206e04c18..f0ce1b461b 100644 --- a/Editor/Mono/ObjectSelector.cs +++ b/Editor/Mono/ObjectSelector.cs @@ -731,7 +731,7 @@ void ResizeBottomPartOfWindow() GUI.changed = false; // Handle preview size - m_PreviewSize = m_PreviewResizer.ResizeHandle(position, kPreviewExpandedAreaHeight + kPreviewMargin * 2 - 20, kMinTopSize + 20, 20) + 20; + m_PreviewSize = m_PreviewResizer.ResizeHandle(position, kPreviewExpandedAreaHeight + kPreviewMargin * 2 - 20, kMinTopSize + 20, m_PreviewSize + 20) + 20; m_TopSize = position.height - m_PreviewSize; bool open = PreviewIsOpen(); diff --git a/Editor/Mono/PreferencesWindow/PreferencesSettingsProviders.cs b/Editor/Mono/PreferencesWindow/PreferencesSettingsProviders.cs index 04ce67c394..c82289c460 100644 --- a/Editor/Mono/PreferencesWindow/PreferencesSettingsProviders.cs +++ b/Editor/Mono/PreferencesWindow/PreferencesSettingsProviders.cs @@ -97,7 +97,7 @@ internal class TwoDProperties internal class LanguageProperties { - public static readonly GUIContent editorLanguageExperimental = EditorGUIUtility.TrTextContent("Editor Language(Experimental)"); + public static readonly GUIContent editorLanguageExperimental = EditorGUIUtility.TrTextContent("Editor Language (Experimental)"); public static readonly GUIContent editorLanguage = EditorGUIUtility.TrTextContent("Editor language"); } diff --git a/Editor/Mono/ProjectWindow/ProjectWindowUtil.cs b/Editor/Mono/ProjectWindow/ProjectWindowUtil.cs index dd858afe22..7ee998c766 100644 --- a/Editor/Mono/ProjectWindow/ProjectWindowUtil.cs +++ b/Editor/Mono/ProjectWindow/ProjectWindowUtil.cs @@ -747,9 +747,9 @@ internal static bool DeleteAssets(List instanceIDs, bool askIfSure) { string title; if (paths.Count > 1) - title = L10n.Tr("Delete selected assets ?"); + title = L10n.Tr("Delete selected assets?"); else - title = L10n.Tr("Delete selected asset ?"); + title = L10n.Tr("Delete selected asset?"); int maxCount = 3; var infotext = new StringBuilder(); diff --git a/Editor/Mono/SceneModeWindows/LightingWindowBakeSettings.cs b/Editor/Mono/SceneModeWindows/LightingWindowBakeSettings.cs index b5f244b5a9..cd66d6407b 100644 --- a/Editor/Mono/SceneModeWindows/LightingWindowBakeSettings.cs +++ b/Editor/Mono/SceneModeWindows/LightingWindowBakeSettings.cs @@ -828,15 +828,15 @@ static class Styles public static readonly GUIContent UseRealtimeGI = EditorGUIUtility.TrTextContent("Realtime Global Illumination", "Controls whether Realtime lights in the Scene contribute indirect light. If enabled, Realtime lights contribute both direct and indirect light. If disabled, Realtime lights only contribute direct light. This can be disabled on a per-light basis in the light component Inspector by setting Indirect Multiplier to 0."); public static readonly GUIContent BakedGIDisabledInfo = EditorGUIUtility.TrTextContent("All Baked and Mixed lights in the Scene are currently being overridden to Realtime light modes. Enable Baked Global Illumination to allow the use of Baked and Mixed light modes."); public static readonly GUIContent BakeBackend = EditorGUIUtility.TrTextContent("Lightmapper", "Specifies which baking system will be used to generate baked lightmaps."); - //public static readonly GUIContent PVRSampling = EditorGUIUtility.TrTextContent("Sampling", "How to sample the lightmaps. Auto and adaptive automatically tests for convergence. Auto uses a maximum of 16K samples. Adaptive uses a configurable maximum number of samples. Fixed always uses the set number of samples and does not test for convergence."); + //public static readonly GUIContent PVRSampling = EditorGUIUtility.TrTextContent("Sampling", "How to sample the lightmaps. Auto and adaptive automatically test for convergence. Auto uses a maximum of 16K samples. Adaptive uses a configurable maximum number of samples. Fixed always uses the set number of samples and does not test for convergence."); //public static readonly GUIContent PVRDirectSampleCountAdaptive = EditorGUIUtility.TrTextContent("Max Direct Samples", "Maximum number of samples to use for direct lighting."); public static readonly GUIContent PVRDirectSampleCount = EditorGUIUtility.TrTextContent("Direct Samples", "Controls the number of samples the lightmapper will use for direct lighting calculations. Increasing this value may improve the quality of lightmaps but increases the time required for baking to complete."); //public static readonly GUIContent PVRSampleCountAdaptive = EditorGUIUtility.TrTextContent("Max Indirect Samples", "Maximum number of samples to use for indirect lighting."); public static readonly GUIContent PVRIndirectSampleCount = EditorGUIUtility.TrTextContent("Indirect Samples", "Controls the number of samples the lightmapper will use for indirect lighting calculations. Increasing this value may improve the quality of lightmaps but increases the time required for baking to complete."); public static readonly GUIContent PVRBounces = EditorGUIUtility.TrTextContent("Bounces", "Controls the maximum number of bounces the lightmapper will compute for indirect light."); - public static readonly GUIContent DenoisingWarningDirect = EditorGUIUtility.TrTextContent("Direct Denoiser", "Your hardware doesn’t support denoising. To see minimum requirements, read the documentation."); - public static readonly GUIContent DenoisingWarningIndirect = EditorGUIUtility.TrTextContent("Indirect Denoiser", "Your hardware doesn’t support denoising. To see minimum requirements, read the documentation."); - public static readonly GUIContent DenoisingWarningAO = EditorGUIUtility.TrTextContent("Ambient Occlusion Denoiser", "Your hardware doesn’t support denoising. To see minimum requirements, read the documentation."); + public static readonly GUIContent DenoisingWarningDirect = EditorGUIUtility.TrTextContent("Direct Denoiser", "Your hardware doesn't support denoising. To see minimum requirements, read the documentation."); + public static readonly GUIContent DenoisingWarningIndirect = EditorGUIUtility.TrTextContent("Indirect Denoiser", "Your hardware doesn't support denoising. To see minimum requirements, read the documentation."); + public static readonly GUIContent DenoisingWarningAO = EditorGUIUtility.TrTextContent("Ambient Occlusion Denoiser", "Your hardware doesn't support denoising. To see minimum requirements, read the documentation."); public static readonly GUIContent PVRDenoiserTypeDirect = EditorGUIUtility.TrTextContent("Direct Denoiser", "Specifies the type of denoiser used to reduce noise for direct lights."); public static readonly GUIContent PVRDenoiserTypeIndirect = EditorGUIUtility.TrTextContent("Indirect Denoiser", "Specifies the type of denoiser used to reduce noise for indirect lights."); public static readonly GUIContent PVRDenoiserTypeAO = EditorGUIUtility.TrTextContent("Ambient Occlusion Denoiser", "Specifies the type of denoiser used to reduce noise for ambient occlusion."); @@ -851,7 +851,7 @@ static class Styles public static readonly GUIContent PVRFilteringAtrousPositionSigmaIndirect = EditorGUIUtility.TrTextContent("Sigma", "Controls the threshold of the filter for indirect light stored in the lightmap. A higher value increases the threshold, which reduces noise in the direct layer of the lightmap. Too high of a value can cause a loss of detail in the lightmap."); public static readonly GUIContent PVRFilteringAtrousPositionSigmaAO = EditorGUIUtility.TrTextContent("Sigma", "Controls the threshold of the filter for ambient occlusion stored in the lightmap. A higher value increases the threshold, which reduces noise in the direct layer of the lightmap. Too high of a value can cause a loss of detail in the lightmap."); public static readonly GUIContent PVRCulling = EditorGUIUtility.TrTextContent("Prioritize View", "Specifies whether the lightmapper should prioritize baking texels within the scene view. When disabled, objects outside the scene view will have the same priority as those in the scene view."); - public static readonly GUIContent PVREnvironmentMIS = EditorGUIUtility.TrTextContent("Multiple Importance Sampling", "Specifies whether to use multiple importance sampling for sampling the environment. This will generally lead to faster convergence when generating lightmaps, but can lead to noisier results in certain low frequency environments."); + public static readonly GUIContent PVREnvironmentMIS = EditorGUIUtility.TrTextContent("Multiple Importance Sampling", "Specifies whether to use multiple importance sampling for sampling the environment. This will generally lead to faster convergence when generating lightmaps but can lead to noisier results in certain low frequency environments."); public static readonly GUIContent PVREnvironmentSampleCount = EditorGUIUtility.TrTextContent("Environment Samples", "Controls the number of samples the lightmapper will use for environment lighting calculations. Increasing this value may improve the quality of lightmaps but increases the time required for baking to complete."); // TODO(RadeonRays): Used for hiding A-trous filtering option until it is implemented. public static readonly GUIContent[] GPUFilterOptions = new[] { EditorGUIUtility.TrTextContent("Gaussian"), EditorGUIUtility.TrTextContent("None") }; diff --git a/Editor/Mono/SceneModeWindows/LightmapPreviewWindow.cs b/Editor/Mono/SceneModeWindows/LightmapPreviewWindow.cs index 0993ed453e..9bc817464f 100644 --- a/Editor/Mono/SceneModeWindows/LightmapPreviewWindow.cs +++ b/Editor/Mono/SceneModeWindows/LightmapPreviewWindow.cs @@ -95,7 +95,7 @@ static class Styles public static readonly GUIContent TextureNotAvailableRealtime = EditorGUIUtility.TrTextContent("The texture is not available at the moment."); public static readonly GUIContent TextureNotAvailableBaked = EditorGUIUtility.TrTextContent("The texture is not available at the moment.\nPlease try to rebake the current scene or turn on Auto, and make sure that this object is set to 'Contribute Global Illumination' if it's meant to be baked."); public static readonly GUIContent TextureNotAvailableBakedShadowmask = EditorGUIUtility.TrTextContent("The texture is not available at the moment.\nPlease make sure that Mixed Lights affect this GameObject and that it is set to 'Contribute Global Illumination'."); - public static readonly GUIContent TextureNotAvailableBakedAlbedoEmissive = EditorGUIUtility.TrTextContent("The texture is not an index based texture and is not available when using Progressive.\nPlease go to the instance you wish to debug, and select the lightmap on the Mesh Renderer."); + public static readonly GUIContent TextureNotAvailableBakedAlbedoEmissive = EditorGUIUtility.TrTextContent("The texture is not an index-based texture and is not available when using Progressive.\nPlease go to the instance you wish to debug, and select the lightmap on the Mesh Renderer."); public static readonly GUIContent TextureLoading = EditorGUIUtility.TrTextContent("Loading..."); public static readonly GUIContent UVOverlayIcon = EditorGUIUtility.TrIconContent("ToggleUVOverlay", "Toggles the UV Overlay for all the objects in the lightmap. The currently selected object will be highlighted. "); public static readonly GUIContent ExposureIcon = EditorGUIUtility.TrIconContent("SceneViewLighting", "Controls the number of stops to over or under expose the lightmap."); diff --git a/Editor/Mono/SceneModeWindows/NavigationWindow.cs b/Editor/Mono/SceneModeWindows/NavigationWindow.cs index 0478f66928..183bd82917 100644 --- a/Editor/Mono/SceneModeWindows/NavigationWindow.cs +++ b/Editor/Mono/SceneModeWindows/NavigationWindow.cs @@ -588,7 +588,7 @@ static void DisplayAgentControls(Object target, SceneView sceneView) } var showAgentNeighbours = NavMeshVisualizationSettings.showAgentNeighbours; - if (showAgentNeighbours != EditorGUILayout.Toggle(EditorGUIUtility.TrTextContent("Show Neighbours", "Show the agent neighbours cosidered during simulation."), showAgentNeighbours)) + if (showAgentNeighbours != EditorGUILayout.Toggle(EditorGUIUtility.TrTextContent("Show Neighbours", "Show the agent neighbours considered during simulation."), showAgentNeighbours)) { NavMeshVisualizationSettings.showAgentNeighbours = !showAgentNeighbours; bRepaint = true; diff --git a/Editor/Mono/SceneModeWindows/OcclusionCullingWindow.cs b/Editor/Mono/SceneModeWindows/OcclusionCullingWindow.cs index 1726a789cf..51ed489cc1 100644 --- a/Editor/Mono/SceneModeWindows/OcclusionCullingWindow.cs +++ b/Editor/Mono/SceneModeWindows/OcclusionCullingWindow.cs @@ -42,7 +42,7 @@ class Styles public GUIContent seeVisualizationInScene = EditorGUIUtility.TrTextContent("See the occlusion culling visualization in the Scene View based on the selected Camera."); public GUIContent noOcclusionData = EditorGUIUtility.TrTextContent("No occlusion data has been baked."); public GUIContent smallestHole = EditorGUIUtility.TrTextContent("Smallest Hole", "Smallest hole in the geometry through which the camera is supposed to see. The single float value of the parameter represents the diameter of the imaginary smallest hole, i.e. the maximum extent of a 3D object that fits through the hole."); - public GUIContent backfaceThreshold = EditorGUIUtility.TrTextContent("Backface Threshold", "The backface threshold is a size optimization that reduces unnecessary details by testing backfaces. A value of 100 is robust and never removes any backfaces. A value of 5 aggressively reduces the data based on locations with visible backfaces. The idea is that typically valid camera positions cannot see many backfaces. For example geometry under terrain and inside solid objects can be removed."); + public GUIContent backfaceThreshold = EditorGUIUtility.TrTextContent("Backface Threshold", "The backface threshold is a size optimization that reduces unnecessary details by testing backfaces. A value of 100 is robust and never removes any backfaces. A value of 5 aggressively reduces the data based on locations with visible backfaces. The idea is that typically valid camera positions cannot see many backfaces. For example, geometry under terrain and inside solid objects can be removed."); public GUIContent farClipPlane = EditorGUIUtility.TrTextContent("Far Clip Plane", "Far Clip Plane used during baking. This should match the largest far clip plane used by any camera in the scene. A value of 0.0 sets the far plane to Infinity."); public GUIContent smallestOccluder = EditorGUIUtility.TrTextContent("Smallest Occluder", "The size of the smallest object that will be used to hide other objects when doing occlusion culling. For example, if a value of 4 is chosen, then all the objects that are higher or wider than 4 meters will block visibility and the objects that are smaller than that will not. This value is a tradeoff between occlusion accuracy and storage size."); public GUIContent defaultParameterText = EditorGUIUtility.TrTextContent("Default Parameters", "The default parameters guarantee that any given scene computes fast and the occlusion culling results are good. As the parameters are always scene specific, better results will be achieved when fine tuning the parameters on a scene to scene basis. All the parameters are dependent on the unit scale of the scene and it is imperative that the unit scale parameter is set correctly before setting the default values."); diff --git a/Editor/Mono/SceneModeWindows/PhysicsDebugWindow.cs b/Editor/Mono/SceneModeWindows/PhysicsDebugWindow.cs index 0a82854cfd..59ae581bd0 100644 --- a/Editor/Mono/SceneModeWindows/PhysicsDebugWindow.cs +++ b/Editor/Mono/SceneModeWindows/PhysicsDebugWindow.cs @@ -50,7 +50,7 @@ private static class Style public static readonly GUIContent showLayers = EditorGUIUtility.TrTextContent("Show Layers", "Show selected layers"); public static readonly GUIContent showPhysicsScenes = EditorGUIUtility.TrTextContent("Show Physics Scene", "Show selected physics scenes"); public static readonly GUIContent showStaticCollider = EditorGUIUtility.TrTextContent("Show Static Colliders", "Show collision geometry from Colliders that do not have a Rigidbody"); - public static readonly GUIContent showTriggers = EditorGUIUtility.TrTextContent("Show Triggers", "Show collision geometry from Colliders that have 'isTrigge' enabled"); + public static readonly GUIContent showTriggers = EditorGUIUtility.TrTextContent("Show Triggers", "Show collision geometry from Colliders that have 'isTrigger' enabled"); public static readonly GUIContent showRigibodies = EditorGUIUtility.TrTextContent("Show Rigidbodies", "Show collision geometry from Rigidbodies"); public static readonly GUIContent showKinematicBodies = EditorGUIUtility.TrTextContent("Show Kinematic Bodies", "Show collision geometry from Kinematic Rigidbodies"); public static readonly GUIContent showSleepingBodies = EditorGUIUtility.TrTextContent("Show Sleeping Bodies", "Show collision geometry from Sleeping Rigidbodies"); diff --git a/Editor/Mono/ScriptAttributeGUI/Implementations/ExposedReferenceDrawer.cs b/Editor/Mono/ScriptAttributeGUI/Implementations/ExposedReferenceDrawer.cs index f0f15fdd38..c84785b4f2 100644 --- a/Editor/Mono/ScriptAttributeGUI/Implementations/ExposedReferenceDrawer.cs +++ b/Editor/Mono/ScriptAttributeGUI/Implementations/ExposedReferenceDrawer.cs @@ -16,7 +16,7 @@ abstract class BaseExposedPropertyDrawer : UnityEditor.PropertyDrawer protected readonly GUIContent ExposePropertyContent = EditorGUIUtility.TrTextContent("Expose Property"); protected readonly GUIContent UnexposePropertyContent = EditorGUIUtility.TrTextContent("Unexpose Property"); protected readonly GUIContent NotFoundOn = EditorGUIUtility.TrTextContent("not found on"); - protected readonly GUIContent OverridenByContent = EditorGUIUtility.TrTextContent("Overriden by "); + protected readonly GUIContent OverridenByContent = EditorGUIUtility.TrTextContent("Overridden by "); private GUIContent m_ModifiedLabel = new GUIContent(); diff --git a/Editor/Mono/Scripting/APIUpdater/APIUpdaterManager.bindings.cs b/Editor/Mono/Scripting/APIUpdater/APIUpdaterManager.bindings.cs index 8f6da209dc..c10f9cd3d0 100644 --- a/Editor/Mono/Scripting/APIUpdater/APIUpdaterManager.bindings.cs +++ b/Editor/Mono/Scripting/APIUpdater/APIUpdaterManager.bindings.cs @@ -233,7 +233,7 @@ private static bool HandleAssemblyUpdaterErrors(IEnumerable completedSuccessfully) { - sb.AppendFormat(L10n.Tr("Following assemblies were successfully updated but due to the failled ones above they were ignored (not copied to the destination folder).")); + sb.AppendFormat(L10n.Tr("Following assemblies were successfully updated but due to the failed ones above they were ignored (not copied to the destination folder).")); foreach (var updaterTask in completedSuccessfully) { sb.AppendFormat("{1} (Result = {2}) (Output: {3}){0}{4}{0}", Environment.NewLine, updaterTask.Candidate.Path, updaterTask.Result, updaterTask.OutputPath, updaterTask.StdOut); diff --git a/Editor/Mono/SettingsWindow/FogEditor.cs b/Editor/Mono/SettingsWindow/FogEditor.cs index 9efc2275e1..4c8d788b9f 100644 --- a/Editor/Mono/SettingsWindow/FogEditor.cs +++ b/Editor/Mono/SettingsWindow/FogEditor.cs @@ -16,7 +16,7 @@ internal class Styles public static readonly GUIContent FogLinearStart = EditorGUIUtility.TrTextContent("Start", "Controls the distance from the camera where the fog will start in the Scene."); public static readonly GUIContent FogLinearEnd = EditorGUIUtility.TrTextContent("End", "Controls the distance from the camera where the fog will completely obscure objects in the Scene."); public static readonly GUIContent FogEnable = EditorGUIUtility.TrTextContent("Fog", "Specifies whether fog is used in the Scene or not."); - public static readonly GUIContent FogColor = EditorGUIUtility.TrTextContent("Color", "Controls the color of that fog drawn in the Scene."); + public static readonly GUIContent FogColor = EditorGUIUtility.TrTextContent("Color", "Controls the color of the fog drawn in the Scene."); public static readonly GUIContent FogMode = EditorGUIUtility.TrTextContent("Mode", "Controls the mathematical function determining the way fog accumulates with distance from the camera. Options are Linear, Exponential, and Exponential Squared."); } diff --git a/Editor/Mono/SettingsWindow/GraphicsSettingsEditors.cs b/Editor/Mono/SettingsWindow/GraphicsSettingsEditors.cs index de9d885c51..db41b4dd2b 100644 --- a/Editor/Mono/SettingsWindow/GraphicsSettingsEditors.cs +++ b/Editor/Mono/SettingsWindow/GraphicsSettingsEditors.cs @@ -248,7 +248,7 @@ internal partial class Styles public static readonly GUIContent lightmapPlain = EditorGUIUtility.TrTextContent("Baked Non-Directional", "Include support for baked non-directional lightmaps."); public static readonly GUIContent lightmapDirCombined = EditorGUIUtility.TrTextContent("Baked Directional", "Include support for baked directional lightmaps."); public static readonly GUIContent lightmapKeepShadowMask = EditorGUIUtility.TrTextContent("Baked Shadowmask", "Include support for baked shadow occlusion."); - public static readonly GUIContent lightmapKeepSubtractive = EditorGUIUtility.TrTextContent("Baked Subtractive", "Include support for baked substractive lightmaps."); + public static readonly GUIContent lightmapKeepSubtractive = EditorGUIUtility.TrTextContent("Baked Subtractive", "Include support for baked subtractive lightmaps."); public static readonly GUIContent lightmapDynamicPlain = EditorGUIUtility.TrTextContent("Realtime Non-Directional", "Include support for realtime non-directional lightmaps."); public static readonly GUIContent lightmapDynamicDirCombined = EditorGUIUtility.TrTextContent("Realtime Directional", "Include support for realtime directional lightmaps."); public static readonly GUIContent lightmapFromScene = EditorGUIUtility.TrTextContent("Import From Current Scene", "Calculate lightmap modes used by the current scene."); @@ -584,7 +584,7 @@ internal partial class Styles public static readonly GUIContent reflectionProbeBlending = EditorGUIUtility.TrTextContent("Reflection Probes Blending"); public static readonly GUIContent detailNormalMap = EditorGUIUtility.TrTextContent("Detail Normal Map"); public static readonly GUIContent cascadedShadowMaps = EditorGUIUtility.TrTextContent("Cascaded Shadows"); - public static readonly GUIContent prefer32BitShadowMaps = EditorGUIUtility.TrTextContent("Prefer 32 bit shadow maps"); + public static readonly GUIContent prefer32BitShadowMaps = EditorGUIUtility.TrTextContent("Prefer 32-bit shadow maps"); public static readonly GUIContent semitransparentShadows = EditorGUIUtility.TrTextContent("Enable Semitransparent Shadows"); public static readonly GUIContent enableLPPV = EditorGUIUtility.TrTextContent("Enable Light Probe Proxy Volume"); public static readonly GUIContent renderingPath = EditorGUIUtility.TrTextContent("Rendering Path"); diff --git a/Editor/Mono/Sprites/SpriteUtilityWindow.cs b/Editor/Mono/Sprites/SpriteUtilityWindow.cs index e3396ce32a..0a97a909ba 100644 --- a/Editor/Mono/Sprites/SpriteUtilityWindow.cs +++ b/Editor/Mono/Sprites/SpriteUtilityWindow.cs @@ -24,7 +24,9 @@ protected class Styles public readonly GUIStyle preBackground = "preBackground"; public readonly GUIStyle pivotdotactive = "U2D.pivotDotActive"; public readonly GUIStyle pivotdot = "U2D.pivotDot"; - + public static readonly GUIContent noSpriteEditorWindowTitle = EditorGUIUtility.TrTextContent("Sprite Editor Window"); + public static readonly GUIContent noSpriteEditorWindow = EditorGUIUtility.TrTextContent("No Sprite Editor Window registered. Please download 2D Sprite package from Package Manager."); + public static readonly GUIContent okText = EditorGUIUtility.TrTextContent("OK"); public readonly GUIStyle dragBorderdot = new GUIStyle(); public readonly GUIStyle dragBorderDotActive = new GUIStyle(); @@ -392,7 +394,7 @@ internal static bool ShowSpriteEditorWindow() static Func showSpriteEditorWindow = () => { - Debug.Log("No Sprite Editor Window is registered."); + EditorUtility.DisplayDialog(Styles.noSpriteEditorWindowTitle.text, Styles.noSpriteEditorWindow.text, Styles.okText.text); return false; }; } // class diff --git a/Editor/Mono/UIElements/Controls/MaskField.cs b/Editor/Mono/UIElements/Controls/MaskField.cs index 08719ccc63..ef5ace4d16 100644 --- a/Editor/Mono/UIElements/Controls/MaskField.cs +++ b/Editor/Mono/UIElements/Controls/MaskField.cs @@ -247,7 +247,7 @@ internal string GetDisplayedValue(int itemIndex) } else { - newValueToShowUser = L10n.Tr("Mixed ..."); + newValueToShowUser = L10n.Tr("Mixed..."); } break; } diff --git a/Modules/AssetPipelineEditor/ImportSettings/ModelImporterClipEditor.cs b/Modules/AssetPipelineEditor/ImportSettings/ModelImporterClipEditor.cs index 86949bd7fe..bff5b11e02 100644 --- a/Modules/AssetPipelineEditor/ImportSettings/ModelImporterClipEditor.cs +++ b/Modules/AssetPipelineEditor/ImportSettings/ModelImporterClipEditor.cs @@ -112,7 +112,7 @@ private class Styles EditorGUIUtility.TrTextContent("Once", "The animation plays through to the end once and then stops."), EditorGUIUtility.TrTextContent("Loop", "The animation plays through and then restarts when the end is reached."), EditorGUIUtility.TrTextContent("PingPong", "The animation plays through and then plays in reverse from the end to the start, and so on."), - EditorGUIUtility.TrTextContent("ClampForever", "The animation plays through but the last frame is repeated indefinitely. This is not the same as Once mode because playback does not technically stop at the last frame (which is useful when blending animations).") + EditorGUIUtility.TrTextContent("ClampForever", "The animation plays through, but the last frame is repeated indefinitely. This is not the same as Once mode because playback does not technically stop at the last frame (which is useful when blending animations).") }; public GUIContent BakeIK = EditorGUIUtility.TrTextContent("Bake Animations", "Enable this when using IK or simulation in your animation package. Unity will convert to forward kinematics on import. This option is available only for Maya, 3dsMax and Cinema4D files."); diff --git a/Modules/AssetPipelineEditor/ImportSettings/ModelImporterModelEditor.cs b/Modules/AssetPipelineEditor/ImportSettings/ModelImporterModelEditor.cs index 361a145686..a25492512e 100644 --- a/Modules/AssetPipelineEditor/ImportSettings/ModelImporterModelEditor.cs +++ b/Modules/AssetPipelineEditor/ImportSettings/ModelImporterModelEditor.cs @@ -122,7 +122,7 @@ protected static class Styles public static GUIContent NormalsLabel = EditorGUIUtility.TrTextContent("Normals", "Source of mesh normals. If Import is selected and a mesh has no normals, they will be calculated instead."); public static GUIContent RecalculateNormalsLabel = EditorGUIUtility.TrTextContent("Normals Mode", "How to weight faces when calculating normals."); - public static GUIContent SmoothingAngle = EditorGUIUtility.TrTextContent("Smoothing Angle", "When calculating normals on a mesh that doesn’t have smoothing groups, edges between faces will be smooth if this value is greater than the angle between the faces."); + public static GUIContent SmoothingAngle = EditorGUIUtility.TrTextContent("Smoothing Angle", "When calculating normals on a mesh that doesn't have smoothing groups, edges between faces will be smooth if this value is greater than the angle between the faces."); public static GUIContent TangentsLabel = EditorGUIUtility.TrTextContent("Tangents", "Source of mesh tangents. If Import is selected and a mesh has no tangents, they will be calculated instead."); diff --git a/Modules/AssetPipelineEditor/ImportSettings/ModelImporterRigEditor.cs b/Modules/AssetPipelineEditor/ImportSettings/ModelImporterRigEditor.cs index 0991b498b6..1eb4327eb9 100644 --- a/Modules/AssetPipelineEditor/ImportSettings/ModelImporterRigEditor.cs +++ b/Modules/AssetPipelineEditor/ImportSettings/ModelImporterRigEditor.cs @@ -99,7 +99,7 @@ static class Styles public static GUIContent UpdateMuscleDefinitionFromSource = EditorGUIUtility.TrTextContent("Update", "Update the copy of the muscle definition from the source."); public static GUIContent RootNode = EditorGUIUtility.TrTextContent("Root node", "Specify the root node used to extract the animation translation."); - public static GUIContent AvatarDefinition = EditorGUIUtility.TrTextContent("Avatar Definition", "Choose between Create From This Model or Copy From Other Avatar. The first one create an Avatar for this file and the second one use an Avatar from another file to import animation."); + public static GUIContent AvatarDefinition = EditorGUIUtility.TrTextContent("Avatar Definition", "Choose between Create From This Model or Copy From Other Avatar. The first one creates an Avatar for this file and the second one uses an Avatar from another file to import animation."); public static GUIContent[] AvatarDefinitionOpt = { @@ -116,10 +116,10 @@ static class Styles public static GUIContent MaxBonesPerVertex = EditorGUIUtility.TrTextContent("Max Bones/Vertex", "Number of bones that can affect each vertex."); public static GUIContent MinBoneWeight = EditorGUIUtility.TrTextContent("Min Bone Weight", "Bone weights smaller than this value are rejected. The remaining weights are scaled to add up to 1.0."); - public static GUIContent UpdateReferenceClips = EditorGUIUtility.TrTextContent("Update reference clips", "Click on this button to update all the @convention file referencing this file. Should set all these files to Copy From Other Avatar, set the source Avatar to this one and reimport all these files."); + public static GUIContent UpdateReferenceClips = EditorGUIUtility.TrTextContent("Update reference clips", "Click on this button to update all the @convention files referencing this file. Should set all these files to Copy From Other Avatar, set the source Avatar to this one and reimport all these files."); public static GUIContent ImportMessages = EditorGUIUtility.TrTextContent("Import Messages"); - public static GUIContent ExtraExposedTransform = EditorGUIUtility.TrTextContent("Extra Transforms to Expose", "Select the list of transforms to expose in the optmized GameObject hierarchy."); + public static GUIContent ExtraExposedTransform = EditorGUIUtility.TrTextContent("Extra Transforms to Expose", "Select the list of transforms to expose in the optimized GameObject hierarchy."); } public ModelImporterRigEditor(AssetImporterEditor panelContainer) diff --git a/Modules/GraphViewEditor/Elements/Blackboard/Blackboard.cs b/Modules/GraphViewEditor/Elements/Blackboard/Blackboard.cs index bb6496c8af..4a87ffb3e3 100644 --- a/Modules/GraphViewEditor/Elements/Blackboard/Blackboard.cs +++ b/Modules/GraphViewEditor/Elements/Blackboard/Blackboard.cs @@ -136,6 +136,11 @@ public Blackboard() { e.StopPropagation(); }); + + RegisterCallback(e => + { + e.StopPropagation(); + }); } } } diff --git a/Modules/PackageManagerUI/Editor/UI/PackageDetails.cs b/Modules/PackageManagerUI/Editor/UI/PackageDetails.cs index b5dbab4894..77ac6bb33a 100644 --- a/Modules/PackageManagerUI/Editor/UI/PackageDetails.cs +++ b/Modules/PackageManagerUI/Editor/UI/PackageDetails.cs @@ -630,15 +630,25 @@ private void RemoveClick() } } - var result = 1; // Cancel - if (!PackageManagerPrefs.SkipRemoveConfirmation) + var result = 0; + if (DisplayPackage.IsBuiltIn) { - result = EditorUtility.DisplayDialogComplex("Removing Package", - "Are you sure you wanted to remove this package?", - "Remove", "Cancel", "Remove and do not ask again"); + if (!PackageManagerPrefs.SkipDisableConfirmation) + { + result = EditorUtility.DisplayDialogComplex("Disable Built-In Package", + "Are you sure you want to disable this built-in package?", + "Disable", "Cancel", "Disable and don't ask again"); + } } else - result = 0; + { + if (!PackageManagerPrefs.SkipRemoveConfirmation) + { + result = EditorUtility.DisplayDialogComplex("Removing Package", + "Are you sure you want to remove this package?", + "Remove", "Cancel", "Remove and don't ask again"); + } + } // Cancel if (result == 1) @@ -646,7 +656,12 @@ private void RemoveClick() // Do not ask again if (result == 2) - PackageManagerPrefs.SkipRemoveConfirmation = true; + { + if (DisplayPackage.IsBuiltIn) + PackageManagerPrefs.SkipDisableConfirmation = true; + else + PackageManagerPrefs.SkipRemoveConfirmation = true; + } // Remove DetailError.ClearError(); diff --git a/Modules/PackageManagerUI/Editor/UI/PackageManagerPrefs.cs b/Modules/PackageManagerUI/Editor/UI/PackageManagerPrefs.cs index 99a035b863..f1b00296f9 100644 --- a/Modules/PackageManagerUI/Editor/UI/PackageManagerPrefs.cs +++ b/Modules/PackageManagerUI/Editor/UI/PackageManagerPrefs.cs @@ -10,6 +10,7 @@ namespace UnityEditor.PackageManager.UI internal static class PackageManagerPrefs { private const string kSkipRemoveConfirmationPrefs = "PackageManager.SkipRemoveConfirmation"; + private const string kSkipDisableConfirmationPrefs = "PackageManager.SkipDisableConfirmation"; private const string kShowPackageDependenciesPrefs = "PackageManager.ShowPackageDependencies"; private const string kShowPreviewPackagesPrefKeyPrefix = "PackageManager.ShowPreviewPackages_"; private const string kShowPreviewPackagesWarningPrefs = "PackageManager.ShowPreviewPackagesWarning"; @@ -27,6 +28,12 @@ public static bool SkipRemoveConfirmation set { EditorPrefs.SetBool(kSkipRemoveConfirmationPrefs, value); } } + public static bool SkipDisableConfirmation + { + get { return EditorPrefs.GetBool(kSkipDisableConfirmationPrefs, false); } + set { EditorPrefs.SetBool(kSkipDisableConfirmationPrefs, value); } + } + public static bool ShowPackageDependencies { get { return EditorPrefs.GetBool(kShowPackageDependenciesPrefs, false); } diff --git a/Modules/ParticleSystemEditor/ParticleSystemModules/CollisionModuleUI.cs b/Modules/ParticleSystemEditor/ParticleSystemModules/CollisionModuleUI.cs index b6480ba960..c4e2589dc4 100644 --- a/Modules/ParticleSystemEditor/ParticleSystemModules/CollisionModuleUI.cs +++ b/Modules/ParticleSystemEditor/ParticleSystemModules/CollisionModuleUI.cs @@ -70,7 +70,7 @@ class Texts public GUIContent collidesWithDynamic = EditorGUIUtility.TrTextContent("Enable Dynamic Colliders", "Should particles collide with dynamic objects?"); public GUIContent maxCollisionShapes = EditorGUIUtility.TrTextContent("Max Collision Shapes", "How many collision shapes can be considered for particle collisions. Excess shapes will be ignored. Terrains take priority."); public GUIContent quality = EditorGUIUtility.TrTextContent("Collision Quality", "Quality of world collisions. Medium and low quality are approximate and may leak particles."); - public GUIContent voxelSize = EditorGUIUtility.TrTextContent("Voxel Size", "Size of voxels in the collision cache. Smaller values improve accuracy, but require higher memory usage and are less efficient."); + public GUIContent voxelSize = EditorGUIUtility.TrTextContent("Voxel Size", "Size of voxels in the collision cache. Smaller values improve accuracy but require higher memory usage and are less efficient."); public GUIContent collisionMessages = EditorGUIUtility.TrTextContent("Send Collision Messages", "Send collision callback messages."); public GUIContent collisionType = EditorGUIUtility.TrTextContent("Type", "Collide with a list of Planes, or the Physics World."); public GUIContent collisionMode = EditorGUIUtility.TrTextContent("Mode", "Use 3D Physics or 2D Physics."); diff --git a/Modules/ParticleSystemEditor/ParticleSystemModules/InitialModuleUI.cs b/Modules/ParticleSystemEditor/ParticleSystemModules/InitialModuleUI.cs index 848208a6ab..ea0cc071e4 100644 --- a/Modules/ParticleSystemEditor/ParticleSystemModules/InitialModuleUI.cs +++ b/Modules/ParticleSystemEditor/ParticleSystemModules/InitialModuleUI.cs @@ -47,7 +47,7 @@ class Texts { public GUIContent duration = EditorGUIUtility.TrTextContent("Duration", "The length of time the Particle System is emitting particles. If the system is looping, this indicates the length of one cycle."); public GUIContent looping = EditorGUIUtility.TrTextContent("Looping", "If true, the emission cycle will repeat after the duration."); - public GUIContent prewarm = EditorGUIUtility.TrTextContent("Prewarm", "When played a prewarmed system will be in a state as if it had emitted one loop cycle. Can only be used if the system is looping."); + public GUIContent prewarm = EditorGUIUtility.TrTextContent("Prewarm", "When played, a prewarmed system will be in a state as if it had emitted one loop cycle. Can only be used if the system is looping."); public GUIContent startDelay = EditorGUIUtility.TrTextContent("Start Delay", "Delay in seconds that this Particle System will wait before emitting particles. Cannot be used together with a prewarmed looping system."); public GUIContent maxParticles = EditorGUIUtility.TrTextContent("Max Particles", "The number of particles in the system will be limited by this number. Emission will be temporarily halted if this is reached."); public GUIContent lifetime = EditorGUIUtility.TrTextContent("Start Lifetime", "Start lifetime in seconds, particle will die when its lifetime reaches 0."); @@ -69,7 +69,7 @@ class Texts public GUIContent randomSeed = EditorGUIUtility.TrTextContent("Random Seed", "Randomize the look of the Particle System. Using the same seed will make the Particle System play identically each time. After changing this value, restart the Particle System to see the changes, or check the Resimulate box."); public GUIContent emitterVelocity = EditorGUIUtility.TrTextContent("Emitter Velocity", "When the Particle System is moving, should we use its Transform, or Rigidbody Component, to calculate its velocity?"); public GUIContent stopAction = EditorGUIUtility.TrTextContent("Stop Action", "When the Particle System is stopped and all particles have died, should the GameObject automatically disable/destroy itself?"); - public GUIContent cullingMode = EditorGUIUtility.TrTextContent("Culling Mode", "Choose whether to continue simulating the Particle System when offscreen. Catch-up mode pauses offscreen simulations, but performs a large simulation step when they become visible, giving the appearance that they were never paused. Automatic uses Pause mode for looping systems, and AlwaysSimulate if not looping."); + public GUIContent cullingMode = EditorGUIUtility.TrTextContent("Culling Mode", "Choose whether to continue simulating the Particle System when offscreen. Catch-up mode pauses offscreen simulations but performs a large simulation step when they become visible, giving the appearance that they were never paused. Automatic uses Pause mode for looping systems, and AlwaysSimulate if not looping."); public GUIContent ringBufferMode = EditorGUIUtility.TrTextContent("Ring Buffer Mode", "Rather than dying when their lifetime has elapsed, particles will remain alive until the Max Particles buffer is full, at which point new particles will replace the oldest."); public GUIContent ringBufferLoopRange = EditorGUIUtility.TrTextContent("Loop Range", "Particle lifetimes may loop between a fade-in and fade-out time, in order to use curves for the entire time they are alive. Values are in the 0-1 range."); public GUIContent x = EditorGUIUtility.TextContent("X"); diff --git a/Modules/ParticleSystemEditor/ParticleSystemModules/TriggerModuleUI.cs b/Modules/ParticleSystemEditor/ParticleSystemModules/TriggerModuleUI.cs index 40c700fac1..4f30706c16 100644 --- a/Modules/ParticleSystemEditor/ParticleSystemModules/TriggerModuleUI.cs +++ b/Modules/ParticleSystemEditor/ParticleSystemModules/TriggerModuleUI.cs @@ -30,8 +30,8 @@ class Texts public GUIContent createCollisionShape = EditorGUIUtility.TrTextContent("", "Create a GameObject containing a sphere collider and assigns it to the list."); public GUIContent inside = EditorGUIUtility.TrTextContent("Inside", "What to do for particles that are inside the collision volume."); public GUIContent outside = EditorGUIUtility.TrTextContent("Outside", "What to do for particles that are outside the collision volume."); - public GUIContent enter = EditorGUIUtility.TrTextContent("Enter", "Triggered once when particles enter the collison volume."); - public GUIContent exit = EditorGUIUtility.TrTextContent("Exit", "Triggered once when particles leave the collison volume."); + public GUIContent enter = EditorGUIUtility.TrTextContent("Enter", "Triggered once when particles enter the collision volume."); + public GUIContent exit = EditorGUIUtility.TrTextContent("Exit", "Triggered once when particles leave the collision volume."); public GUIContent radiusScale = EditorGUIUtility.TrTextContent("Radius Scale", "Scale particle bounds by this amount to get more precise collisions."); public GUIContent visualizeBounds = EditorGUIUtility.TrTextContent("Visualize Bounds", "Render the collision bounds of the particles."); diff --git a/Modules/ParticleSystemEditor/ParticleSystemModules/UVModuleUI.cs b/Modules/ParticleSystemEditor/ParticleSystemModules/UVModuleUI.cs index e003212301..87f44b0f67 100644 --- a/Modules/ParticleSystemEditor/ParticleSystemModules/UVModuleUI.cs +++ b/Modules/ParticleSystemEditor/ParticleSystemModules/UVModuleUI.cs @@ -29,7 +29,7 @@ class Texts public GUIContent mode = EditorGUIUtility.TrTextContent("Mode", "Animation frames can either be specified on a regular grid texture, or as a list of Sprites."); public GUIContent timeMode = EditorGUIUtility.TrTextContent("Time Mode", "Play frames either based on the lifetime of the particle, the speed of the particle, or at a constant FPS, regardless of particle lifetime."); public GUIContent fps = EditorGUIUtility.TrTextContent("FPS", "Specify the Frames Per Second of the animation."); - public GUIContent frameOverTime = EditorGUIUtility.TrTextContent("Frame over Time", "Controls the uv animation frame of each particle over its lifetime. On the horisontal axis you will find the lifetime. On the vertical axis you will find the sheet index."); + public GUIContent frameOverTime = EditorGUIUtility.TrTextContent("Frame over Time", "Controls the uv animation frame of each particle over its lifetime. On the horizontal axis you will find the lifetime. On the vertical axis you will find the sheet index."); public GUIContent startFrame = EditorGUIUtility.TrTextContent("Start Frame", "Phase the animation, so it starts on a frame other than 0."); public GUIContent speedRange = EditorGUIUtility.TrTextContent("Speed Range", "Remaps speed in the defined range to a 0-1 value through the animation."); public GUIContent tiles = EditorGUIUtility.TrTextContent("Tiles", "Defines the tiling of the texture."); diff --git a/Modules/ProfilerEditor/ProfilerWindow/ProfilerDetailedCallsView.cs b/Modules/ProfilerEditor/ProfilerWindow/ProfilerDetailedCallsView.cs index 659d2ec350..5d914d5b62 100644 --- a/Modules/ProfilerEditor/ProfilerWindow/ProfilerDetailedCallsView.cs +++ b/Modules/ProfilerEditor/ProfilerWindow/ProfilerDetailedCallsView.cs @@ -383,8 +383,8 @@ static class Styles public static GUIContent calleesLabel = EditorGUIUtility.TrTextContent("Calls To", "Functions which are called from the selected function\n\n(Press 'F' for frame selection)"); public static GUIContent callsLabel = EditorGUIUtility.TrTextContent("Calls", "Total number of calls in a selected frame"); public static GUIContent gcAllocLabel = EditorGUIUtility.TrTextContent("GC Alloc"); - public static GUIContent timeMsCallersLabel = EditorGUIUtility.TrTextContent("Time ms", "Total time the selected function spend within a parent"); - public static GUIContent timeMsCalleesLabel = EditorGUIUtility.TrTextContent("Time ms", "Total time the child call spend within selected function"); + public static GUIContent timeMsCallersLabel = EditorGUIUtility.TrTextContent("Time ms", "Total time the selected function spends within a parent"); + public static GUIContent timeMsCalleesLabel = EditorGUIUtility.TrTextContent("Time ms", "Total time the child call spends within selected function"); public static GUIContent timePctCallersLabel = EditorGUIUtility.TrTextContent("Time %", "Shows how often the selected function was called from the parent call"); public static GUIContent timePctCalleesLabel = EditorGUIUtility.TrTextContent("Time %", "Shows how often child call was called from the selected function"); } diff --git a/Modules/ShortcutManagerEditor/ShortcutController.cs b/Modules/ShortcutManagerEditor/ShortcutController.cs index d05be83071..5c4bd4b53d 100644 --- a/Modules/ShortcutManagerEditor/ShortcutController.cs +++ b/Modules/ShortcutManagerEditor/ShortcutController.cs @@ -165,9 +165,6 @@ void HandleModeChanged(ModeService.ModeChangedArgs args) if (shortcutProfiles == null || shortcutProfiles.Count == 0) return; - // Rebuild shortcuts so all shortcuts bound to invisible menu items are removed. - RebuildShortcuts(); - string defaultMode = null; try { @@ -255,7 +252,7 @@ void LoadProfileById(string profileId) static bool TryParseUniquePrefKeyString(string prefString, out string name, out Event keyboardEvent, out string shortcut) { - int i = prefString.IndexOf(";"); + int i = prefString.IndexOf(";", StringComparison.Ordinal); if (i < 0) { name = null; diff --git a/Modules/SketchUpEditor/Mono/SketchUpImporterModelEditor.cs b/Modules/SketchUpEditor/Mono/SketchUpImporterModelEditor.cs index e8c50d13e0..1f09047d42 100644 --- a/Modules/SketchUpEditor/Mono/SketchUpImporterModelEditor.cs +++ b/Modules/SketchUpEditor/Mono/SketchUpImporterModelEditor.cs @@ -177,7 +177,7 @@ public void SetSelectedNodes(int[] selectedNodes) static public readonly GUIContent fileUnitLabel = EditorGUIUtility.TrTextContent("Unit conversion", "Length measurement to unit conversion. The value in Scale Factor is calculated based on the value here"); static public readonly GUIContent longitudeLabel = EditorGUIUtility.TrTextContent("Longitude", "Longitude Geo-location"); static public readonly GUIContent latitudeLabel = EditorGUIUtility.TrTextContent("Latitude", "Latitude Geo-location"); - static public readonly GUIContent northCorrectionLabel = EditorGUIUtility.TrTextContent("North Correction", "The angle which will rotate the north direction to the z-axis for a the model"); + static public readonly GUIContent northCorrectionLabel = EditorGUIUtility.TrTextContent("North Correction", "The angle which will rotate the north direction to the z-axis for the model"); static public readonly GUIContent[] measurementOptions = { EditorGUIUtility.TrTextContent("Meters"), diff --git a/Modules/TerrainEditor/PaintTools/CreateTerrainTool.cs b/Modules/TerrainEditor/PaintTools/CreateTerrainTool.cs index 1072bd9b58..8fe8163277 100644 --- a/Modules/TerrainEditor/PaintTools/CreateTerrainTool.cs +++ b/Modules/TerrainEditor/PaintTools/CreateTerrainTool.cs @@ -15,7 +15,7 @@ internal class CreateTerrainTool : TerrainPaintTool { private class Styles { - public GUIContent fillHeightmapUsingNeighbors = EditorGUIUtility.TrTextContent("Fill Heightmap Using Neighbors", "If selected, it will fill heightmap of the new terrain performing cross blend of heightmaps of it's neighbors."); + public GUIContent fillHeightmapUsingNeighbors = EditorGUIUtility.TrTextContent("Fill Heightmap Using Neighbors", "If selected, it will fill heightmap of the new terrain performing cross blend of heightmaps of its neighbors."); public GUIContent fillAddressMode = EditorGUIUtility.TrTextContent("Fill Heightmap Address Mode", "Type of the terrain's neighbors sampling address mode."); } diff --git a/Modules/TerrainEditor/PaintTools/StampTool.cs b/Modules/TerrainEditor/PaintTools/StampTool.cs index f2d5ec7b5d..03829aad7e 100644 --- a/Modules/TerrainEditor/PaintTools/StampTool.cs +++ b/Modules/TerrainEditor/PaintTools/StampTool.cs @@ -32,7 +32,7 @@ class Styles public readonly GUIContent description = EditorGUIUtility.TrTextContent("Left click to stamp the brush onto the terrain.\n\nHold control and mousewheel to adjust height.\nHold shift to invert the stamp."); public readonly GUIContent height = EditorGUIUtility.TrTextContent("Stamp Height", "You can set the Stamp Height manually or you can hold shift and mouse wheel on the terrain to adjust it."); public readonly GUIContent down = EditorGUIUtility.TrTextContent("Subtract", "Subtract the stamp from the terrain."); - public readonly GUIContent maxadd = EditorGUIUtility.TrTextContent("Max <--> Add", "Blend between adding the heights, and taking the maximum."); + public readonly GUIContent maxadd = EditorGUIUtility.TrTextContent("Max <--> Add", "Blend between adding the heights and taking the maximum."); } private static Styles m_styles; diff --git a/Modules/TerrainEditor/TerrainInspector.cs b/Modules/TerrainEditor/TerrainInspector.cs index 77d43f1bbe..08e787e590 100644 --- a/Modules/TerrainEditor/TerrainInspector.cs +++ b/Modules/TerrainEditor/TerrainInspector.cs @@ -78,7 +78,7 @@ class Styles public readonly GUIContent[] toolNames = { EditorGUIUtility.TrTextContent("Create Neighbor Terrains", "Click the edges to create neighbor terrains"), - EditorGUIUtility.TrTextContent("Paint Terrain", "Select a tool from the drop down list"), + EditorGUIUtility.TrTextContent("Paint Terrain", "Select a tool from the drop-down list"), EditorGUIUtility.TrTextContent("Paint Trees", "Click to paint trees.\n\nHold shift and click to erase trees.\n\nHold Ctrl and click to erase only trees of the selected type."), EditorGUIUtility.TrTextContent("Paint Details", "Click to paint details.\n\nHold shift and click to erase details.\n\nHold Ctrl and click to erase only details of the selected type."), EditorGUIUtility.TrTextContent("Terrain Settings") @@ -138,11 +138,11 @@ class Styles // Settings public readonly GUIContent basicTerrain = EditorGUIUtility.TrTextContent("Basic Terrain"); public readonly GUIContent groupingID = EditorGUIUtility.TrTextContent("Grouping ID", "Grouping ID for auto connection"); - public readonly GUIContent allowAutoConnect = EditorGUIUtility.TrTextContent("Auto Connect", "Allow the current terrain tile automatically connect to neighboring tiles sharing the same grouping ID."); + public readonly GUIContent allowAutoConnect = EditorGUIUtility.TrTextContent("Auto Connect", "Allow the current terrain tile to automatically connect to neighboring tiles sharing the same grouping ID."); public readonly GUIContent attemptReconnect = EditorGUIUtility.TrTextContent("Reconnect", "Will attempt to re-run auto connection"); public readonly GUIContent drawTerrain = EditorGUIUtility.TrTextContent("Draw", "Toggle the rendering of terrain"); public readonly GUIContent drawInstancedTerrain = EditorGUIUtility.TrTextContent("Draw Instanced" , "Toggle terrain instancing rendering"); - public readonly GUIContent pixelError = EditorGUIUtility.TrTextContent("Pixel Error", "The accuracy of the mapping between the terrain maps (heightmap, textures, etc) and the generated terrain; higher values indicate lower accuracy but lower rendering overhead."); + public readonly GUIContent pixelError = EditorGUIUtility.TrTextContent("Pixel Error", "The accuracy of the mapping between the terrain maps (heightmap, textures, etc.) and the generated terrain; higher values indicate lower accuracy but lower rendering overhead."); public readonly GUIContent baseMapDist = EditorGUIUtility.TrTextContent("Base Map Dist.", "The maximum distance at which terrain textures will be displayed at full resolution. Beyond this distance, a lower resolution composite image will be used for efficiency."); public readonly GUIContent castShadows = EditorGUIUtility.TrTextContent("Cast Shadows", "Does the terrain cast shadows?"); public readonly GUIContent material = EditorGUIUtility.TrTextContent("Material", "The material used to render the terrain. The shader used by the material will affect how the color channels of a terrain texture are interpreted."); diff --git a/Modules/TreeEditor/TreeEditor.cs b/Modules/TreeEditor/TreeEditor.cs index 8ee5d00614..2c344b93f8 100644 --- a/Modules/TreeEditor/TreeEditor.cs +++ b/Modules/TreeEditor/TreeEditor.cs @@ -163,9 +163,9 @@ public enum EditMode private static string weldLengthString = L10n.Tr("Weld Length|Defines how far up the branch the weld spread starts."); - private static string spreadTopString = L10n.Tr("Spread Top|Weld's spread factor on the top-side of the branch, relative to it's parent branch. Zero means no spread."); + private static string spreadTopString = L10n.Tr("Spread Top|Weld's spread factor on the top-side of the branch, relative to its parent branch. Zero means no spread."); - private static string spreadBottomString = L10n.Tr("Spread Bottom|Weld's spread factor on the bottom-side of the branch, relative to it's parent branch. Zero means no spread."); + private static string spreadBottomString = L10n.Tr("Spread Bottom|Weld's spread factor on the bottom-side of the branch, relative to its parent branch. Zero means no spread."); private static string breakChanceString = L10n.Tr("Break Chance|Chance of a branch breaking, i.e. 0 = no branches are broken, 0.5 = half of the branches are broken, 1.0 = all the branches are broken."); @@ -2558,7 +2558,7 @@ void DrawHierachy(TreeData treeData, Renderer renderer, Rect sizeRect) int ms = renderer.sharedMaterials.Length; Rect labelrect = new Rect(hierachyDisplayRect.xMax - 80 - 4, hierachyDisplayRect.yMax + offset.y - 40 - 4, 80, 40); - string text = TreeEditorHelper.GetGUIContent("Hierachy Stats").text; + string text = TreeEditorHelper.GetGUIContent("Hierarchy Stats").text; text = text.Replace("[v]", vs.ToString()); text = text.Replace("[t]", ts.ToString()); text = text.Replace("[m]", ms.ToString()); diff --git a/Modules/UIElements/Renderer/UIRChainBuilderImpl.cs b/Modules/UIElements/Renderer/UIRChainBuilderImpl.cs index 2c02f2c94a..3f38070e36 100644 --- a/Modules/UIElements/Renderer/UIRChainBuilderImpl.cs +++ b/Modules/UIElements/Renderer/UIRChainBuilderImpl.cs @@ -143,9 +143,12 @@ internal static void ProcessRegenText(RenderChain renderChain, VisualElement ve, static Matrix4x4 GetTransformIDTransformInfo(VisualElement ve) { Debug.Assert(ve.renderChainData.allocatedTransformID || (ve.renderHint & (RenderHint.GroupTransform)) != 0); + Matrix4x4 transform; if (ve.renderChainData.groupTransformAncestor != null) - return ve.renderChainData.groupTransformAncestor.worldTransform.inverse * ve.worldTransform; - return ve.worldTransform; + transform = ve.renderChainData.groupTransformAncestor.worldTransform.inverse * ve.worldTransform; + else transform = ve.worldTransform; + transform.m22 = transform.m33 = 1.0f; // Once world-space mode is introduced, this should become conditional + return transform; } static Vector4 GetTransformIDClipInfo(VisualElement ve) @@ -171,6 +174,7 @@ static void GetVerticesTransformInfo(VisualElement ve, out Matrix4x4 transform, else if (ve.renderChainData.groupTransformAncestor != null) transform = ve.renderChainData.groupTransformAncestor.worldTransform.inverse * ve.worldTransform; else transform = ve.worldTransform; + transform.m22 = transform.m33 = 1.0f; // Once world-space mode is introduced, this should become conditional transformID = ve.renderChainData.transformID.start; } diff --git a/Modules/VREditor/Mono/PlayerSettingsEditorVR.cs b/Modules/VREditor/Mono/PlayerSettingsEditorVR.cs index 9a38343ce3..89663f479e 100644 --- a/Modules/VREditor/Mono/PlayerSettingsEditorVR.cs +++ b/Modules/VREditor/Mono/PlayerSettingsEditorVR.cs @@ -25,7 +25,7 @@ static class Styles public static readonly GUIContent singlepassAndroidWarning2 = EditorGUIUtility.TrTextContent("Multi Pass will be used on Android devices that don't support Single Pass."); public static readonly GUIContent singlepassAndroidWarning3 = EditorGUIUtility.TrTextContent("When using a Scriptable Render Pipeline, Single Pass Double Wide will be used on Android devices that don't support Single Pass Instancing or Multi-view."); public static readonly GUIContent singlePassInstancedWarning = EditorGUIUtility.TrTextContent("Single Pass Instanced is only supported on Windows. Multi Pass will be used on other platforms."); - public static readonly GUIContent multiPassNotSupportedWithSRP = EditorGUIUtility.TrTextContent("Multi Pass is only supported using the legacy render pipelies. Stereo Rendering Mode is set to the fallback mode of Single Pass."); + public static readonly GUIContent multiPassNotSupportedWithSRP = EditorGUIUtility.TrTextContent("Multi Pass is only supported using the legacy render pipelines. Stereo Rendering Mode is set to the fallback mode of Single Pass."); public static readonly GUIContent[] kDefaultStereoRenderingPaths = { diff --git a/Modules/VideoEditor/Editor/VideoPlayerEditor.cs b/Modules/VideoEditor/Editor/VideoPlayerEditor.cs index 89fa5cc45c..757f57e88e 100644 --- a/Modules/VideoEditor/Editor/VideoPlayerEditor.cs +++ b/Modules/VideoEditor/Editor/VideoPlayerEditor.cs @@ -45,7 +45,7 @@ class Styles public readonly GUIContent cameraContent = EditorGUIUtility.TrTextContent("Camera", "Camera where the images will be drawn, behind (Back Plane) or in front of (Front Plane) of the scene."); public readonly GUIContent textureContent = - EditorGUIUtility.TrTextContent("Target Texture", "RenderTexture where the images will be drawn. RenderTextures can be created under the Assets folder and the used on other objects."); + EditorGUIUtility.TrTextContent("Target Texture", "RenderTexture where the images will be drawn. RenderTextures can be created under the Assets folder and then used on other objects."); public readonly GUIContent alphaContent = EditorGUIUtility.TrTextContent("Alpha", "A value less than 1.0 will reveal the content behind the video."); public readonly GUIContent camera3DLayout = diff --git a/README.md b/README.md index 2b546e1668..2d58273022 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## Unity 2019.2.0a13 C# reference source code +## Unity 2019.2.0a14 C# reference source code The C# part of the Unity engine and editor source code. May be used for reference purposes only.