From 4a6d0459b7710d693344028b7647d86cb22a0ae9 Mon Sep 17 00:00:00 2001 From: Unity Technologies Date: Wed, 17 Sep 2025 11:13:50 +0000 Subject: [PATCH 01/34] Unity 6000.3.0b2 C# reference source code --- .../Mono/Animation/AnimationMode.bindings.cs | 30 +- .../Animation/AnimationWindow/AnimEditor.cs | 12 +- Editor/Mono/AnimatorController.bindings.cs | 9 +- Editor/Mono/AssemblyInfo/AssemblyInfo.cs | 12 +- .../BuildCallbackContext.bindings.cs | 81 + .../BuildPipeline/BuildPipelineInterfaces.cs | 60 + Editor/Mono/BuildPlayerWindowBuildMethods.cs | 7 +- Editor/Mono/BuildProfile/BuildProfile.cs | 17 - .../BuildProfile/BuildProfileModuleUtil.cs | 1 + .../Internal/AddSettingsDropdownWindow.cs | 4 + Editor/Mono/BuildTargetConverter.cs | 61 +- Editor/Mono/BuildTargetDiscovery.bindings.cs | 1 + Editor/Mono/ConsoleWindow.cs | 23 +- Editor/Mono/EditorApplication.cs | 2 +- Editor/Mono/EditorBuildSettings.bindings.cs | 1 + Editor/Mono/EditorDeeplink.cs | 124 ++ Editor/Mono/EditorGUI.cs | 9 + Editor/Mono/EditorGUIUtility.bindings.cs | 2 +- Editor/Mono/GI/BakePipeline.bindings.cs | 33 + Editor/Mono/GI/InputExtraction.bindings.cs | 32 +- Editor/Mono/GI/InputExtraction.cs | 110 +- Editor/Mono/GI/LightBaker.bindings.cs | 1476 +++++++++-------- Editor/Mono/GI/Lightmapping.bindings.cs | 74 +- Editor/Mono/GI/ProbeIntegrator.bindings.cs | 32 +- Editor/Mono/GUI/AboutWindow.cs | 29 +- Editor/Mono/GUI/AssetPopupBackend.cs | 12 +- Editor/Mono/GUI/ColorPicker.cs | 4 +- Editor/Mono/GUI/PackageImportTreeView.cs | 4 - Editor/Mono/GUI/Toolbars/Toolbar.cs | 2 +- Editor/Mono/GUI/TreeView/AssetsTreeViewGUI.cs | 2 +- Editor/Mono/GameObjectUtility.bindings.cs | 35 +- Editor/Mono/GenerateIconsWithMipLevels.cs | 2 +- Editor/Mono/GlobalObjectId.bindings.cs | 11 +- Editor/Mono/Handles/HandleUtility.cs | 70 +- Editor/Mono/Handles/Handles.cs | 36 +- Editor/Mono/HierarchyProperty.bindings.cs | 13 +- Editor/Mono/Inspector/AvatarMaskInspector.cs | 7 +- .../Mono/Inspector/EditorSettingsInspector.cs | 21 - Editor/Mono/Inspector/GameObjectInspector.cs | 35 +- Editor/Mono/Inspector/LODGroupEditor.cs | 19 +- .../Mono/Inspector/LightingSettingsEditor.cs | 32 +- .../PlayerSettingsEditor.cs | 162 +- .../Mono/Inspector/ReorderableListWrapper.cs | 6 +- Editor/Mono/Inspector/TagManagerInspector.cs | 6 +- .../PlayerConnection/ConnectionDropDown.cs | 1 + Editor/Mono/ObjectNames.bindings.cs | 2 +- Editor/Mono/Overlays/Overlay.cs | 2 +- Editor/Mono/Overlays/OverlayCanvas.cs | 1 + Editor/Mono/Overlays/OverlayUtilities.cs | 13 +- Editor/Mono/Prefabs/PrefabImporterEditor.cs | 27 +- Editor/Mono/Prefabs/PrefabUtility.bindings.cs | 4 +- Editor/Mono/ProjectBrowser/ProjectBrowser.cs | 32 +- ...raphicsSettingsCollectionPropertyDrawer.cs | 4 +- .../Mono/SceneModeWindows/SceneModeUtility.cs | 83 +- Editor/Mono/SceneView/SceneView.cs | 8 +- .../VersionDefinesConsoleLogs.bindings.cs | 4 +- Editor/Mono/SerializedProperty.bindings.cs | 2 +- Editor/Mono/StateMachine.bindings.cs | 4 +- Editor/Mono/Tools/EditorToolManager.cs | 55 +- .../UIElements/BaseLiveReloadAssetTracker.cs | 10 + Editor/Mono/UIElements/Controls/ColorField.cs | 107 +- .../Mono/UIElements/Controls/PropertyField.cs | 8 - .../DynamicDependencyAttribute.cs | 101 ++ .../Bindings/AccessibilityManager.bindings.cs | 8 +- .../AccessibilityNodeDataTests.bindings.cs | 52 + .../AccessibilitySettings.bindings.cs | 6 +- .../Managed/AccessibilitySettings.cs | 1 + .../Accessibility/Managed/AssistiveSupport.cs | 9 +- .../Hierarchy/AccessibilityHierarchy.cs | 439 ++--- .../Managed/Hierarchy/AccessibilityNode.cs | 159 +- .../Hierarchy/AccessibilityNode.deprecated.cs | 4 + .../AdaptivePerformanceLoaderOrderUI.cs | 26 - .../Management/ProviderSettingsEditor.cs | 5 +- .../ScriptBindings/AssetDatabase.bindings.cs | 72 +- .../ImportSettings/ModelImporterClipEditor.cs | 3 +- .../ScriptBindings/ChannelBuffer.cs | 44 +- .../ScriptBindings/ControlContext.cs | 153 +- .../ScriptBindings/DSPConfiguration.cs | 39 +- .../ScriptableGenerator.bindings.cs | 244 ++- .../ScriptableProcessor.bindings.cs | 150 +- .../ScriptableRootOutput.bindings.cs | 74 +- Modules/BuildProfileEditor/AssemblyInfo.cs | 2 + .../BuildProfileEditor/BuildProfileEditor.cs | 2 + .../BuildProfileEditor/BuildProfileWindow.cs | 2 +- .../Handlers/AddSettingsDataProvider.cs | 17 + .../Handlers/BuildProfileDataSource.cs | 30 +- .../CrashReporting/Managed/CrashReporting.cs | 5 - .../Managed/BuildReferenceMap.bindings.cs | 2 +- .../Managed/ContentBuildInterface.bindings.cs | 2 +- .../Managed/ObjectIdentifier.bindings.cs | 4 +- .../Editor/Managed/WriteCommand.cs | 12 +- .../ToolbarElements/EditorToolsToolbar.cs | 15 +- .../ToolbarElements/OverlayMenu.cs | 82 + .../ToolbarElements/PackageManagerButton.cs | 82 +- .../Managed/HierarchyNodeTypeHandler.cs | 284 ---- Modules/Hierarchy/Managed/HierarchyView.cs | 12 +- .../HierarchyViewDragAndDropSetupData.cs | 6 +- .../Managed/HierarchyViewDragHandler.cs | 20 +- .../Hierarchy/Managed/HierarchyViewItem.cs | 11 +- .../HierarchyViewOperationExtension.cs | 21 +- .../HierarchyViewSelectionExtension.cs | 1 + .../IHierarchyEditorNodeTypeHandler.cs | 43 + .../Managed/HierarchyWindow.cs | 6 +- .../HierarchyWindowContextMenuUtility.cs | 60 +- .../Managed/HierarchyWindowDefaultColumns.cs | 37 +- .../HierarchyGameObjectHandler.bindings.cs | 304 ++-- .../HierarchySceneHandler.bindings.cs | 211 ++- .../HierarchySubSceneHandler.bindings.cs | 145 +- Modules/IMGUI/AssemblyInfo.cs | 5 + Modules/IMGUI/Event.cs | 4 +- Modules/IMGUI/GUIStyle.cs | 2 +- Modules/IMGUI/TextEditor.cs | 10 +- .../Editor/InAppPurchasingMenuItem.cs | 15 + Modules/InputForUI/AssemblyInfo.cs | 8 +- Modules/InsightsEditor/AssemblyInfo.cs | 7 + ...ildProfileInsightsSettingsVisualElement.cs | 54 +- Modules/InsightsEditor/DisablementPopup.cs | 2 +- .../EngineDiagnosticsSettings.bindings.cs | 2 + Modules/LevelPlay/Editor/LevelPlayMenuItem.cs | 18 + .../Marshalling/MarshallingTests.bindings.cs | 85 +- .../AnalyticsOnPlayFromScenarioEvent.cs | 10 + .../EditorInstanceDescription.cs | 0 .../PlayModeConfig/InstanceDescription.cs | 0 .../LocalInstanceDescription.cs | 7 +- .../MainEditorInstanceDescription.cs | 0 .../PlayModeConfig/ScenarioConfig.cs | 73 +- .../PlayModeConfig/ScenarioFactory.cs | 12 +- .../PlayModeConfig/ServerCliSettings.cs | 58 + .../PlayModeConfig/ServerCliSettingsDrawer.cs | 92 + .../UI/InstanceDescriptorDrawer.cs | 8 + .../UI/LocalInstanceDescriptionDrawer.cs | 17 +- .../FreeRunningStatusElement.cs | 5 + .../PlaymodeStatusElement.cs | 64 +- .../PlaymodeStatusPopupContent.cs | 52 +- .../Scenarios/GraphsFoundation/Instance.cs | 180 +- .../Scenarios/GraphsFoundation/Scenario.cs | 36 + .../Instances/LocalInstanceController.cs | 83 +- .../Instances/RemoteInstanceController.cs | 29 +- .../Scenarios/Nodes/Local/LocalRunNode.cs | 18 +- .../Nodes/Multiplay/DeployFleetNode.cs | 10 +- .../LocalDeploymentUtility.cs | 10 +- .../Nodes/Multiplay/ServerSettings.cs | 1 + .../Nodes/Multiplay/ServerSettingsDrawer.cs | 8 + .../Nodes/Multiplay/SimulatorSettings.cs | 6 +- .../Scenarios/PlayModeController.cs | 8 + .../Scenarios/ScenarioRunner.cs | 32 +- .../Workflow/Players/SystemDataStore.cs | 4 +- .../Editor/Managed/PackageValidation.cs | 78 - .../Extensions/ExtendableToolbarMenu.cs | 8 +- .../Editor/Services/Common/DropdownHandler.cs | 121 ++ .../Editor/Services/Common/HeaderColor.cs | 11 + .../Services/Common/PackageSanitizer.cs | 27 - .../Services/Common/PackageValidator.cs | 74 + .../Services/Packages/Actions/AddAction.cs | 4 +- .../Packages/Actions/OpenManifestAction.cs | 29 +- .../Services/Packages/Actions/ResetAction.cs | 33 +- .../Packages/CustomizedDependencyType.cs | 17 + .../Packages/InProjectPackagesMonitor.cs | 3 +- .../Services/Packages/PackageCreator.cs | 8 +- .../Services/Packages/PackageDatabase.cs | 14 +- .../Packages/PackageOperationDispatcher.cs | 36 +- .../Editor/Services/Packages/PackageSample.cs | 8 +- .../Editor/Services/ServicesContainer.cs | 6 +- .../Editor/Services/Upm/UpmCache.cs | 7 - .../Editor/UI/AddPackageByNameDropdown.cs | 55 +- .../Editor/UI/Common/ManageDropdownButton.cs | 10 +- .../Editor/UI/Common/SelectableLabel.cs | 18 - .../Editor/UI/Common/Tabs/BaseTabView.cs | 4 + .../Editor/UI/Common/TextFieldPlaceholder.cs | 39 - .../Editor/UI/CreatePackageDropdown.cs | 39 +- .../CustomDisplayDialog/CustomDialogArgs.cs | 2 + .../CustomDisplayDialogContent.cs | 3 +- .../Editor/UI/DropdownContainer.cs | 44 - .../Editor/UI/DropdownContent.cs | 18 +- .../Editor/UI/DropdownElement.cs | 44 - .../Editor/UI/GenericInputDropdown.cs | 64 +- .../Editor/UI/InProgressDropdown.cs | 6 +- .../Editor/UI/PackageDetailsHeader.cs | 6 +- .../PackageDetailsDependenciesTab.cs | 2 +- .../PackageDetailsDescriptionTab.cs | 8 +- .../PackageDetailsFeatureDependenciesTab.cs | 6 +- .../PackageDetailsOverviewTabContent.cs | 8 +- .../PackageDetailsSampleItem.cs | 3 +- .../PackageManagerUI/Editor/UI/PackageItem.cs | 2 +- .../Editor/UI/PackageManagerToolbar.cs | 20 +- .../Editor/UI/PackageManagerWindow.cs | 45 +- .../Editor/UI/PackageManagerWindowRoot.cs | 30 +- .../UI/PackageManifestImporterEditor.cs | 16 +- .../Editor/UI/PackageSampleItemLowWidth.cs | 4 +- .../Editor/UI/PackageSelectionEditor.cs | 261 +-- .../Editor/UI/ScopedRegistriesSettings.cs | 27 +- .../Editor/UI/ToolBar/PackageToolBar.cs | 6 +- .../ParticleSystemEditor/ParticleEffectUI.cs | 8 +- Modules/Physics/Managed/Collision.cs | 18 +- .../Physics/ScriptBindings/Joint.bindings.cs | 9 +- .../ScriptBindings/Physics.bindings.cs | 3 + .../ScriptBindings/Physics.deprecated.cs | 8 - .../ScriptBindings/PhysicsContact.bindings.cs | 34 +- .../Scripting/Joints/PhysicsHingeJoint.cs | 2 +- .../Joints/PhysicsHingeJointDefinition.cs | 2 +- .../LowLevel/Scripting/Joints/PhysicsJoint.cs | 1 - .../Scripting/Joints/PhysicsRelativeJoint.cs | 5 +- .../Scripting/Joints/PhysicsWheelJoint.cs | 2 +- .../Joints/PhysicsWheelJointDefinition.cs | 2 +- .../Scripting/Miscellaneous/PhysicsMask.cs | 6 +- .../LowLevel/Scripting/PhysicsBody.cs | 2 +- .../Scripting/PhysicsBodyDefinition.cs | 2 +- .../LowLevel/Scripting/PhysicsGeometry.cs | 35 +- .../LowLevel/Scripting/PhysicsQuery.cs | 8 +- .../LowLevel/Scripting/PhysicsShape.cs | 3 +- .../ContactFilterPropertyDrawer.cs | 2 +- .../BackendSystem/PhysicsBackendStripping.cs | 2 +- Modules/PhysicsEditor/PhysicsDebugWindow.cs | 3 +- .../PhysicsDebugWindowContactsTab.cs | 10 +- .../PhysicsEditor/PhysicsManagerInspector.cs | 26 +- .../Managed/Configurations/PlayModeManager.cs | 42 +- .../Configurations/PlayModeUserSettings.cs | 41 + .../Managed/Configurations/StateMachine.cs | 5 +- .../ConfigurationsWindow/PlayModeListView.cs | 4 + .../UI/Toolbar/PlayModeButtonsExtension.cs | 3 + .../Captures/CaptureDataService.cs | 70 +- .../CaptureFileTreeItemViewController.cs | 11 +- .../ProfilerDetailedObjectsView.cs | 10 +- .../ProfilerFrameDataTreeView.cs | 12 +- .../ProfilerFrameHierarchyView.cs | 6 +- .../Public/FrameDataView.bindings.cs | 6 +- .../Public/HierarchyFrameDataView.bindings.cs | 19 +- .../ProfilerFrameDataIterator.bindings.cs | 8 +- .../ProfilerEditor/Public/ProfilerSettings.cs | 6 +- .../Editor/Indexing/SearchDatabase.cs | 36 + .../Editor/Indexing/SearchDatabaseImporter.cs | 2 +- .../Editor/Indexing/SearchIndexer.cs | 3 +- .../Editor/Providers/AssetProvider.cs | 4 +- .../Editor/Providers/ObjectQueryEngine.cs | 8 +- .../QueryBuilder/Blocks/QueryFilterBlock.cs | 17 +- .../QueryBuilder/Blocks/QueryListBlock.cs | 6 +- .../Editor/QueryBuilder/QueryBlock.cs | 2 +- Modules/QuickSearch/Editor/SearchInit.cs | 2 +- Modules/QuickSearch/Editor/SearchSettings.cs | 20 +- Modules/QuickSearch/Editor/SearchUtils.cs | 14 + Modules/QuickSearch/Editor/UI/ObjectField.cs | 10 +- .../QuickSearch/Editor/UITK/SearchField.cs | 12 +- Modules/QuickSearch/Editor/Utilities/Utils.cs | 5 +- .../ScriptBindings/RenderAs2D.bindings.cs | 1 + .../ShortcutManagerWindowViewController.cs | 35 +- .../ShortcutProfileStore.cs | 20 +- .../Managed/NativeTextInfo.cs | 2 +- .../Managed/TextAssets/FontAsset.cs | 9 +- .../Managed/TextAssets/FontAssetUtilities.cs | 11 + .../Managed}/TextEditingUtilities.cs | 31 +- .../TextGenerator/RichTextTagParser.cs | 66 +- .../TextGenerator/TextGeneratorParsing.cs | 8 +- .../TextGeneratorPreferredValues.cs | 8 +- .../TextGenerator/TextGeneratorPrepare.cs | 18 +- .../TextCoreTextEngine/Managed/TextHandle.cs | 37 +- .../Managed/TextHandlePermanentCache.cs | 1 - .../Managed}/TextSelectingUtilities.cs | 22 +- .../Builder/Inspector/BuilderInspector.cs | 45 +- .../Inspector/BuilderInspectorStyleFields.cs | 7 + .../Editor/Builder/Toolbar/BuilderToolbar.cs | 3 - .../Utilities/BuilderAssetUtilities.cs | 2 - .../Builder/Utilities/BuilderConstants.cs | 2 +- .../PersistedFoldout/PersistedFoldout.cs | 3 +- .../StyleField/TextAutoSizeStyleField.cs | 2 + Modules/UIElements/AssemblyInfo.cs | 5 + .../UIElements/Core/Bindings/DataBinding.cs | 7 +- .../DynamicHeightVirtualizationController.cs | 9 +- .../FixedHeightVirtualizationController.cs | 6 + .../VerticalVirtualizationController.cs | 37 +- .../UIElements/Core/Controls/BaseBoolField.cs | 1 + Modules/UIElements/Core/Controls/Foldout.cs | 2 +- .../InputField/TouchScreenTextEditor.cs | 4 +- .../UIElements/Core/Controls/ScrollView.cs | 55 +- .../UIElements/Core/GameObjects/UIDocument.cs | 7 +- .../Core/ILiveReloadAssetTracker.cs | 1 + Modules/UIElements/Core/ILiveReloadSystem.cs | 5 + .../Core/Style/Generated/ComputedStyle.cs | 17 +- .../Core/Style/Generated/InitialStyle.cs | 4 +- .../Core/Style/Generated/StyleDataStructs.cs | 6 +- .../Core/Style/Generated/StyleDebug.cs | 4 +- .../Style/Generated/StylePropertyEnums.cs | 16 +- .../Core/Style/Generated/StylePropertyUtil.cs | 2 +- .../Core/Style/InlineStyleAccess.cs | 5 + .../Core/StyleSheets/StyleSheetBuilder.cs | 1 + .../Core/StyleSheets/StyleVariable.cs | 45 +- .../Core/Text/ATGTextEventHandler.cs | 41 +- Modules/UIElements/Core/Text/ATGTextHandle.cs | 7 +- .../UIElements/Core/Text/ATGTextJobSystem.cs | 140 +- .../Core/Text/TextSelectingManipulator.cs | 6 +- .../UIElements/Core/Text/UITKTextHandle.cs | 23 +- Modules/UIElements/Core/TextElement.cs | 15 +- .../UIElements/Core/TextElementSelection.cs | 3 + .../Core/UIElementsInitialization.cs | 6 - Modules/UIElements/Core/UIElementsUtility.cs | 35 +- Modules/UIElements/Core/VectorImage.cs | 5 +- Modules/UIElements/Core/VisualElement.cs | 11 +- .../UIElements/Core/VisualElementHierarchy.cs | 4 +- .../UIElementsEditor/Debugger/BoxModelView.cs | 72 +- .../LayoutDebugger/LayoutPanelDebuggerImpl.cs | 108 +- .../Debugger/PanelDebugger.cs | 6 +- .../Debugger/StylesDebugger.cs | 513 +++--- .../Debugger/UIElementsDebugger.cs | 56 +- Modules/UIElementsEditor/EditorDragAndDrop.cs | 2 +- .../Inspector/PanelSettingsInspector.cs | 32 +- .../Inspector/UIDocumentInspector.cs | 4 +- Modules/UIElementsEditor/RetainedMode.cs | 22 +- .../UIElementsViewImporter.cs | 30 +- .../VisualTreeAssetChangeTrackerUpdater.cs | 54 +- .../DefaultEditorWindowBackend.cs | 4 + .../VisualElementHierarchyHandlerColumns.cs | 4 +- .../Hierarchy/VisualElementNodeTypeHandler.cs | 262 ++- Modules/VR/ScriptBindings/XR.bindings.cs | 6 +- Modules/VectorGraphics/Runtime/VectorScene.cs | 53 +- Projects/CSharp/UnityEditor.csproj | 63 +- Projects/CSharp/UnityEngine.csproj | 50 +- README.md | 2 +- .../Application/Application.bindings.cs | 1 + Runtime/Export/AssemblyInfo.cs | 16 + Runtime/Export/Debug/Debug.bindings.cs | 2 +- .../Graphics/GraphicsRenderers.bindings.cs | 4 + .../Graphics/GraphicsSettings.bindings.cs | 2 - Runtime/Export/Input/CopyBuffer.binding.cs | 21 + .../Export/ObjectPool}/RentMemory.cs | 6 +- .../Export/ObjectPool}/RentMemoryUnmanaged.cs | 6 +- .../Export/ObjectPool}/RentSpan.cs | 6 +- .../Export/ObjectPool}/RentSpanUnmanaged.cs | 6 +- .../RenderPipeline/RenderPipelineAsset.cs | 2 - Runtime/Export/Scripting/LazyLoadReference.cs | 51 +- .../TouchScreenKeyboard.bindings.cs | 1 + .../ScriptBindings/RectTransform.bindings.cs | 1 + .../TransformAccessArray.bindings.cs | 43 + .../BeeDriver2/Bee.BeeDriver2.dll | Bin 120320 -> 120320 bytes .../Distribution/BeeDriver2/Bee.BinLog.dll | Bin 18944 -> 18944 bytes .../BeeTinyProfiler2/Bee.TinyProfiler2.dll | Bin 20480 -> 20480 bytes third-party-notices.txt | 2 +- 335 files changed, 6854 insertions(+), 4508 deletions(-) create mode 100644 Editor/Mono/BuildPipeline/BuildCallbackContext.bindings.cs create mode 100644 Editor/Mono/EditorDeeplink.cs create mode 100644 External/CoreCLR/SourceCopiesToRemove/DynamicDependencyAttribute.cs create mode 100644 Modules/Accessibility/Bindings/AccessibilityNodeDataTests.bindings.cs create mode 100644 Modules/Hierarchy/Managed/IHierarchyEditorNodeTypeHandler.cs create mode 100644 Modules/InsightsEditor/AssemblyInfo.cs rename Modules/MultiplayerEditor/Managed/MultiplayerPlayMode/{Scenarios => }/PlayModeConfig/EditorInstanceDescription.cs (100%) rename Modules/MultiplayerEditor/Managed/MultiplayerPlayMode/{Scenarios => }/PlayModeConfig/InstanceDescription.cs (100%) rename Modules/MultiplayerEditor/Managed/MultiplayerPlayMode/{Scenarios => }/PlayModeConfig/MainEditorInstanceDescription.cs (100%) create mode 100644 Modules/MultiplayerEditor/Managed/MultiplayerPlayMode/PlayModeConfig/ServerCliSettings.cs create mode 100644 Modules/MultiplayerEditor/Managed/MultiplayerPlayMode/PlayModeConfig/ServerCliSettingsDrawer.cs delete mode 100644 Modules/PackageManager/Editor/Managed/PackageValidation.cs create mode 100644 Modules/PackageManagerUI/Editor/Services/Common/DropdownHandler.cs create mode 100644 Modules/PackageManagerUI/Editor/Services/Common/HeaderColor.cs delete mode 100644 Modules/PackageManagerUI/Editor/Services/Common/PackageSanitizer.cs create mode 100644 Modules/PackageManagerUI/Editor/Services/Common/PackageValidator.cs create mode 100644 Modules/PackageManagerUI/Editor/Services/Packages/CustomizedDependencyType.cs delete mode 100644 Modules/PackageManagerUI/Editor/UI/Common/TextFieldPlaceholder.cs delete mode 100644 Modules/PackageManagerUI/Editor/UI/DropdownContainer.cs delete mode 100644 Modules/PackageManagerUI/Editor/UI/DropdownElement.cs create mode 100644 Modules/PlayModeEditor/Managed/Configurations/PlayModeUserSettings.cs rename Modules/{IMGUI => TextCoreTextEngine/Managed}/TextEditingUtilities.cs (96%) rename Modules/{IMGUI => TextCoreTextEngine/Managed}/TextSelectingUtilities.cs (98%) create mode 100644 Runtime/Export/Input/CopyBuffer.binding.cs rename {Modules/HierarchyCore/Managed => Runtime/Export/ObjectPool}/RentMemory.cs (85%) rename {Modules/HierarchyCore/Managed => Runtime/Export/ObjectPool}/RentMemoryUnmanaged.cs (84%) rename {Modules/HierarchyCore/Managed => Runtime/Export/ObjectPool}/RentSpan.cs (86%) rename {Modules/HierarchyCore/Managed => Runtime/Export/ObjectPool}/RentSpanUnmanaged.cs (86%) diff --git a/Editor/Mono/Animation/AnimationMode.bindings.cs b/Editor/Mono/Animation/AnimationMode.bindings.cs index 5ef3cafb54..c8a093c403 100644 --- a/Editor/Mono/Animation/AnimationMode.bindings.cs +++ b/Editor/Mono/Animation/AnimationMode.bindings.cs @@ -41,6 +41,8 @@ public class AnimationMode static internal event Action onAnimationRecordingStop; static internal event Action onAnimationPlaybackStart; static internal event Action onAnimationPlaybackStop; + static internal event Action onAnimationSampleEnd; + static internal event Action onAnimationModeStop; static private PrefColor s_AnimatedPropertyColor = new PrefColor("Animation/Property Animated", 0.82f, 0.97f, 1.00f, 1.00f, 0.54f, 0.85f, 1.00f, 1.00f); static private PrefColor s_RecordedPropertyColor = new PrefColor("Animation/Property Recorded", 1.00f, 0.60f, 0.60f, 1.00f, 1.00f, 0.50f, 0.50f, 1.00f); @@ -71,12 +73,16 @@ static private AnimationModeDriver DummyDriver() public static void StopAnimationMode() { Internal_StopAnimationMode(DummyDriver()); + + onAnimationModeStop?.Invoke(); } // Stops animation mode, as used by the animation editor. public static void StopAnimationMode(AnimationModeDriver driver) { Internal_StopAnimationMode(driver); + + onAnimationModeStop?.Invoke(); } // Returns true if the editor is currently in animation mode. @@ -148,6 +154,18 @@ internal static void StartCandidateRecording(AnimationModeDriver driver) Internal_StartCandidateRecording(driver); } + public static void BeginSampling() + { + Internal_BeginSampling(); + } + + public static void EndSampling() + { + Internal_EndSampling(); + + onAnimationSampleEnd?.Invoke(); + } + [NativeThrows] extern internal static void AddCandidate(EditorCurveBinding binding, PropertyModification modification, bool keepPrefabOverride); @@ -158,12 +176,6 @@ internal static void StartCandidateRecording(AnimationModeDriver driver) extern internal static bool IsRecordingCandidates(); - [NativeThrows] - extern public static void BeginSampling(); - - [NativeThrows] - extern public static void EndSampling(); - [NativeThrows] extern public static void SampleAnimationClip([NotNull] GameObject gameObject, [NotNull] AnimationClip clip, float time); @@ -206,6 +218,12 @@ internal static void StartCandidateRecording(AnimationModeDriver driver) // Return editor curve bindings for animator hierarhcy that need to be snapshot for animation mode. extern internal static EditorCurveBinding[] GetAnimatorBindings([NotNull] GameObject root); + [NativeThrows] + extern private static void Internal_BeginSampling(); + + [NativeThrows] + extern private static void Internal_EndSampling(); + extern private static void Internal_StartAnimationMode(Object driver); extern private static void Internal_StopAnimationMode(Object driver); diff --git a/Editor/Mono/Animation/AnimationWindow/AnimEditor.cs b/Editor/Mono/Animation/AnimationWindow/AnimEditor.cs index b808d78f2b..b00d59abbe 100644 --- a/Editor/Mono/Animation/AnimationWindow/AnimEditor.cs +++ b/Editor/Mono/Animation/AnimationWindow/AnimEditor.cs @@ -167,8 +167,8 @@ public void OnAnimEditorGUI(EditorWindow parent, Rect position) GUILayout.BeginVertical(); // First row of controls - GUILayout.BeginHorizontal(AnimationWindowStyles.animPlayToolBar); - PlayControlsOnGUI(); + Rect playControlsRect = EditorGUILayout.BeginHorizontal(AnimationWindowStyles.animPlayToolBar); + PlayControlsOnGUI(playControlsRect); GUILayout.EndHorizontal(); // Second row of controls @@ -777,8 +777,14 @@ private void AddKeyframeButtonOnGUI() } } - private void PlayControlsOnGUI() + private void PlayControlsOnGUI(Rect playControlsRect) { + // Remove keyfocus when clicking within control to ensure play control shortcuts are received (UUM-113412) + if (Event.current.type == EventType.MouseDown && playControlsRect.Contains(Event.current.mousePosition)) + { + GUIUtility.keyboardControl = 0; + } + using (new EditorGUI.DisabledScope(!m_State.canPreview)) { PreviewButtonOnGUI(); diff --git a/Editor/Mono/AnimatorController.bindings.cs b/Editor/Mono/AnimatorController.bindings.cs index 89521ecc2e..4033521a30 100644 --- a/Editor/Mono/AnimatorController.bindings.cs +++ b/Editor/Mono/AnimatorController.bindings.cs @@ -82,8 +82,11 @@ static public StateMachineBehaviourContext[] FindStateMachineBehaviourContext(St [FreeFunction("FindStateMachineBehaviourContext")] extern internal static StateMachineBehaviourContext[] Internal_FindStateMachineBehaviourContext(ScriptableObject behaviour); - [FreeFunction("AnimatorControllerBindings::Internal_CreateStateMachineBehaviour")] - extern public static int CreateStateMachineBehaviour(MonoScript script); + [FreeFunction("AnimatorControllerBindings::Internal_CreateNewStateMachineBehaviour")] + extern public static EntityId CreateNewStateMachineBehaviour(MonoScript script); + + [Obsolete("CreateStateMachineBehaviour is deprecated. Use CreateNewStateMachineBehaviour instead.", false)] + public static int CreateStateMachineBehaviour(MonoScript script) => (int)CreateNewStateMachineBehaviour(script); [FreeFunction("AnimatorControllerBindings::CanAddStateMachineBehaviours")] extern internal static bool CanAddStateMachineBehaviours(); @@ -130,7 +133,7 @@ internal extern bool isAssetBundled get; } - extern internal void AddStateEffectiveBehaviour([NotNull] AnimatorState state, int layerIndex, int instanceID); + extern internal void AddStateEffectiveBehaviour([NotNull] AnimatorState state, int layerIndex, EntityId entityId); extern internal void RemoveStateEffectiveBehaviour([NotNull] AnimatorState state, int layerIndex, int behaviourIndex); [FreeFunction(Name = "AnimatorControllerBindings::Internal_GetEffectiveBehaviours", HasExplicitThis = true)] diff --git a/Editor/Mono/AssemblyInfo/AssemblyInfo.cs b/Editor/Mono/AssemblyInfo/AssemblyInfo.cs index 280da3f857..26fc07fab6 100644 --- a/Editor/Mono/AssemblyInfo/AssemblyInfo.cs +++ b/Editor/Mono/AssemblyInfo/AssemblyInfo.cs @@ -36,9 +36,11 @@ [assembly: InternalsVisibleTo("Unity.IntegrationTests.AssetImporting")] [assembly: InternalsVisibleTo("Unity.IntegrationTests.BuildPipeline")] [assembly: InternalsVisibleTo("Unity.IntegrationTests.Builds")] +[assembly: InternalsVisibleTo("Unity.IntegrationTests.Insights")] [assembly: InternalsVisibleTo("Unity.IntegrationTests.CrashReporting")] [assembly: InternalsVisibleTo("Unity.IntegrationTests.DeploymentTargets")] [assembly: InternalsVisibleTo("Unity.IntegrationTests.EditorApplication")] +[assembly: InternalsVisibleTo("Unity.IntegrationTests.EditorDeeplink")] [assembly: InternalsVisibleTo("Unity.IntegrationTests.EditorUI")] [assembly: InternalsVisibleTo("Unity.IntegrationTests.GameCore")] [assembly: InternalsVisibleTo("Unity.IntegrationTests.GameView")] @@ -75,6 +77,7 @@ [assembly: InternalsVisibleTo("UnityEditor.PS4.Extensions")] [assembly: InternalsVisibleTo("UnityEditor.PS5.Extensions")] [assembly: InternalsVisibleTo("UnityEditor.Switch.Extensions")] +[assembly: InternalsVisibleTo("UnityEditor.Switch2.Extensions")] [assembly: InternalsVisibleTo("UnityEditor.WebGL.Extensions")] [assembly: InternalsVisibleTo("Unity.Automation.Players.WebGL")] [assembly: InternalsVisibleTo("Unity.WebGL.Extensions")] @@ -95,7 +98,6 @@ [assembly: InternalsVisibleTo("UnityEditor.Analytics")] [assembly: InternalsVisibleTo("UnityEditor.Purchasing")] [assembly: InternalsVisibleTo("UnityEditor.Lumin")] -[assembly: InternalsVisibleTo("UnityEditor.Switch.Extensions")] [assembly: InternalsVisibleTo("UnityEditor.EditorTestsRunner")] [assembly: InternalsVisibleTo("UnityEditor.TestRunner")] [assembly: InternalsVisibleTo("UnityEditor.TestRunner.Tests")] @@ -103,6 +105,7 @@ [assembly: InternalsVisibleTo("ExternalCSharpCompiler")] [assembly: InternalsVisibleTo("UnityEngine.TestRunner")] [assembly: InternalsVisibleTo("Unity.Modules.AssetDatabase.ImportActivityWindow.Tests")] +[assembly: InternalsVisibleTo("Unity.Modules.AssetDatabase.UnityPackage.Tests.Editor")] [assembly: InternalsVisibleTo("UnityEditor.VR")] [assembly: InternalsVisibleTo("Unity.RuntimeTests")] [assembly: InternalsVisibleTo("Unity.RuntimeTests.Framework")] @@ -112,6 +115,8 @@ [assembly: InternalsVisibleTo("Unity.Module.AssetDatabase.DanglingComponents.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.Modules.CoreEditor.ComponentUtility.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.Modules.CoreEditor.DragAndDrop.Tests.Editor")] +[assembly: InternalsVisibleTo("Unity.Modules.CoreEditor.NestedPrefabsFrontEnd.Tests.Editor")] +[assembly: InternalsVisibleTo("Unity.Modules.CoreEditor.NestedPrefabsFrontEnd.Tests.Common")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] [assembly: InternalsVisibleTo("UnityEditor.InteractiveTutorialsFramework")] [assembly: InternalsVisibleTo("UnityEditor.Networking")] @@ -194,6 +199,7 @@ [assembly: InternalsVisibleTo("UnityEditor.Switch.Tests")] +[assembly: InternalsVisibleTo("UnityEditor.Switch2.Tests")] [assembly: InternalsVisibleTo("UnityEditor.BuildProfileModule.Tests")] //For add Component tests @@ -218,6 +224,7 @@ [assembly: InternalsVisibleTo("Unity.Modules.Licensing.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.Modules.PlatformIcons.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.Modules.BuildProfileEditor.Tests.Editor")] +[assembly: InternalsVisibleTo("Unity.Modules.UI.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.Modules.Multiplayer.Server.Tests.Editor")] // This should move with the AnimationWindow to a module at some point [assembly: InternalsVisibleTo("Unity.Modules.Animation.AnimationWindow.Tests.Editor")] @@ -225,6 +232,7 @@ [assembly: InternalsVisibleTo("Unity.Modules.GI.EditorBake.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.Modules.Physics2D.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.Modules.U2D.NineSlice.Tests.Editor")] +[assembly: InternalsVisibleTo("Unity.Modules.GI.Prefabs.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.Tests.Shared")] @@ -238,6 +246,8 @@ [assembly: InternalsVisibleTo("Unity.Core.EditorWindowManagement.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.Core.InspectorFramework.Tests.Editor")] +[assembly: InternalsVisibleTo("Unity.Modules.Core.Undo.Tests.Editor")] +[assembly: InternalsVisibleTo("Unity.Modules.Core.UnityType.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.Core.VersionControl.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.ProjectAuditor.EditorTests")] [assembly: InternalsVisibleTo("Unity.Modules.GI.Analytics.Tests.Editor")] diff --git a/Editor/Mono/BuildPipeline/BuildCallbackContext.bindings.cs b/Editor/Mono/BuildPipeline/BuildCallbackContext.bindings.cs new file mode 100644 index 0000000000..8ad42862a9 --- /dev/null +++ b/Editor/Mono/BuildPipeline/BuildCallbackContext.bindings.cs @@ -0,0 +1,81 @@ +// 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 UnityEngine; +using UnityEngine.Bindings; +using UnityEditor.Build.Reporting; +using UnityEngine.Scripting; +using System.Runtime.InteropServices; + +namespace UnityEditor.Build +{ + [RequiredByNativeCode] + [NativeType(Header = "Modules/ContentBuild/Editor/Public/BuildCallbackContext.h")] + [NativeClass("BuildPipeline::BuildCallbackContext")] + public class BuildCallbackContext + { + // The bindings generator is setting the instance pointer in this field + internal IntPtr m_Self; + + internal static class BindingsMarshaller // IS THIS NEEDED ?? + { + public static IntPtr ConvertToNative(BuildCallbackContext ctx) => ctx?.m_Self ?? IntPtr.Zero; + + public static BuildCallbackContext ConvertToManaged(IntPtr ptr) => + ptr != IntPtr.Zero ? new BuildCallbackContext(ptr) : null; + } + + // Constructor used for wrapping native instances + private BuildCallbackContext(IntPtr nativePtr) + { + m_Self = nativePtr; + } + + [FreeFunction("BuildCallbackContextBindings::GetReport")] + private static extern BuildReport GetReportInternal(IntPtr self); + + public BuildReport Report + { + get + { + if (m_Self != IntPtr.Zero) + { + return GetReportInternal(m_Self); + } + return null; + } + } + + [FreeFunction("BuildCallbackContextBindings::IsPlayerBuild")] + private static extern bool IsPlayerBuildInternal(IntPtr self); + + public bool IsPlayerBuild + { + get + { + if (m_Self != IntPtr.Zero) + { + return IsPlayerBuildInternal(m_Self); + } + return false; + } + } + + [FreeFunction("BuildCallbackContextBindings::IsContentOnlyBuild")] + private static extern bool IsContentOnlyBuildInternal(IntPtr self); + + public bool IsContentOnlyBuild + { + get + { + if (m_Self != IntPtr.Zero) + { + return IsContentOnlyBuildInternal(m_Self); + } + return false; + } + } + } +} diff --git a/Editor/Mono/BuildPipeline/BuildPipelineInterfaces.cs b/Editor/Mono/BuildPipeline/BuildPipelineInterfaces.cs index 1dc65562f5..3c05495475 100644 --- a/Editor/Mono/BuildPipeline/BuildPipelineInterfaces.cs +++ b/Editor/Mono/BuildPipeline/BuildPipelineInterfaces.cs @@ -38,6 +38,10 @@ public interface IPreprocessBuildWithReport : IOrderedCallback { void OnPreprocessBuild(BuildReport report); } + public interface IPreprocessBuildWithContext : IOrderedCallback + { + void OnPreprocessBuild(BuildCallbackContext ctx); + } public interface IFilterBuildAssemblies : IOrderedCallback { @@ -54,6 +58,10 @@ public interface IPostprocessBuildWithReport : IOrderedCallback { void OnPostprocessBuild(BuildReport report); } + public interface IPostprocessBuildWithContext : IOrderedCallback + { + void OnPostprocessBuild(BuildCallbackContext ctx); + } public interface IPostBuildPlayerScriptDLLs : IOrderedCallback { @@ -162,6 +170,8 @@ internal class Processors public List buildPreprocessorsWithReport; public List buildPostprocessorsWithReport; + public List buildPreprocessorsWithContext; + public List buildPostprocessorsWithContext; public List launchPostprocessors; public List sceneProcessorsWithReport; @@ -297,8 +307,10 @@ internal static void InitializeBuildCallbacks(BuildCallbacks findFlags) AddToListIfTypeImplementsInterface(t, ref instance, ref processors.buildPlayerProcessors); AddToListIfTypeImplementsInterface(t, ref instance, ref processors.buildPreprocessors); AddToListIfTypeImplementsInterface(t, ref instance, ref processors.buildPreprocessorsWithReport); + AddToListIfTypeImplementsInterface(t, ref instance, ref processors.buildPreprocessorsWithContext); AddToListIfTypeImplementsInterface(t, ref instance, ref processors.buildPostprocessors); AddToListIfTypeImplementsInterface(t, ref instance, ref processors.buildPostprocessorsWithReport); + AddToListIfTypeImplementsInterface(t, ref instance, ref processors.buildPostprocessorsWithContext); } if (findSceneProcessors) @@ -362,10 +374,14 @@ internal static void InitializeBuildCallbacks(BuildCallbacks findFlags) processors.buildPreprocessors.Sort(CompareICallbackOrder); if (processors.buildPreprocessorsWithReport != null) processors.buildPreprocessorsWithReport.Sort(CompareICallbackOrder); + if (processors.buildPreprocessorsWithContext != null) + processors.buildPreprocessorsWithContext.Sort(CompareICallbackOrder); if (processors.buildPostprocessors != null) processors.buildPostprocessors.Sort(CompareICallbackOrder); if (processors.buildPostprocessorsWithReport != null) processors.buildPostprocessorsWithReport.Sort(CompareICallbackOrder); + if (processors.buildPostprocessorsWithContext != null) + processors.buildPostprocessorsWithContext.Sort(CompareICallbackOrder); if (processors.buildTargetProcessors != null) processors.buildTargetProcessors.Sort(CompareICallbackOrder); if (processors.sceneProcessors != null) @@ -524,6 +540,27 @@ internal static void OnBuildPreProcess(BuildReport report) profile.SerializePlayerSettings(); } + [RequiredByNativeCode] + internal static void OnBuildPreProcessWithContext(BuildCallbackContext context) + { + if (processors.buildPreprocessorsWithContext != null) + { + foreach (var processor in processors.buildPreprocessorsWithContext) + { + try + { + processor.OnPreprocessBuild(context); + } + catch (Exception e) + { + Debug.LogException(e); + if (context.Report != null && ((context.Report.summary.options & BuildOptions.StrictMode) != 0 || (context.Report.summary.assetBundleOptions & BuildAssetBundleOptions.StrictMode) != 0)) + return; + } + } + } + } + [RequiredByNativeCode] internal static void OnSceneProcess(UnityEngine.SceneManagement.Scene scene, BuildReport report) { @@ -588,6 +625,27 @@ internal static void OnBuildPostProcess(BuildReport report) #pragma warning restore 618 } + [RequiredByNativeCode] + internal static void OnBuildPostProcessWithContext(BuildCallbackContext context) + { + if (processors.buildPostprocessorsWithContext != null) + { + foreach (var processor in processors.buildPostprocessorsWithContext) + { + try + { + processor.OnPostprocessBuild(context); + } + catch (Exception e) + { + Debug.LogException(e); + if (context.Report != null && ((context.Report.summary.options & BuildOptions.StrictMode) != 0 || (context.Report.summary.assetBundleOptions & BuildAssetBundleOptions.StrictMode) != 0)) + return; + } + } + } + } + // Some platforms like Desktop, instead of launching the app via C#, perform their launch in C++ // See BuildPlayer.cpp LaunchPlayerIfSupported, which calls native LaunchApplication @@ -752,7 +810,9 @@ internal static void CleanupBuildCallbacks() processors.buildPostprocessors = null; processors.sceneProcessors = null; processors.buildPreprocessorsWithReport = null; + processors.buildPreprocessorsWithContext = null; processors.buildPostprocessorsWithReport = null; + processors.buildPostprocessorsWithContext = null; processors.sceneProcessorsWithReport = null; processors.filterBuildAssembliesProcessor = null; processors.unityLinkerProcessors = null; diff --git a/Editor/Mono/BuildPlayerWindowBuildMethods.cs b/Editor/Mono/BuildPlayerWindowBuildMethods.cs index 199130c791..f951bb239b 100644 --- a/Editor/Mono/BuildPlayerWindowBuildMethods.cs +++ b/Editor/Mono/BuildPlayerWindowBuildMethods.cs @@ -396,9 +396,10 @@ private static bool PickBuildLocation(BuildTargetGroup targetGroup, BuildTarget if (!Directory.Exists(check_dir)) Directory.CreateDirectory(check_dir); - // On OSX we've got replace/update dialog, for other platforms warn about deleting - // files in target folder. - if ((target == BuildTarget.iOS) && (Application.platform != RuntimePlatform.OSXEditor)) + // All files are deleted in build path when building iOS/tvOS/visionOS project with replace option on WinEditor or MacEditor, we need to + // ask the user if they want to proceed by showing a warning dialog + bool isApplePlatform = target == BuildTarget.iOS || target == BuildTarget.tvOS || target == BuildTarget.VisionOS; + if (isApplePlatform && !updateExistingBuild) if (!FolderIsEmpty(path) && !UserWantsToDeleteFiles(path)) return false; diff --git a/Editor/Mono/BuildProfile/BuildProfile.cs b/Editor/Mono/BuildProfile/BuildProfile.cs index 5fb0007d86..4a7f4d37b2 100644 --- a/Editor/Mono/BuildProfile/BuildProfile.cs +++ b/Editor/Mono/BuildProfile/BuildProfile.cs @@ -230,23 +230,6 @@ internal string GetLastRunnableBuildPathKey() return BuildProfileModuleUtil.GetLastRunnableBuildKeyFromAssetPath(assetPath, key); } - /// - /// Duplicate the build profile. Note this does not create a new asset. - /// - [VisibleToOtherModules] - internal BuildProfile Duplicate() - { - var duplicatedProfile = Instantiate(this); - - if (graphicsSettings != null) - duplicatedProfile.graphicsSettings = Instantiate(graphicsSettings); - - if (qualitySettings != null) - duplicatedProfile.qualitySettings = Instantiate(qualitySettings); - - return duplicatedProfile; - } - [VisibleToOtherModules] internal void ResetToGlobalQualitySettingsValues() { diff --git a/Editor/Mono/BuildProfile/BuildProfileModuleUtil.cs b/Editor/Mono/BuildProfile/BuildProfileModuleUtil.cs index 728115f2ed..1ed20efae7 100644 --- a/Editor/Mono/BuildProfile/BuildProfileModuleUtil.cs +++ b/Editor/Mono/BuildProfile/BuildProfileModuleUtil.cs @@ -48,6 +48,7 @@ internal class BuildProfileModuleUtil static HashSet s_BuildProfileIconModules = new() { "Switch", + "Switch2", }; /// diff --git a/Editor/Mono/BuildProfile/Internal/AddSettingsDropdownWindow.cs b/Editor/Mono/BuildProfile/Internal/AddSettingsDropdownWindow.cs index 13f5067ae3..7f360562bc 100644 --- a/Editor/Mono/BuildProfile/Internal/AddSettingsDropdownWindow.cs +++ b/Editor/Mono/BuildProfile/Internal/AddSettingsDropdownWindow.cs @@ -20,6 +20,8 @@ namespace UnityEditor.Build.Profile.Internal internal class AddSettingsDropdownWindow : AdvancedDropdownWindow { const string k_ComponentSearchString = "BuildProfileComponentSearchString"; + const int k_WindowMinSize = 325; + const int k_WindowMaxSize = 325; static AdvancedDropdownState s_State = new AdvancedDropdownState(); @@ -44,6 +46,8 @@ public static bool Show( window.gui = new AdvancedDropdownGUI(window.dataSource); window.state = s_State; window.m_OnSelection = onSelection; + window.minSize = new Vector2(rect.width, k_WindowMinSize); + window.maxSize = new Vector2(rect.width, k_WindowMaxSize); window.Init(rect); return window; } diff --git a/Editor/Mono/BuildTargetConverter.cs b/Editor/Mono/BuildTargetConverter.cs index 8f6ae8c3a5..c72ba8fafc 100644 --- a/Editor/Mono/BuildTargetConverter.cs +++ b/Editor/Mono/BuildTargetConverter.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 JetBrains.Annotations; using UnityEngine; @@ -10,51 +11,21 @@ namespace UnityEditor internal static class BuildTargetConverter { [UsedImplicitly] // used by com.unity.test-framework package - public static RuntimePlatform? TryConvertToRuntimePlatform(BuildTarget buildTarget) - { - switch (buildTarget) + public static RuntimePlatform TryConvertToRuntimePlatform(BuildTarget buildTarget) => + buildTarget switch { - case BuildTarget.Android: - return RuntimePlatform.Android; - case BuildTarget.PS4: - return RuntimePlatform.PS4; - case BuildTarget.PS5: - return RuntimePlatform.PS5; - case BuildTarget.StandaloneLinux64: - return RuntimePlatform.LinuxPlayer; - case BuildTarget.LinuxHeadlessSimulation: - return RuntimePlatform.LinuxPlayer; - case BuildTarget.StandaloneOSX: - return RuntimePlatform.OSXPlayer; - case BuildTarget.StandaloneWindows: - return RuntimePlatform.WindowsPlayer; - case BuildTarget.StandaloneWindows64: - return RuntimePlatform.WindowsPlayer; - case BuildTarget.Switch: - return RuntimePlatform.Switch; - case BuildTarget.WSAPlayer: - return RuntimePlatform.WSAPlayerARM; - case BuildTarget.XboxOne: - return RuntimePlatform.XboxOne; - case BuildTarget.iOS: - return RuntimePlatform.IPhonePlayer; - case BuildTarget.tvOS: - return RuntimePlatform.tvOS; - case BuildTarget.VisionOS: - return RuntimePlatform.VisionOS; - case BuildTarget.WebGL: - return RuntimePlatform.WebGLPlayer; - case BuildTarget.GameCoreXboxSeries: - return RuntimePlatform.GameCoreXboxSeries; - case BuildTarget.GameCoreXboxOne: - return RuntimePlatform.GameCoreXboxOne; - case BuildTarget.EmbeddedLinux: - return RuntimePlatform.EmbeddedLinuxArm64; - case BuildTarget.QNX: - return RuntimePlatform.QNXArm64; - default: - return null; - } - } + BuildTarget.StandaloneLinux64 or BuildTarget.LinuxHeadlessSimulation => + RuntimePlatform.LinuxPlayer, + BuildTarget.StandaloneOSX => RuntimePlatform.OSXPlayer, + BuildTarget.StandaloneWindows or BuildTarget.StandaloneWindows64 => + RuntimePlatform.WindowsPlayer, + BuildTarget.WSAPlayer => RuntimePlatform.WSAPlayerARM, + BuildTarget.iOS => RuntimePlatform.IPhonePlayer, + BuildTarget.WebGL => RuntimePlatform.WebGLPlayer, + BuildTarget.EmbeddedLinux => RuntimePlatform.EmbeddedLinuxArm64, + BuildTarget.QNX => RuntimePlatform.QNXArm64, + BuildTarget.GameCoreXboxSeries => RuntimePlatform.GameCoreXboxSeries, + _ => Enum.Parse(buildTarget.ToString()), + }; } } diff --git a/Editor/Mono/BuildTargetDiscovery.bindings.cs b/Editor/Mono/BuildTargetDiscovery.bindings.cs index fb2e524da2..f06d23ce0b 100644 --- a/Editor/Mono/BuildTargetDiscovery.bindings.cs +++ b/Editor/Mono/BuildTargetDiscovery.bindings.cs @@ -565,6 +565,7 @@ public PlatformPackageInfo(string displayName, string qualifiedName, string desc instructions = L10n.Tr("This platform is not available to download from the Unity website, contact the platform holder directly to learn more."), description = L10n.Tr("Benefit from Unity’s support for developing games and applications on this platform"), buildTarget = BuildTarget.Switch2, + iconName = "BuildSettings.Switch2", flags = PlatformAttributes.ExternalDownloadForBuildTarget | PlatformAttributes.IsHidden | PlatformAttributes.IsNDAPlatform | PlatformAttributes.IsWindowsBuildTarget } }, diff --git a/Editor/Mono/ConsoleWindow.cs b/Editor/Mono/ConsoleWindow.cs index 2aad8ecc47..15308c9595 100644 --- a/Editor/Mono/ConsoleWindow.cs +++ b/Editor/Mono/ConsoleWindow.cs @@ -447,6 +447,14 @@ static internal GUIStyle GetStatusStyleForErrorMode(int mode) return Constants.StatusLog; } + void ResetActiveEntry() + { + SetActiveEntry(null); + DestroyLatestRestoreEntry(); + m_ListView.row = -1; + m_ListView.selectedItems = null; + } + void SetActiveEntry(LogEntry entry) { if (entry != null) @@ -531,6 +539,8 @@ internal void OnGUI() { LogEntries.Clear(); GUIUtility.keyboardControl = 0; + //Reset active selection + ResetActiveEntry(); } int currCount = LogEntries.GetCount(); @@ -553,6 +563,9 @@ internal void OnGUI() bool collapsedChanged = (wasCollapsed != HasFlag(ConsoleFlags.Collapse)); if (collapsedChanged) { + //Reset selected elements + ResetActiveEntry(); + // unselect if collapsed flag changed m_ListView.row = -1; @@ -588,7 +601,7 @@ internal void OnGUI() if (EditorGUI.EndChangeCheck()) { SetActiveEntry(null); - m_LastActiveEntryIndex = -1; + DestroyLatestRestoreEntry(); } SetFlag(ConsoleFlags.LogLevelLog, setLogFlag); @@ -700,14 +713,14 @@ internal void OnGUI() textRect.x += offset; if (string.IsNullOrEmpty(m_SearchText)) - errorModeStyle.Draw(textRect, tempContent, id, m_ListView.row == el.row); + errorModeStyle.Draw(textRect, tempContent, id, entryIsSelected); else if (text != null) { //the whole text contains the searchtext, we have to know where it is int startIndex = text.IndexOf(m_SearchText, StringComparison.OrdinalIgnoreCase); if (startIndex == -1 ) // the searchtext is not in the visible text, we don't show the selection - errorModeStyle.Draw(textRect, tempContent, id, m_ListView.row == el.row); + errorModeStyle.Draw(textRect, tempContent, id, entryIsSelected); else // the searchtext is visible, we show the selection { int endIndex = startIndex + m_SearchText.Length; @@ -902,6 +915,10 @@ private void SearchField(Event e) var filteringText = EditorGUI.ToolbarSearchField(rect, searchText, false); if (m_SearchText != filteringText) { + //Reset console selection when entering filter mode + if(String.IsNullOrEmpty(m_SearchText)) + ResetActiveEntry(); + SetFilter(filteringText); } } diff --git a/Editor/Mono/EditorApplication.cs b/Editor/Mono/EditorApplication.cs index 4de236a943..d11b04e8fb 100644 --- a/Editor/Mono/EditorApplication.cs +++ b/Editor/Mono/EditorApplication.cs @@ -569,7 +569,7 @@ static void FireFileMenuNewScene() } } - [RequiredByNativeCode] + [VisibleToOtherModules("UnityEditor.PlayModeModule")] internal static void TogglePlaying() { isPlaying = !isPlaying; diff --git a/Editor/Mono/EditorBuildSettings.bindings.cs b/Editor/Mono/EditorBuildSettings.bindings.cs index 4d9e79bad9..6eb54af07d 100644 --- a/Editor/Mono/EditorBuildSettings.bindings.cs +++ b/Editor/Mono/EditorBuildSettings.bindings.cs @@ -149,6 +149,7 @@ enum ConfigObjectResult FailedTypeMismatch } + [Obsolete("UseParallelAssetBundleBuilding is obsolete and will be removed.")] public static extern bool UseParallelAssetBundleBuilding { get; set; } [NativeMethod("AddConfigObject")] diff --git a/Editor/Mono/EditorDeeplink.cs b/Editor/Mono/EditorDeeplink.cs new file mode 100644 index 0000000000..90b3a7bd94 --- /dev/null +++ b/Editor/Mono/EditorDeeplink.cs @@ -0,0 +1,124 @@ +// 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.Reflection; +using System.Text; +using UnityEditor; +using UnityEditorInternal; +using UnityEngine; +using RequiredByNativeCodeAttribute = UnityEngine.Scripting.RequiredByNativeCodeAttribute; + +namespace UnityEditor +{ + [AttributeUsage(AttributeTargets.Method, Inherited = false)] + public sealed class DeeplinkHandlerAttribute : Attribute + { + public string HandlerNamespace { get; } + public DeeplinkHandlerAttribute(string value) => HandlerNamespace = value.ToLowerInvariant(); + } + + internal static class EditorDeeplink + { + [RequiredByNativeCode] + public static void Internal_OpenDeeplinkInEditor(string openInEditorUrl) + { + if (!IsValidOpenInEditorUrl(openInEditorUrl, out var uri)) + { + Debug.LogWarning(string.Format(L10n.Tr("Invalid URL \"{0}\". Ignoring deeplink operation."), openInEditorUrl)); + return; + } + + if (!TryGetUrlNamespaceTarget(openInEditorUrl, out var urlNamespaceTarget)) + { + Debug.LogWarning(string.Format(L10n.Tr("Invalid URL \"{0}\", missing namespace target. Ignoring deeplink operation."), openInEditorUrl)); + return; + } + + var deeplinkHandler = FindDeeplinkHandler(urlNamespaceTarget); + if (deeplinkHandler == null) + { + Debug.LogWarning(string.Format(L10n.Tr("Missing handler for URL \"{0}\". Ignoring deeplink operation."), openInEditorUrl)); + return; + } + + var handlerReflectedType = deeplinkHandler.ReflectedType; + var handlerReflectedAssembly = handlerReflectedType.Assembly; + UnityEditor.PackageManager.PackageInfo methodPackageInfo = UnityEditor.PackageManager.PackageInfo.FindForAssembly(handlerReflectedAssembly); + // If the assembly of the handler is in a package from the Unity Package Manager registry or in a fully trusted package. + if (methodPackageInfo != null && (methodPackageInfo.registry.isDefault || methodPackageInfo.trustLevel == UnityEditor.PackageManager.TrustLevel.FullTrust)) + { + deeplinkHandler.Invoke(null, new object[] { uri }); + } + else + { + // Otherwise prompt user for manual confirmation + if (InternalEditorUtility.isHumanControllingUs) + { + var dialogText = new StringBuilder(string.Format(L10n.Tr("An URL targeting the \"{0}\" namespace has been received:\n"), urlNamespaceTarget)); + dialogText.AppendLine(openInEditorUrl); + + bool openURL = EditorUtility.DisplayDialog(L10n.Tr("Open URL in Editor"), + dialogText.ToString(), + L10n.Tr("Open"), L10n.Tr("Dismiss")); + + if (openURL) + { + deeplinkHandler.Invoke(null, new object[] { uri }); + } + } + else + { + Debug.LogWarning(string.Format(L10n.Tr("Unvalidated URL \"{0}\" requires manual user confirmation before opening. Ignoring deeplink operation."), openInEditorUrl)); + } + } + } + + static MethodInfo FindDeeplinkHandler(string handlerNamespace) + { + foreach (var methodInfo in EditorAssemblies.GetAllMethodsWithAttribute(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)) + { + if (methodInfo.GetParameters().Length != 1) + { + Debug.LogWarning(string.Format(L10n.Tr("Missing System.Uri parameter in method '{0} {1}'."), methodInfo.DeclaringType.FullName, methodInfo.Name)); + continue; + } + if (methodInfo.GetParameters()[0].ParameterType != typeof(Uri)) + { + Debug.LogWarning(string.Format(L10n.Tr("Wrong parameter type in method '{0} {1}'. Expecting System.Uri parameter."), methodInfo.DeclaringType.FullName, methodInfo.Name)); + continue; + } + var deeplinkHandlerAttribute = methodInfo.GetCustomAttribute(); + if(!deeplinkHandlerAttribute.HandlerNamespace.ToLowerInvariant().Equals(handlerNamespace)) continue; + + var handlerAssemblyQualifiedName = methodInfo.ReflectedType.AssemblyQualifiedName; + // If the handler's assembly qualified name is a parent or a match for the requested namespace + if (handlerAssemblyQualifiedName == null || !handlerAssemblyQualifiedName.ToLowerInvariant() + .StartsWith(deeplinkHandlerAttribute.HandlerNamespace)) continue; + + return methodInfo; + } + return null; + } + + static bool IsValidOpenInEditorUrl(string url, out Uri uri) + { + if (!Uri.TryCreate(url, UriKind.Absolute, out uri)) return false; + return uri.Host.ToLowerInvariant().Equals("editor") && uri.Scheme.ToLowerInvariant().Equals("com.unity.editor"); + } + + // Extract the handler.namespace from openInEditorUrl, which is formatted like this: com.unity.editor://editor/handler.namespace/ + static bool TryGetUrlNamespaceTarget(string url, out string urlNamespaceTarget) + { + urlNamespaceTarget= string.Empty; + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) return false; + if (uri.Segments.Length < 2) return false; + urlNamespaceTarget = uri.Segments[1].ToLowerInvariant(); + if(urlNamespaceTarget.EndsWith("/")) + urlNamespaceTarget = urlNamespaceTarget.Remove(urlNamespaceTarget.Length - 1); + return urlNamespaceTarget.Length > 0; + } + } +} diff --git a/Editor/Mono/EditorGUI.cs b/Editor/Mono/EditorGUI.cs index f654f91585..ca28d536ea 100644 --- a/Editor/Mono/EditorGUI.cs +++ b/Editor/Mono/EditorGUI.cs @@ -229,6 +229,7 @@ static class Styles static EditorGUI() { hyperLinkClicked += EditorGUI_OpenFileOnHyperLinkClicked; + ATGTextEventHandler.onComplexHyperlinkClicked += HandleComplexHyperlinkClicked; } internal static void BeginHandleMixedValueContentColor() @@ -1523,6 +1524,14 @@ private static void EditorGUI_OpenFileOnHyperLinkClicked(EditorWindow window, Un } } + private static void HandleComplexHyperlinkClicked(Dictionary hyperLinkData) + { + if (hyperLinkData != null) + { + hyperLinkClicked(null, new HyperLinkClickedEventArgs(hyperLinkData)); + } + } + // KEYEVENTFIELD HERE =============================================================== internal static Event KeyEventField(Rect position, Event evt) { diff --git a/Editor/Mono/EditorGUIUtility.bindings.cs b/Editor/Mono/EditorGUIUtility.bindings.cs index 05dafcc5dd..ca6e0758e4 100644 --- a/Editor/Mono/EditorGUIUtility.bindings.cs +++ b/Editor/Mono/EditorGUIUtility.bindings.cs @@ -161,7 +161,7 @@ internal static extern void DrawTextureHdrSupport(Rect screenRect, Texture textu private static extern Texture2D FindTextureByName(string name); private static extern Texture2D FindTextureByType([NotNull] Type type); internal static extern string GetObjectNameWithInfo(Object obj); - private static extern string GetTypeNameWithInfo(string typeName, int instanceID); + private static extern string GetTypeNameWithInfo(string typeName, EntityId instanceID); private static extern void Internal_SetupEventValues(object evt); private static extern Vector2 Internal_GetIconSize(); private static extern bool Internal_GetKeyboardRect(int id, out Rect rect); diff --git a/Editor/Mono/GI/BakePipeline.bindings.cs b/Editor/Mono/GI/BakePipeline.bindings.cs index 44afaf8215..864dc46577 100644 --- a/Editor/Mono/GI/BakePipeline.bindings.cs +++ b/Editor/Mono/GI/BakePipeline.bindings.cs @@ -9,6 +9,35 @@ namespace UnityEditor.LightBaking { + [StructLayout(LayoutKind.Sequential)] + internal struct PostProcessProbeRequest + { + public bool dering; + public float indirectScale; + public string outputFolderPath; + }; + + [RequiredByNativeCode] + [StructLayout(LayoutKind.Sequential)] + [NativeHeader("Editor/Src/GI/BakePipeline/BakePipeline.bindings.h")] + internal class PostProcessRequests + { + private IntPtr _ptr; + + public PostProcessRequests(IntPtr ptr) + { + _ptr = ptr; + } + + internal extern void SetProbeRequests(PostProcessProbeRequest[] requests); + internal extern PostProcessProbeRequest[] GetProbeRequests(); + + internal static class BindingsMarshaller + { + public static IntPtr ConvertToUnmanaged(PostProcessRequests connection) => connection._ptr; + } + } + [RequiredByNativeCode] [StructLayout(LayoutKind.Sequential)] [NativeHeader("Editor/Src/GI/BakePipeline/BakePipeline.bindings.h")] @@ -27,6 +56,10 @@ public BakePipelineDriver(IntPtr ptr) _ptr = ptr; _ownsPtr = false; } + ~BakePipelineDriver() + { + Destroy(); + } public void Dispose() { diff --git a/Editor/Mono/GI/InputExtraction.bindings.cs b/Editor/Mono/GI/InputExtraction.bindings.cs index f9544e7a05..7b2d845f03 100644 --- a/Editor/Mono/GI/InputExtraction.bindings.cs +++ b/Editor/Mono/GI/InputExtraction.bindings.cs @@ -68,13 +68,13 @@ internal static class BindingsMarshaller } } - public static extern bool ExtractFromScene(string outputFolderPath, LightBaker.BakeInput input, LightBaker.LightmapRequests lightmapRequests, LightBaker.LightProbeRequests lightProbeRequests, SourceMap map); + public static extern bool ExtractFromScene(string outputFolderPath, BakeInput input, LightmapRequests lightmapRequests, LightProbeRequests lightProbeRequests, SourceMap map); [NativeMethod(IsThreadSafe = true)] - public static extern int[] ComputeOcclusionLightIndicesFromBakeInput(LightBaker.BakeInput bakeInput, UnityEngine.Vector3[] probePositions, uint maxLightsPerProbe); + public static extern int[] ComputeOcclusionLightIndicesFromBakeInput(BakeInput bakeInput, UnityEngine.Vector3[] probePositions, uint maxLightsPerProbe); [NativeMethod(IsThreadSafe = true)] - public static extern int[] GetShadowmaskChannelsFromLightIndices(LightBaker.BakeInput bakeInput, int[] lightIndices); + public static extern int[] GetShadowmaskChannelsFromLightIndices(BakeInput bakeInput, int[] lightIndices); private static string LookupGameObjectName(SourceMap map, int instanceIndex) { @@ -97,7 +97,7 @@ private static string LookupGameObjectName(SourceMap map, int instanceIndex) return ""; } - public static string LogInstances(LightBaker.BakeInput bakeInput, SourceMap map) + public static string LogInstances(BakeInput bakeInput, SourceMap map) { if (bakeInput is null) return string.Empty; @@ -109,11 +109,11 @@ public static string LogInstances(LightBaker.BakeInput bakeInput, SourceMap map) message += $" Instance [{i}]:\n"; else message += $" Instance [{i}] [{LookupGameObjectName(map, i)}]:\n"; - LightBaker.Instance instance = bakeInput.instance((uint)i); + Instance instance = bakeInput.instance((uint)i); message += $" mesh type\t\t\t: {instance.meshType}\n"; - if (instance.meshType == LightBaker.MeshType.MeshRenderer) + if (instance.meshType == MeshType.MeshRenderer) message += $" mesh index\t\t\t: {instance.meshIndex}\n"; - else if (instance.meshType == LightBaker.MeshType.Terrain) + else if (instance.meshType == MeshType.Terrain) message += $" terrain index\t\t: {instance.terrainIndex}\n"; message += $" transform\t\t\t: {instance.transform.GetRow(0)}\n"; message += $" \t\t\t: {instance.transform.GetRow(1)}\n"; @@ -121,7 +121,7 @@ public static string LogInstances(LightBaker.BakeInput bakeInput, SourceMap map) message += $" \t\t\t: {instance.transform.GetRow(3)}\n"; message += $" cast shadows\t\t: {instance.castShadows}\n"; message += $" receive shadows\t: {instance.receiveShadows}\n"; - if (instance.meshType == LightBaker.MeshType.MeshRenderer) + if (instance.meshType == MeshType.MeshRenderer) { message += $" odd neg scale\t\t: {instance.oddNegativeScale}\n"; message += $" lod group\t\t\t: {instance.lodGroup}\n"; @@ -142,7 +142,7 @@ public static string LogInstances(LightBaker.BakeInput bakeInput, SourceMap map) return message; } - public static string LogSceneMaterials(LightBaker.BakeInput bakeInput) + public static string LogSceneMaterials(BakeInput bakeInput) { if (bakeInput is null) return string.Empty; @@ -158,7 +158,7 @@ public static string LogSceneMaterials(LightBaker.BakeInput bakeInput) return message; } - public static string LogSceneCookies(LightBaker.BakeInput bakeInput) + public static string LogSceneCookies(BakeInput bakeInput) { if (bakeInput is null) return string.Empty; @@ -167,7 +167,7 @@ public static string LogSceneCookies(LightBaker.BakeInput bakeInput) message += $" cookie tex count\t: {bakeInput.GetCookieCount()}\n"; for (int i = 0; i < bakeInput.GetCookieCount(); ++i) { - LightBaker.CookieData cookie = bakeInput.GetCookieData((uint)i); + CookieData cookie = bakeInput.GetCookieData((uint)i); message += $" CookieTexture [{i}]:\n"; message += $" resolution\t\t: {cookie.resolution.width} x {cookie.resolution.height}\n"; message += $" pixelStride\t\t: {cookie.pixelStride}\n"; @@ -177,7 +177,7 @@ public static string LogSceneCookies(LightBaker.BakeInput bakeInput) return message; } - public static string LogSceneLights(LightBaker.BakeInput bakeInput) + public static string LogSceneLights(BakeInput bakeInput) { if (bakeInput is null) return string.Empty; @@ -185,7 +185,7 @@ public static string LogSceneLights(LightBaker.BakeInput bakeInput) message += $" light count\t\t: {bakeInput.GetLightCount()}\n"; for (int i = 0; i < bakeInput.GetLightCount(); ++i) { - LightBaker.Light light = bakeInput.GetLight((uint)i); + Light light = bakeInput.GetLight((uint)i); message += $" Light [{i}]:\n"; message += $" color\t\t\t\t\t: {light.color}\n"; message += $" indirect color\t\t: {light.indirectColor}\n"; @@ -208,7 +208,7 @@ public static string LogSceneLights(LightBaker.BakeInput bakeInput) return message; } - public static string LogSampleCounts(LightBaker.SampleCount sampleCount) + public static string LogSampleCounts(SampleCount sampleCount) { string message = string.Empty; message += $" direct\t\t: {sampleCount.directSampleCount}\n"; @@ -217,7 +217,7 @@ public static string LogSampleCounts(LightBaker.SampleCount sampleCount) return message; } - public static string LogSceneSettings(LightBaker.BakeInput bakeInput) + public static string LogSceneSettings(BakeInput bakeInput) { if (bakeInput is null) return string.Empty; @@ -237,7 +237,7 @@ public static string LogSceneSettings(LightBaker.BakeInput bakeInput) return message; } - public static string LogScene(LightBaker.BakeInput bakeInput, LightBaker.LightmapRequests lightmapRequests, LightBaker.LightProbeRequests lightProbeRequests, SourceMap map) + public static string LogScene(BakeInput bakeInput, LightmapRequests lightmapRequests, LightProbeRequests lightProbeRequests, SourceMap map) { if (bakeInput is null) return string.Empty; diff --git a/Editor/Mono/GI/InputExtraction.cs b/Editor/Mono/GI/InputExtraction.cs index 900eb4010b..2611032f2b 100644 --- a/Editor/Mono/GI/InputExtraction.cs +++ b/Editor/Mono/GI/InputExtraction.cs @@ -2,33 +2,125 @@ // Copyright (c) Unity Technologies. For terms of use, see // https://unity3d.com/legal/licenses/Unity_Reference_Only_License +using System; using UnityEditor.LightBaking; -using static UnityEditor.LightBaking.LightBaker; namespace UnityEngine.LightTransport { + public enum ProbeBakeRequestOutput : uint + { + RadianceDirect = 1 << 0, + RadianceIndirect = 1 << 1, + Validity = 1 << 2, + Occlusion = 1 << 3, + All = 0xFFFFFFFF + } + + public struct ProbeBakeRequest + { + public ProbeBakeRequestOutput outputTypes { get; set; } + public ulong positionOffset { get; set; } + public ulong positionLength { get; set; } + public string bakeOutputFolderPath { get; set; } + public string postProcessOutputFolderPath { get; set; } + public bool ignoreDirectEnvironment { get; set; } + public bool ignoreIndirectEnvironment { get; set; } + public float pushoff { get; set; } + public float indirectScale { get; set; } + public bool dering { get; set; } + } + public static class InputExtraction { // Completely opaque in the public API, this effectively hides internal LightBaker details. public class BakeInput { - internal BakeInput(LightBaker.BakeInput editorBakeInput) + internal BakeInput(UnityEditor.LightBaking.BakeInput editorBakeInput) { bakeInput = editorBakeInput; } - internal LightBaker.BakeInput bakeInput { get; } + internal UnityEditor.LightBaking.BakeInput bakeInput { get; } // Requests are not exposed in the public API, but we need them in LightBaker.PopulateWorld(). Going forward, requests will be split from the bake input in the public API as well. internal LightmapRequests lightmapRequests { get; set; } internal LightProbeRequests lightProbeRequests { get; set; } + internal PostProcessRequests postProcessRequests { get; set; } + + public void SetProbePositions(Vector3[] probePositions) + { + lightProbeRequests.SetProbePositions(probePositions); + } + + public void SetOcclusionLightIndices(int[] occlusionLightIndices) + { + lightProbeRequests.SetOcclusionLightIndices(occlusionLightIndices); + } + + public Vector3[] GetProbePositions() + { + return lightProbeRequests.GetProbePositions(); + } + + public int[] GetOcclusionLightIndices() + { + return lightProbeRequests.GetOcclusionLightIndices(); + } + + public void AddProbeRequest(ProbeBakeRequest request) + { + static ProbeRequestOutputType ConvertOutputEnum(ProbeBakeRequestOutput val) + { + var output = (ProbeRequestOutputType)0; + if (val.HasFlag(ProbeBakeRequestOutput.RadianceDirect)) + output |= ProbeRequestOutputType.RadianceDirect; + if (val.HasFlag(ProbeBakeRequestOutput.RadianceIndirect)) + output |= ProbeRequestOutputType.RadianceIndirect; + if (val.HasFlag(ProbeBakeRequestOutput.Validity)) + output |= ProbeRequestOutputType.Validity; + if (val.HasFlag(ProbeBakeRequestOutput.Occlusion)) + { + output |= ProbeRequestOutputType.LightProbeOcclusion; + output |= ProbeRequestOutputType.MixedLightOcclusion; + } + return output; + } + + ProbeRequest bakeRequest = new() + { + outputTypeMask = ConvertOutputEnum(request.outputTypes), + positionOffset = request.positionOffset, + positionLength = request.positionLength, + outputFolderPath = request.bakeOutputFolderPath, + ignoreDirectEnvironment = request.ignoreDirectEnvironment, + ignoreIndirectEnvironment = request.ignoreIndirectEnvironment, + pushoff = request.pushoff, + }; + + PostProcessProbeRequest postProcessRequest = new() + { + dering = request.dering, + indirectScale = request.indirectScale, + outputFolderPath = request.postProcessOutputFolderPath + }; + + var requests = lightProbeRequests.GetProbeRequests(); + Array.Resize(ref requests, requests.Length + 1); + requests[requests.Length - 1] = bakeRequest; + lightProbeRequests.SetLightProbeRequests(requests); + + var ppRequests = postProcessRequests.GetProbeRequests(); + Array.Resize(ref ppRequests, ppRequests.Length + 1); + ppRequests[ppRequests.Length - 1] = postProcessRequest; + postProcessRequests.SetProbeRequests(ppRequests); + } } public static bool ExtractFromScene(out BakeInput bakeInput) { const string outputFolderPath = "unused"; // We are not using disk IO. - LightBaker.BakeInput lightBakerBakeInput = new(); - LightBaker.LightmapRequests lightBakerLightmapRequests = new(); - LightBaker.LightProbeRequests lightBakerlightProbeRequests = new(); + UnityEditor.LightBaking.BakeInput lightBakerBakeInput = new(); + LightmapRequests lightBakerLightmapRequests = new(); + LightProbeRequests lightBakerlightProbeRequests = new(); UnityEditor.LightBaking.InputExtraction.SourceMap map = new(); bool result = UnityEditor.LightBaking.InputExtraction.ExtractFromScene(outputFolderPath, lightBakerBakeInput, lightBakerLightmapRequests, lightBakerlightProbeRequests, map); bakeInput = new BakeInput(lightBakerBakeInput) @@ -42,8 +134,8 @@ public static bool ExtractFromScene(out BakeInput bakeInput) public static bool PopulateWorld(BakeInput bakeInput, BakeProgressState progress, IDeviceContext context, IWorld world) { - LightBaker.Result result = LightBaker.PopulateWorld(bakeInput.bakeInput, bakeInput.lightmapRequests, bakeInput.lightProbeRequests, progress, context, world); - return result.type == LightBaker.ResultType.Success; + Result result = LightBaker.PopulateWorld(bakeInput.bakeInput, bakeInput.lightmapRequests, bakeInput.lightProbeRequests, progress, context, world); + return result.type == ResultType.Success; } // Note that in the non-public API, serialization of bake input does not imply serialization of requests. @@ -52,7 +144,7 @@ public static bool PopulateWorld(BakeInput bakeInput, BakeProgressState progress // Note that in the non-public API, deserialization of bake input does not imply deserialization of requests. internal static bool DeserializeBakeInput(string path, out InputExtraction.BakeInput bakeInput) { - UnityEditor.LightBaking.LightBaker.BakeInput lightBakerBakeInput = new(); + UnityEditor.LightBaking.BakeInput lightBakerBakeInput = new(); bakeInput = new BakeInput(lightBakerBakeInput); return LightBaker.Deserialize(path, bakeInput.bakeInput); } diff --git a/Editor/Mono/GI/LightBaker.bindings.cs b/Editor/Mono/GI/LightBaker.bindings.cs index 32ae76e6d3..3901cc5f1e 100644 --- a/Editor/Mono/GI/LightBaker.bindings.cs +++ b/Editor/Mono/GI/LightBaker.bindings.cs @@ -11,834 +11,840 @@ namespace UnityEditor.LightBaking { - [NativeHeader("Editor/Src/GI/LightBaker/LightBaker.Bindings.h")] - [StaticAccessor("LightBakerBindings", StaticAccessorType.DoubleColon)] - internal static partial class LightBaker + internal struct ProbeRequest + { + public ProbeRequestOutputType outputTypeMask; + public ulong positionOffset; + public ulong positionLength; + public float pushoff; + public string outputFolderPath; + + // Environment occlusion + public ulong integrationRadiusOffset; + public uint environmentOcclusionSampleCount; + public bool ignoreDirectEnvironment; + public bool ignoreIndirectEnvironment; + }; + + [Flags] + internal enum ProbeRequestOutputType : uint + { + RadianceDirect = 1 << 0, + RadianceIndirect = 1 << 1, + Validity = 1 << 2, + MixedLightOcclusion = 1 << 3, + LightProbeOcclusion = 1 << 4, + EnvironmentOcclusion = 1 << 5, + Depth = 1 << 6, + All = 0xFFFFFFFF + }; + + internal enum TilingMode : byte + { // Assuming a 4k lightmap (16M texels), the tiling will yield the following chunk sizes: + None = 0, // 4k * 4k = 16M texels + Quarter = 1, // 2k * 2k = 4M texels + Sixteenth = 2, // 1k * 1k = 1M texels + Sixtyfourth = 3, // 512 * 512 = 262k texels + TwoHundredFiftySixth = 4, // 256 * 256 = 65k texels + Max = TwoHundredFiftySixth, + Error = 5 // Error. We don't want to go lower (GPU occupancy will start to be a problem for smaller atlas sizes). + }; + + internal struct LightmapRequest + { + public LightmapRequestOutputType outputTypeMask; + public uint lightmapOffset; + public uint lightmapCount; + public TilingMode tilingMode; + public string outputFolderPath; + public float pushoff; + }; + + internal enum LightmapRequestOutputType : uint + { + IrradianceIndirect = 1 << 0, + IrradianceDirect = 1 << 1, + IrradianceEnvironment = 1 << 2, + Occupancy = 1 << 3, + Validity = 1 << 4, + DirectionalityIndirect = 1 << 5, + DirectionalityDirect = 1 << 6, + AmbientOcclusion = 1 << 7, + Shadowmask = 1 << 8, + Normal = 1 << 9, + ChartIndex = 1 << 10, + OverlapPixelIndex = 1 << 11, + All = 0xFFFFFFFF + }; + + internal enum ResultType : uint + { + Success = 0, + Cancelled, + JobFailed, + OutOfMemory, + InvalidInput, + LowLevelAPIFailure, + FailedCreatingJobQueue, + IOFailed, + ConnectedToBaker, + Undefined + } + + [RequiredByNativeCode] + internal struct Result { - public enum ResultType : uint + public ResultType type; + public string message; + public override string ToString() { - Success = 0, - Cancelled, - JobFailed, - OutOfMemory, - InvalidInput, - LowLevelAPIFailure, - FailedCreatingJobQueue, - IOFailed, - ConnectedToBaker, - Undefined + if (message.Length == 0) + return $"Result type: '{type}'"; + return $"Result type: '{type}', message: '{message}'"; } - [RequiredByNativeCode] - public struct Result + public IProbeIntegrator.Result ConvertToIProbeIntegratorResult() { - public ResultType type; - public string message; - public override string ToString() + IProbeIntegrator.Result result = new() { - if (message.Length == 0) - return $"Result type: '{type}'"; - return $"Result type: '{type}', message: '{message}'"; - } - - public IProbeIntegrator.Result ConvertToIProbeIntegratorResult() - { - IProbeIntegrator.Result result = new () - { - type = (IProbeIntegrator.ResultType)type, - message = message - }; - return result; - } + type = (IProbeIntegrator.ResultType)type, + message = message + }; + return result; } + } - public enum Backend - { - CPU = 0, - GPU = 1, - UnityComputeGPU = 2 - } - public enum TransmissionChannels - { - Red = 0, - Alpha = 1, - AlphaCutout = 2, - RGB = 3, - None = 4 - } - public enum TransmissionType - { - Opacity = 0, - Transparency = 1, - None = 2 - } - public enum MeshType - { - Terrain = 0, - MeshRenderer = 1 - } - public enum MixedLightingMode - { - IndirectOnly = 0, - Subtractive = 1, - Shadowmask = 2, - }; - public enum LightmapBakeMode - { - NonDirectional = 0, - CombinedDirectional = 1 - }; - [Flags] - public enum ProbeRequestOutputType : uint - { - RadianceDirect = 1 << 0, - RadianceIndirect = 1 << 1, - Validity = 1 << 2, - MixedLightOcclusion = 1 << 3, - LightProbeOcclusion = 1 << 4, - EnvironmentOcclusion = 1 << 5, - Depth = 1 << 6, - All = 0xFFFFFFFF - }; - public struct ProbeRequest - { - public ProbeRequestOutputType outputTypeMask; - public ulong positionOffset; - public ulong positionLength; - public float pushoff; - public string outputFolderPath; - - // Environment occlusion - public ulong integrationRadiusOffset; - public uint environmentOcclusionSampleCount; - public bool ignoreDirectEnvironment; - public bool ignoreIndirectEnvironment; - }; - [Flags] - public enum LightmapRequestOutputType : uint - { - IrradianceIndirect = 1 << 0, - IrradianceDirect = 1 << 1, - IrradianceEnvironment = 1 << 2, - Occupancy = 1 << 3, - Validity = 1 << 4, - DirectionalityIndirect = 1 << 5, - DirectionalityDirect = 1 << 6, - AmbientOcclusion = 1 << 7, - Shadowmask = 1 << 8, - Normal = 1 << 9, - ChartIndex = 1 << 10, - OverlapPixelIndex = 1 << 11, - All = 0xFFFFFFFF - }; - public enum TilingMode : byte - { // Assuming a 4k lightmap (16M texels), the tiling will yield the following chunk sizes: - None = 0, // 4k * 4k = 16M texels - Quarter = 1, // 2k * 2k = 4M texels - Sixteenth = 2, // 1k * 1k = 1M texels - Sixtyfourth = 3, // 512 * 512 = 262k texels - TwoHundredFiftySixth = 4, // 256 * 256 = 65k texels - Max = TwoHundredFiftySixth, - Error = 5 // Error. We don't want to go lower (GPU occupancy will start to be a problem for smaller atlas sizes). - }; - public struct LightmapRequest - { - public LightmapRequestOutputType outputTypeMask; - public uint lightmapOffset; - public uint lightmapCount; - public TilingMode tilingMode; - public string outputFolderPath; - public float pushoff; - }; - public struct Resolution - { - public Resolution(uint widthIn, uint heightIn) - { - width = widthIn; - height = heightIn; - } - public uint width; - public uint height; + internal enum Backend + { + CPU = 0, + GPU = 1, + UnityComputeGPU = 2 + } + internal enum TransmissionChannels + { + Red = 0, + Alpha = 1, + AlphaCutout = 2, + RGB = 3, + None = 4 + } + internal enum TransmissionType + { + Opacity = 0, + Transparency = 1, + None = 2 + } + internal enum MeshType + { + Terrain = 0, + MeshRenderer = 1 + } + internal enum MixedLightingMode + { + IndirectOnly = 0, + Subtractive = 1, + Shadowmask = 2, + }; + internal enum LightmapBakeMode + { + NonDirectional = 0, + CombinedDirectional = 1 + }; + internal struct Resolution + { + public Resolution(uint widthIn, uint heightIn) + { + width = widthIn; + height = heightIn; } + public uint width; + public uint height; + } - public struct TextureData + internal struct TextureData + { + public TextureData(Resolution resolutionIn) { - public TextureData(Resolution resolutionIn) - { - resolution = resolutionIn; - data = new Vector4[resolution.width * resolution.height]; - } - public Resolution resolution; - public Vector4[] data; + resolution = resolutionIn; + data = new Vector4[resolution.width * resolution.height]; } + public Resolution resolution; + public Vector4[] data; + } - public struct TextureTransform - { - public Vector2 scale; - public Vector2 offset; - }; + internal struct TextureTransform + { + public Vector2 scale; + public Vector2 offset; + }; - public struct TextureProperties - { - public TextureWrapMode wrapModeU; - public TextureWrapMode wrapModeV; - public FilterMode filterMode; - public TextureTransform textureST; - }; + internal struct TextureProperties + { + public TextureWrapMode wrapModeU; + public TextureWrapMode wrapModeV; + public FilterMode filterMode; + public TextureTransform textureST; + }; - public struct CookieData + internal struct CookieData + { + public CookieData(Resolution resolutionIn, uint pixelStrideIn, uint slicesIn, bool repeatIn) { - public CookieData(Resolution resolutionIn, uint pixelStrideIn, uint slicesIn, bool repeatIn) - { - resolution = resolutionIn; - pixelStride = pixelStrideIn; - slices = slicesIn; - repeat = repeatIn; - data = new byte[resolution.width * resolution.height * slices * pixelStride]; - } - public Resolution resolution; - public uint pixelStride; - public uint slices; - public bool repeat; - public byte[] data; - } - - public struct Instance - { - public MeshType meshType; - public int meshIndex; // index into BakeInput::m_MeshData, -1 for Terrain - public int terrainIndex; // index into BakeInput::m_TerrainData, -1 for MeshRenderer - public Matrix4x4 transform; - public bool castShadows; - public bool receiveShadows; - public bool oddNegativeScale; - public int lodGroup; - public byte lodMask; - public int[] submeshMaterialIndices; - } - - public struct Terrain - { - public uint heightMapIndex; // index into BakeInput::m_HeightmapData - public int terrainHoleIndex; // index into BakeInput::m_TerrainHoleData -1 means no hole data - public float outputResolution; - public Vector3 heightmapScale; - public Vector4 uvBounds; - } - - public struct Material - { - public bool doubleSidedGI; - public TransmissionChannels transmissionChannels; - public TransmissionType transmissionType; - } - - public enum LightType : byte - { - Directional = 0, - Point = 1, - Spot = 2, - Rectangle = 3, - Disc = 4, - SpotPyramidShape = 5, - SpotBoxShape = 6 - }; - - public enum FalloffType : byte - { - InverseSquared = 0, - InverseSquaredNoRangeAttenuation = 1, - Linear = 2, - Legacy = 3 - }; - - public enum AngularFalloffType : byte - { - LUT = 0, - AnalyticAndInnerAngle = 1 - }; - - public enum LightMode : byte - { - Realtime = 0, - Mixed = 1, - Baked = 2 - }; - - public struct Light - { - public Vector3 color; - public Vector3 indirectColor; - public Quaternion orientation; - public Vector3 position; - public float range; - public int cookieTextureIndex; - public float cookieScale; - public float coneAngle; - public float innerConeAngle; - public float shape0; - public float shape1; - public LightType type; - public LightMode mode; - public FalloffType falloff; - public AngularFalloffType angularFalloff; - public bool castsShadows; - public int shadowMaskChannel; - } - - public struct SampleCount - { - public uint directSampleCount; - public uint indirectSampleCount; - public uint environmentSampleCount; - }; - - public struct LightingSettings - { - public SampleCount lightmapSampleCounts; - public SampleCount probeSampleCounts; - public uint minBounces; - public uint maxBounces; - public LightmapBakeMode lightmapBakeMode; - public MixedLightingMode mixedLightingMode; - public bool aoEnabled; - public float aoDistance; - }; - - [RequiredByNativeCode] - [StructLayout(LayoutKind.Sequential)] - public class ExternalProcessConnection : IDisposable - { - private IntPtr _ptr; - private readonly bool _ownsPtr; + resolution = resolutionIn; + pixelStride = pixelStrideIn; + slices = slicesIn; + repeat = repeatIn; + data = new byte[resolution.width * resolution.height * slices * pixelStride]; + } + public Resolution resolution; + public uint pixelStride; + public uint slices; + public bool repeat; + public byte[] data; + } - public ExternalProcessConnection() - { - _ptr = Internal_Create(); - _ownsPtr = true; - } + internal struct Instance + { + public MeshType meshType; + public int meshIndex; // index into BakeInput::m_MeshData, -1 for Terrain + public int terrainIndex; // index into BakeInput::m_TerrainData, -1 for MeshRenderer + public Matrix4x4 transform; + public bool castShadows; + public bool receiveShadows; + public bool oddNegativeScale; + public int lodGroup; + public byte lodMask; + public int[] submeshMaterialIndices; + } - public ExternalProcessConnection(IntPtr ptr) - { - _ptr = ptr; - _ownsPtr = false; - } + internal struct Terrain + { + public uint heightMapIndex; // index into BakeInput::m_HeightmapData + public int terrainHoleIndex; // index into BakeInput::m_TerrainHoleData -1 means no hole data + public float outputResolution; + public Vector3 heightmapScale; + public Vector4 uvBounds; + } - public bool Connect(int bakePortNumber) - { - return Internal_Connect(bakePortNumber); - } + internal struct Material + { + public bool doubleSidedGI; + public TransmissionChannels transmissionChannels; + public TransmissionType transmissionType; + } - ~ExternalProcessConnection() - { - Destroy(); - } + internal enum LightType : byte + { + Directional = 0, + Point = 1, + Spot = 2, + Rectangle = 3, + Disc = 4, + SpotPyramidShape = 5, + SpotBoxShape = 6 + }; + + internal enum FalloffType : byte + { + InverseSquared = 0, + InverseSquaredNoRangeAttenuation = 1, + Linear = 2, + Legacy = 3 + }; - public void Dispose() - { - Destroy(); - GC.SuppressFinalize(this); - } + internal enum AngularFalloffType : byte + { + LUT = 0, + AnalyticAndInnerAngle = 1 + }; - void Destroy() - { - if (_ownsPtr && _ptr != IntPtr.Zero) - { - Internal_Destroy(_ptr); - _ptr = IntPtr.Zero; - } - } + internal enum LightMode : byte + { + Realtime = 0, + Mixed = 1, + Baked = 2 + }; - [NativeMethod(IsThreadSafe = true)] - static extern void Internal_Destroy(IntPtr ptr); - [NativeMethod(IsThreadSafe = true)] - static extern IntPtr Internal_Create(); - extern bool Internal_Connect(int bakePortNumber); + internal struct Light + { + public Vector3 color; + public Vector3 indirectColor; + public Quaternion orientation; + public Vector3 position; + public float range; + public int cookieTextureIndex; + public float cookieScale; + public float coneAngle; + public float innerConeAngle; + public float shape0; + public float shape1; + public LightType type; + public LightMode mode; + public FalloffType falloff; + public AngularFalloffType angularFalloff; + public bool castsShadows; + public int shadowMaskChannel; + } - internal static class BindingsMarshaller - { - public static IntPtr ConvertToNative(ExternalProcessConnection connection) => connection._ptr; - } + internal struct SampleCount + { + public uint directSampleCount; + public uint indirectSampleCount; + public uint environmentSampleCount; + }; + + internal struct LightingSettings + { + public SampleCount lightmapSampleCounts; + public SampleCount probeSampleCounts; + public uint minBounces; + public uint maxBounces; + public LightmapBakeMode lightmapBakeMode; + public MixedLightingMode mixedLightingMode; + public bool aoEnabled; + public float aoDistance; + }; + + [RequiredByNativeCode] + [StructLayout(LayoutKind.Sequential)] + internal class ExternalProcessConnection : IDisposable + { + private IntPtr _ptr; + private readonly bool _ownsPtr; + + public ExternalProcessConnection() + { + _ptr = Internal_Create(); + _ownsPtr = true; } - [RequiredByNativeCode] - [StructLayout(LayoutKind.Sequential)] - public class BakeInput : IDisposable + public ExternalProcessConnection(IntPtr ptr) { - private IntPtr _ptr; - private readonly bool _ownsPtr; + _ptr = ptr; + _ownsPtr = false; + } - public BakeInput() - { - _ptr = Internal_Create(); - _ownsPtr = true; - } - public BakeInput(IntPtr ptr) - { - _ptr = ptr; - _ownsPtr = false; - } - ~BakeInput() - { - Destroy(); - } + public bool Connect(int bakePortNumber) + { + return Internal_Connect(bakePortNumber); + } - public void Dispose() - { - Destroy(); - GC.SuppressFinalize(this); - } + ~ExternalProcessConnection() + { + Destroy(); + } - void Destroy() + public void Dispose() + { + Destroy(); + GC.SuppressFinalize(this); + } + + void Destroy() + { + if (_ownsPtr && _ptr != IntPtr.Zero) { - if (_ownsPtr && _ptr != IntPtr.Zero) - { - Internal_Destroy(_ptr); - _ptr = IntPtr.Zero; - } + Internal_Destroy(_ptr); + _ptr = IntPtr.Zero; } + } - public extern ulong GetByteSize(); + [NativeMethod(IsThreadSafe = true)] + static extern void Internal_Destroy(IntPtr ptr); + [NativeMethod(IsThreadSafe = true)] + static extern IntPtr Internal_Create(); + extern bool Internal_Connect(int bakePortNumber); - public Texture2D GetAlbedoTexture(uint index) - { - if (index >= albedoTextureCount) - throw new ArgumentException($"index must be between 0 and {albedoTextureCount - 1}, but was {index}"); - TextureData textureData = GetAlbedoTextureData(index); - Texture2D tex = new ((int)textureData.resolution.width, (int)textureData.resolution.height, TextureFormat.RGBAFloat, false); - tex.SetPixelData(textureData.data, 0); - tex.filterMode = FilterMode.Point; - tex.Apply(); - return tex; - } + internal static class BindingsMarshaller + { + public static IntPtr ConvertToNative(ExternalProcessConnection connection) => connection._ptr; + } + } - public Texture2D GetEmissiveTexture(uint index) - { - if (index >= emissiveTextureCount) - throw new ArgumentException($"index must be between 0 and {emissiveTextureCount - 1}, but was {index}"); - TextureData textureData = GetEmissiveTextureData(index); - Texture2D tex = new ((int)textureData.resolution.width, (int)textureData.resolution.height, TextureFormat.RGBAFloat, false); - tex.SetPixelData(textureData.data, 0); - tex.filterMode = FilterMode.Point; - tex.Apply(); - return tex; - } + [RequiredByNativeCode] + [StructLayout(LayoutKind.Sequential)] + internal class BakeInput : IDisposable + { + private IntPtr _ptr; + private readonly bool _ownsPtr; - static extern IntPtr Internal_Create(); - [NativeMethod(IsThreadSafe = true)] - static extern void Internal_Destroy(IntPtr ptr); + public BakeInput() + { + _ptr = Internal_Create(); + _ownsPtr = true; + } + public BakeInput(IntPtr ptr) + { + _ptr = ptr; + _ownsPtr = false; + } + ~BakeInput() + { + Destroy(); + } - extern LightingSettings Internal_GetLightingSettings(); - public LightingSettings GetLightingSettings() - { - return Internal_GetLightingSettings(); - } - extern void Internal_SetLightingSettings(LightingSettings lightingSettings); - public void SetLightingSettings(LightingSettings lightingSettings) - { - Internal_SetLightingSettings(lightingSettings); - } + public void Dispose() + { + Destroy(); + GC.SuppressFinalize(this); + } - public extern uint instanceCount { get; } - extern Instance Internal_Instance(uint index); - public Instance instance(uint index) - { - if (index >= instanceCount) - throw new ArgumentException($"index must be between 0 and {instanceCount - 1}, but was {index}"); - Instance instance = Internal_Instance(index); - return instance; - } - extern void Internal_SetInstance(uint index, Instance instance); - public void instance(uint index, Instance instance) + void Destroy() + { + if (_ownsPtr && _ptr != IntPtr.Zero) { - if (index >= instanceCount) - throw new ArgumentException($"index must be between 0 and {instanceCount - 1}, but was {index}"); - Internal_SetInstance(index, instance); + Internal_Destroy(_ptr); + _ptr = IntPtr.Zero; } + } - public extern uint terrainCount { get; } - extern Terrain Internal_GetTerrain(uint index); - public Terrain GetTerrain(uint index) - { - if (index >= terrainCount) - throw new ArgumentException($"index must be between 0 and {terrainCount - 1}, but was {index}"); - Terrain terrain = Internal_GetTerrain(index); - return terrain; - } + public extern ulong GetByteSize(); - public extern Vector2[] GetUV1VertexData(uint meshIndex); + public Texture2D GetAlbedoTexture(uint index) + { + if (index >= albedoTextureCount) + throw new ArgumentException($"index must be between 0 and {albedoTextureCount - 1}, but was {index}"); + TextureData textureData = GetAlbedoTextureData(index); + Texture2D tex = new((int)textureData.resolution.width, (int)textureData.resolution.height, TextureFormat.RGBAFloat, false); + tex.SetPixelData(textureData.data, 0); + tex.filterMode = FilterMode.Point; + tex.Apply(); + return tex; + } - public extern uint meshCount { get; } - public extern uint heightmapCount { get; } - public extern uint holemapCount { get; } - public extern uint materialCount { get; } - extern Material Internal_GetMaterial(uint index); - extern void Internal_SetMaterial(uint index, Material material); - public Material GetMaterial(uint index) - { - if (index >= materialCount) - throw new ArgumentException($"index must be between 0 and {materialCount - 1}, but was {index}"); - Material material = Internal_GetMaterial(index); - return material; - } - public void SetMaterial(uint index, Material material) - { - if (index >= materialCount) - throw new ArgumentException($"index must be between 0 and {materialCount - 1}, but was {index}"); - Internal_SetMaterial(index, material); - } - public int GetMaterialIndex(uint instanceIndex, uint submeshIndex) - { - if (instanceIndex >= instanceCount) - throw new ArgumentException($"instanceIndex must be between 0 and {instanceCount - 1}, but was {instanceIndex}"); - Instance theInstance = instance(instanceIndex); - if (theInstance.submeshMaterialIndices.Length == 0) - throw new ArgumentException($"instance {instanceIndex} has not materials"); - if (submeshIndex >= theInstance.submeshMaterialIndices.Length) - throw new ArgumentException($"submeshIndex must be between 0 and {theInstance.submeshMaterialIndices.Length - 1}, but was {submeshIndex}"); - return theInstance.submeshMaterialIndices[submeshIndex]; - } - extern uint Internal_GetLightCount(); - public uint GetLightCount() - { - return Internal_GetLightCount(); - } - extern Light Internal_GetLight(uint index); - extern void Internal_SetLight(uint index, Light light); - public Light GetLight(uint index) - { - if (index >= GetLightCount()) - throw new ArgumentException($"index must be between 0 and {GetLightCount() - 1}, but was {index}"); - return Internal_GetLight(index); - } - public void SetLight(uint index, Light light) - { - if (index >= GetLightCount()) - throw new ArgumentException($"index must be between 0 and {GetLightCount() - 1}, but was {0}"); - Internal_SetLight(index, light); - } + public Texture2D GetEmissiveTexture(uint index) + { + if (index >= emissiveTextureCount) + throw new ArgumentException($"index must be between 0 and {emissiveTextureCount - 1}, but was {index}"); + TextureData textureData = GetEmissiveTextureData(index); + Texture2D tex = new((int)textureData.resolution.width, (int)textureData.resolution.height, TextureFormat.RGBAFloat, false); + tex.SetPixelData(textureData.data, 0); + tex.filterMode = FilterMode.Point; + tex.Apply(); + return tex; + } - extern int Internal_instanceAlbedoEmissiveIndex(uint instanceIndex); - extern int Internal_instanceTransmissiveIndex(uint instanceIndex, uint submeshIndex); - public int instanceToAlbedoIndex(uint instanceIndex) - { - if (instanceIndex >= instanceCount) - throw new ArgumentException($"index must be between 0 and {instanceCount - 1}, but was {instanceIndex}"); - return Internal_instanceAlbedoEmissiveIndex(instanceIndex); - } - public int instanceToEmissiveIndex(uint instanceIndex) - { - if (instanceIndex >= instanceCount) - throw new ArgumentException($"index must be between 0 and {instanceCount - 1}, but was {instanceIndex}"); - return Internal_instanceAlbedoEmissiveIndex(instanceIndex); - } - public int instanceToTransmissiveIndex(uint instanceIndex, uint submeshIndex) - { - if (instanceIndex >= instanceCount) - throw new ArgumentException($"index must be between 0 and {instanceCount - 1}, but was {instanceIndex}"); - Instance inst = instance(instanceIndex); - int submeshCount = inst.submeshMaterialIndices.Length; - if (submeshIndex >= submeshCount) - throw new ArgumentException($"submeshIndex must be between 0 and {submeshCount - 1}, but was {submeshIndex}"); - int materialIndex = inst.submeshMaterialIndices[submeshIndex]; - if (materialIndex == -1) - throw new ArgumentException($"material for submesh {submeshIndex} did not exist."); - - return Internal_instanceTransmissiveIndex(instanceIndex, submeshIndex); - } + static extern IntPtr Internal_Create(); + [NativeMethod(IsThreadSafe = true)] + static extern void Internal_Destroy(IntPtr ptr); - public extern uint albedoTextureCount { get; } - extern TextureData Internal_GetAlbedoTextureData(uint index); - extern void Internal_SetAlbedoTextureData(uint index, TextureData textureData); + extern LightingSettings Internal_GetLightingSettings(); + public LightingSettings GetLightingSettings() + { + return Internal_GetLightingSettings(); + } + extern void Internal_SetLightingSettings(LightingSettings lightingSettings); + public void SetLightingSettings(LightingSettings lightingSettings) + { + Internal_SetLightingSettings(lightingSettings); + } - public TextureData GetAlbedoTextureData(uint index) - { - if (index >= albedoTextureCount) - throw new ArgumentException($"index must be between 0 and {albedoTextureCount - 1}, but was {index}"); - return Internal_GetAlbedoTextureData(index); - } - public void SetAlbedoTextureData(uint index, TextureData textureData) - { - if (index >= albedoTextureCount) - throw new ArgumentException($"index must be between 0 and {albedoTextureCount - 1}, but was {index}"); - Internal_SetAlbedoTextureData(index, textureData); - } + public extern uint instanceCount { get; } + extern Instance Internal_Instance(uint index); + public Instance instance(uint index) + { + if (index >= instanceCount) + throw new ArgumentException($"index must be between 0 and {instanceCount - 1}, but was {index}"); + Instance instance = Internal_Instance(index); + return instance; + } + extern void Internal_SetInstance(uint index, Instance instance); + public void instance(uint index, Instance instance) + { + if (index >= instanceCount) + throw new ArgumentException($"index must be between 0 and {instanceCount - 1}, but was {index}"); + Internal_SetInstance(index, instance); + } - public extern uint emissiveTextureCount { get; } - public extern uint transmissiveTextureCount { get; } - public extern uint transmissiveTexturePropertiesCount { get; } - extern TextureData Internal_GetEmissiveTextureData(uint index); - extern void Internal_SetEmissiveTextureData(uint index, TextureData textureData); - public TextureData GetEmissiveTextureData(uint index) - { - if (index >= emissiveTextureCount) - throw new ArgumentException($"index must be between 0 and {emissiveTextureCount - 1}, but was {index}"); - return Internal_GetEmissiveTextureData(index); - } - public void SetEmissiveTextureData(uint index, TextureData textureData) - { - if (index >= emissiveTextureCount) - throw new ArgumentException($"index must be between 0 and {emissiveTextureCount - 1}, but was {index}"); - Internal_SetEmissiveTextureData(index, textureData); - } + public extern uint terrainCount { get; } + extern Terrain Internal_GetTerrain(uint index); + public Terrain GetTerrain(uint index) + { + if (index >= terrainCount) + throw new ArgumentException($"index must be between 0 and {terrainCount - 1}, but was {index}"); + Terrain terrain = Internal_GetTerrain(index); + return terrain; + } - extern TextureData Internal_GetTransmissiveTextureData(uint index); - extern void Internal_SetTransmissiveTextureData(uint index, TextureData textureData); - public TextureData GetTransmissiveTextureData(uint index) - { - if (index >= transmissiveTextureCount) - throw new ArgumentException($"index must be between 0 and {transmissiveTextureCount - 1}, but was {index}"); - return Internal_GetTransmissiveTextureData(index); - } - public void SetTransmissiveTextureData(uint index, TextureData textureData) - { - if (index >= emissiveTextureCount) - throw new ArgumentException($"index must be between 0 and {transmissiveTextureCount - 1}, but was {index}"); - Internal_SetTransmissiveTextureData(index, textureData); - } - extern TextureProperties Internal_GetTransmissiveTextureProperties(uint index); - public TextureProperties GetTransmissiveTextureProperties(uint index) - { - if (index >= transmissiveTexturePropertiesCount) - throw new ArgumentException($"index must be between 0 and {transmissiveTexturePropertiesCount - 1}, but was {index}"); - return Internal_GetTransmissiveTextureProperties(index); - } - extern void Internal_SetTransmissiveTextureProperties(uint index, TextureProperties textureProperties); - public void SetTransmissiveTextureProperties(uint index, TextureProperties textureProperties) - { - if (index >= transmissiveTexturePropertiesCount) - throw new ArgumentException($"index must be between 0 and {transmissiveTexturePropertiesCount - 1}, but was {index}"); - Internal_SetTransmissiveTextureProperties(index, textureProperties); - } + public extern Vector2[] GetUV1VertexData(uint meshIndex); - public extern uint GetCookieCount(); - extern CookieData Internal_GetCookieData(uint index); - extern void Internal_SetCookieData(uint index, CookieData cookieData); - public CookieData GetCookieData(uint index) - { - if (index >= GetCookieCount()) - throw new ArgumentException($"index must be between 0 and {GetCookieCount() - 1}, but was {index}"); - return Internal_GetCookieData(index); - } - public void SetCookieData(uint index, CookieData cookieData) - { - if (index >= GetCookieCount()) - throw new ArgumentException($"index must be between 0 and {GetCookieCount() - 1}, but was {index}"); - Internal_SetCookieData(index, cookieData); - } - public extern void SetEnvironment(Vector4 color); - public extern void SetEnvironmentFromTextures(TextureData posX, TextureData negX, TextureData posY, TextureData negY, TextureData posZ, TextureData negZ); - public extern TextureData GetEnvironmentCubeTexture(); + public extern uint meshCount { get; } + public extern uint heightmapCount { get; } + public extern uint holemapCount { get; } + public extern uint materialCount { get; } + extern Material Internal_GetMaterial(uint index); + extern void Internal_SetMaterial(uint index, Material material); + public Material GetMaterial(uint index) + { + if (index >= materialCount) + throw new ArgumentException($"index must be between 0 and {materialCount - 1}, but was {index}"); + Material material = Internal_GetMaterial(index); + return material; + } + public void SetMaterial(uint index, Material material) + { + if (index >= materialCount) + throw new ArgumentException($"index must be between 0 and {materialCount - 1}, but was {index}"); + Internal_SetMaterial(index, material); + } + public int GetMaterialIndex(uint instanceIndex, uint submeshIndex) + { + if (instanceIndex >= instanceCount) + throw new ArgumentException($"instanceIndex must be between 0 and {instanceCount - 1}, but was {instanceIndex}"); + Instance theInstance = instance(instanceIndex); + if (theInstance.submeshMaterialIndices.Length == 0) + throw new ArgumentException($"instance {instanceIndex} has not materials"); + if (submeshIndex >= theInstance.submeshMaterialIndices.Length) + throw new ArgumentException($"submeshIndex must be between 0 and {theInstance.submeshMaterialIndices.Length - 1}, but was {submeshIndex}"); + return theInstance.submeshMaterialIndices[submeshIndex]; + } + extern uint Internal_GetLightCount(); + public uint GetLightCount() + { + return Internal_GetLightCount(); + } + extern Light Internal_GetLight(uint index); + extern void Internal_SetLight(uint index, Light light); + public Light GetLight(uint index) + { + if (index >= GetLightCount()) + throw new ArgumentException($"index must be between 0 and {GetLightCount() - 1}, but was {index}"); + return Internal_GetLight(index); + } + public void SetLight(uint index, Light light) + { + if (index >= GetLightCount()) + throw new ArgumentException($"index must be between 0 and {GetLightCount() - 1}, but was {0}"); + Internal_SetLight(index, light); + } - internal static class BindingsMarshaller - { - public static IntPtr ConvertToNative(BakeInput bakeInput) => bakeInput._ptr; - } - public extern bool CheckIntegrity(); + extern int Internal_instanceAlbedoEmissiveIndex(uint instanceIndex); + extern int Internal_instanceTransmissiveIndex(uint instanceIndex, uint submeshIndex); + public int instanceToAlbedoIndex(uint instanceIndex) + { + if (instanceIndex >= instanceCount) + throw new ArgumentException($"index must be between 0 and {instanceCount - 1}, but was {instanceIndex}"); + return Internal_instanceAlbedoEmissiveIndex(instanceIndex); + } + public int instanceToEmissiveIndex(uint instanceIndex) + { + if (instanceIndex >= instanceCount) + throw new ArgumentException($"index must be between 0 and {instanceCount - 1}, but was {instanceIndex}"); + return Internal_instanceAlbedoEmissiveIndex(instanceIndex); + } + public int instanceToTransmissiveIndex(uint instanceIndex, uint submeshIndex) + { + if (instanceIndex >= instanceCount) + throw new ArgumentException($"index must be between 0 and {instanceCount - 1}, but was {instanceIndex}"); + Instance inst = instance(instanceIndex); + int submeshCount = inst.submeshMaterialIndices.Length; + if (submeshIndex >= submeshCount) + throw new ArgumentException($"submeshIndex must be between 0 and {submeshCount - 1}, but was {submeshIndex}"); + int materialIndex = inst.submeshMaterialIndices[submeshIndex]; + if (materialIndex == -1) + throw new ArgumentException($"material for submesh {submeshIndex} did not exist."); + + return Internal_instanceTransmissiveIndex(instanceIndex, submeshIndex); + } + + public extern uint albedoTextureCount { get; } + extern TextureData Internal_GetAlbedoTextureData(uint index); + extern void Internal_SetAlbedoTextureData(uint index, TextureData textureData); + + public TextureData GetAlbedoTextureData(uint index) + { + if (index >= albedoTextureCount) + throw new ArgumentException($"index must be between 0 and {albedoTextureCount - 1}, but was {index}"); + return Internal_GetAlbedoTextureData(index); + } + public void SetAlbedoTextureData(uint index, TextureData textureData) + { + if (index >= albedoTextureCount) + throw new ArgumentException($"index must be between 0 and {albedoTextureCount - 1}, but was {index}"); + Internal_SetAlbedoTextureData(index, textureData); } - [RequiredByNativeCode] - [StructLayout(LayoutKind.Sequential)] - public class LightProbeRequests : IDisposable + public extern uint emissiveTextureCount { get; } + public extern uint transmissiveTextureCount { get; } + public extern uint transmissiveTexturePropertiesCount { get; } + extern TextureData Internal_GetEmissiveTextureData(uint index); + extern void Internal_SetEmissiveTextureData(uint index, TextureData textureData); + public TextureData GetEmissiveTextureData(uint index) + { + if (index >= emissiveTextureCount) + throw new ArgumentException($"index must be between 0 and {emissiveTextureCount - 1}, but was {index}"); + return Internal_GetEmissiveTextureData(index); + } + public void SetEmissiveTextureData(uint index, TextureData textureData) { - private IntPtr _ptr; - private readonly bool _ownsPtr; + if (index >= emissiveTextureCount) + throw new ArgumentException($"index must be between 0 and {emissiveTextureCount - 1}, but was {index}"); + Internal_SetEmissiveTextureData(index, textureData); + } - public LightProbeRequests() - { - _ptr = Internal_Create(); - _ownsPtr = true; - } - public LightProbeRequests(IntPtr ptr) - { - _ptr = ptr; - _ownsPtr = false; - } - ~LightProbeRequests() - { - Destroy(); - } + extern TextureData Internal_GetTransmissiveTextureData(uint index); + extern void Internal_SetTransmissiveTextureData(uint index, TextureData textureData); + public TextureData GetTransmissiveTextureData(uint index) + { + if (index >= transmissiveTextureCount) + throw new ArgumentException($"index must be between 0 and {transmissiveTextureCount - 1}, but was {index}"); + return Internal_GetTransmissiveTextureData(index); + } + public void SetTransmissiveTextureData(uint index, TextureData textureData) + { + if (index >= emissiveTextureCount) + throw new ArgumentException($"index must be between 0 and {transmissiveTextureCount - 1}, but was {index}"); + Internal_SetTransmissiveTextureData(index, textureData); + } + extern TextureProperties Internal_GetTransmissiveTextureProperties(uint index); + public TextureProperties GetTransmissiveTextureProperties(uint index) + { + if (index >= transmissiveTexturePropertiesCount) + throw new ArgumentException($"index must be between 0 and {transmissiveTexturePropertiesCount - 1}, but was {index}"); + return Internal_GetTransmissiveTextureProperties(index); + } + extern void Internal_SetTransmissiveTextureProperties(uint index, TextureProperties textureProperties); + public void SetTransmissiveTextureProperties(uint index, TextureProperties textureProperties) + { + if (index >= transmissiveTexturePropertiesCount) + throw new ArgumentException($"index must be between 0 and {transmissiveTexturePropertiesCount - 1}, but was {index}"); + Internal_SetTransmissiveTextureProperties(index, textureProperties); + } - public void Dispose() - { - Destroy(); - GC.SuppressFinalize(this); - } + public extern uint GetCookieCount(); + extern CookieData Internal_GetCookieData(uint index); + extern void Internal_SetCookieData(uint index, CookieData cookieData); + public CookieData GetCookieData(uint index) + { + if (index >= GetCookieCount()) + throw new ArgumentException($"index must be between 0 and {GetCookieCount() - 1}, but was {index}"); + return Internal_GetCookieData(index); + } + public void SetCookieData(uint index, CookieData cookieData) + { + if (index >= GetCookieCount()) + throw new ArgumentException($"index must be between 0 and {GetCookieCount() - 1}, but was {index}"); + Internal_SetCookieData(index, cookieData); + } + public extern void SetEnvironment(Vector4 color); + public extern void SetEnvironmentFromTextures(TextureData posX, TextureData negX, TextureData posY, TextureData negY, TextureData posZ, TextureData negZ); + public extern TextureData GetEnvironmentCubeTexture(); - void Destroy() - { - if (_ownsPtr && _ptr != IntPtr.Zero) - { - Internal_Destroy(_ptr); - _ptr = IntPtr.Zero; - } - } + internal static class BindingsMarshaller + { + public static IntPtr ConvertToNative(BakeInput bakeInput) => bakeInput._ptr; + } + public extern bool CheckIntegrity(); + } - public extern ulong GetByteSize(); - static extern IntPtr Internal_Create(); - [NativeMethod(IsThreadSafe = true)] - static extern void Internal_Destroy(IntPtr ptr); + [RequiredByNativeCode] + [StructLayout(LayoutKind.Sequential)] + internal class LightProbeRequests : IDisposable + { + private IntPtr _ptr; + private readonly bool _ownsPtr; - public void SetIntegrationRadii(float[] positions) - { - SetIntegrationRadii(positions.AsSpan()); - } - public extern void SetIntegrationRadii(ReadOnlySpan positions); - public extern Vector3[] GetProbePositions(); - public extern float[] GetIntegrationRadii(); - public extern uint lightProbeCount { get; } - public extern ProbeRequest[] GetProbeRequests(); - public extern void SetLightProbeRequests(ProbeRequest[] requests); - - internal static class BindingsMarshaller - { - public static IntPtr ConvertToNative(LightProbeRequests lightProbeRequests) => lightProbeRequests._ptr; - } - public extern bool CheckIntegrity(); + public LightProbeRequests() + { + _ptr = Internal_Create(); + _ownsPtr = true; + } + public LightProbeRequests(IntPtr ptr) + { + _ptr = ptr; + _ownsPtr = false; + } + ~LightProbeRequests() + { + Destroy(); } - [RequiredByNativeCode] - [StructLayout(LayoutKind.Sequential)] - public class LightmapRequests : IDisposable + public void Dispose() { - private IntPtr _ptr; - private readonly bool _ownsPtr; + Destroy(); + GC.SuppressFinalize(this); + } - public LightmapRequests() - { - _ptr = Internal_Create(); - _ownsPtr = true; - } - public LightmapRequests(IntPtr ptr) - { - _ptr = ptr; - _ownsPtr = false; - } - ~LightmapRequests() + void Destroy() + { + if (_ownsPtr && _ptr != IntPtr.Zero) { - Destroy(); + Internal_Destroy(_ptr); + _ptr = IntPtr.Zero; } + } - public void Dispose() - { - Destroy(); - GC.SuppressFinalize(this); - } + public extern ulong GetByteSize(); + static extern IntPtr Internal_Create(); + [NativeMethod(IsThreadSafe = true)] + static extern void Internal_Destroy(IntPtr ptr); - void Destroy() - { - if (_ownsPtr && _ptr != IntPtr.Zero) - { - Internal_Destroy(_ptr); - _ptr = IntPtr.Zero; - } - } + public extern void SetProbePositions(Vector3[] probePositions); + public extern int[] GetOcclusionLightIndices(); + public extern void SetOcclusionLightIndices(int[] probePositions); + public extern Vector3[] GetProbePositions(); + public extern float[] GetIntegrationRadii(); + public void SetIntegrationRadii(float[] positions) + { + SetIntegrationRadii(positions.AsSpan()); + } + public extern void SetIntegrationRadii(ReadOnlySpan positions); + public extern uint lightProbeCount { get; } + public extern ProbeRequest[] GetProbeRequests(); + public extern void SetLightProbeRequests(ProbeRequest[] requests); - public extern ulong GetByteSize(); - static extern IntPtr Internal_Create(); - [NativeMethod(IsThreadSafe = true)] - static extern void Internal_Destroy(IntPtr ptr); + internal static class BindingsMarshaller + { + public static IntPtr ConvertToNative(LightProbeRequests lightProbeRequests) => lightProbeRequests._ptr; + } + public extern bool CheckIntegrity(); + } - public extern LightmapRequest[] GetLightmapRequests(); - public extern void SetLightmapRequests(LightmapRequest[] requests); + [RequiredByNativeCode] + [StructLayout(LayoutKind.Sequential)] + internal class LightmapRequests : IDisposable + { + private IntPtr _ptr; + private readonly bool _ownsPtr; - public uint lightmapInstanceCount(uint index) - { - if (index >= lightmapCount) - throw new ArgumentException($"index must be between 0 and {lightmapCount - 1}, but was {index}"); - return Internal_InstanceCount(index); - } + public LightmapRequests() + { + _ptr = Internal_Create(); + _ownsPtr = true; + } + public LightmapRequests(IntPtr ptr) + { + _ptr = ptr; + _ownsPtr = false; + } + ~LightmapRequests() + { + Destroy(); + } - public extern uint lightmapCount { get; } - extern uint Internal_LightmapWidth(uint index); - extern uint Internal_LightmapHeight(uint index); - extern uint Internal_InstanceCount(uint lightmapIndex); - public extern void SetLightmapResolution(Resolution resolution); - public extern void SetSingleLightmapResolution(uint index, Resolution resolution); - public Resolution lightmapResolution(uint index) - { - if (index >= lightmapCount) - throw new ArgumentException($"index must be between 0 and {lightmapCount - 1}, but was {index}"); - Resolution resolution; - resolution.width = Internal_LightmapWidth(index); - resolution.height = Internal_LightmapHeight(index); - return resolution; - } + public void Dispose() + { + Destroy(); + GC.SuppressFinalize(this); + } - internal static class BindingsMarshaller + void Destroy() + { + if (_ownsPtr && _ptr != IntPtr.Zero) { - public static IntPtr ConvertToNative(LightmapRequests lightmapRequests) => lightmapRequests._ptr; + Internal_Destroy(_ptr); + _ptr = IntPtr.Zero; } - public extern bool CheckIntegrity(); } - [RequiredByNativeCode] - [StructLayout(LayoutKind.Sequential)] - public class DeviceSettings : IDisposable + public extern ulong GetByteSize(); + static extern IntPtr Internal_Create(); + [NativeMethod(IsThreadSafe = true)] + static extern void Internal_Destroy(IntPtr ptr); + + public extern LightmapRequest[] GetLightmapRequests(); + public extern void SetLightmapRequests(LightmapRequest[] requests); + + public uint lightmapInstanceCount(uint index) { - static extern IntPtr Internal_Create(); - [NativeMethod(IsThreadSafe = true)] + if (index >= lightmapCount) + throw new ArgumentException($"index must be between 0 and {lightmapCount - 1}, but was {index}"); + return Internal_InstanceCount(index); + } - public extern bool Initialize(Backend backend); + public extern uint lightmapCount { get; } + extern uint Internal_LightmapWidth(uint index); + extern uint Internal_LightmapHeight(uint index); + extern uint Internal_InstanceCount(uint lightmapIndex); + public extern void SetLightmapResolution(Resolution resolution); + public extern void SetSingleLightmapResolution(uint index, Resolution resolution); + public Resolution lightmapResolution(uint index) + { + if (index >= lightmapCount) + throw new ArgumentException($"index must be between 0 and {lightmapCount - 1}, but was {index}"); + Resolution resolution; + resolution.width = Internal_LightmapWidth(index); + resolution.height = Internal_LightmapHeight(index); + return resolution; + } - [NativeMethod(IsThreadSafe = true)] - static extern void Internal_Destroy(IntPtr ptr); + internal static class BindingsMarshaller + { + public static IntPtr ConvertToNative(LightmapRequests lightmapRequests) => lightmapRequests._ptr; + } + public extern bool CheckIntegrity(); + } - private IntPtr _ptr; - private bool _ownsPtr; + [RequiredByNativeCode] + [StructLayout(LayoutKind.Sequential)] + internal class DeviceSettings : IDisposable + { + static extern IntPtr Internal_Create(); + [NativeMethod(IsThreadSafe = true)] - public DeviceSettings() - { - _ptr = Internal_Create(); - _ownsPtr = true; - } - public DeviceSettings(IntPtr ptr) - { - _ptr = ptr; - _ownsPtr = false; - } - ~DeviceSettings() - { - Destroy(); - } + public extern bool Initialize(Backend backend); - public void Dispose() - { - Destroy(); - GC.SuppressFinalize(this); - } + [NativeMethod(IsThreadSafe = true)] + static extern void Internal_Destroy(IntPtr ptr); - void Destroy() - { - if (_ownsPtr && _ptr != IntPtr.Zero) - { - Internal_Destroy(_ptr); - _ptr = IntPtr.Zero; - } - } + private IntPtr _ptr; + private bool _ownsPtr; + + public DeviceSettings() + { + _ptr = Internal_Create(); + _ownsPtr = true; + } + public DeviceSettings(IntPtr ptr) + { + _ptr = ptr; + _ownsPtr = false; + } + ~DeviceSettings() + { + Destroy(); + } - private extern Backend Internal_GetBackend(); - private extern void Internal_SetBackend(Backend backend); + public void Dispose() + { + Destroy(); + GC.SuppressFinalize(this); + } - internal Backend _backend + void Destroy() + { + if (_ownsPtr && _ptr != IntPtr.Zero) { - get => Internal_GetBackend(); - set => Internal_SetBackend(value); + Internal_Destroy(_ptr); + _ptr = IntPtr.Zero; } + } - internal static class BindingsMarshaller - { - public static IntPtr ConvertToNative(DeviceSettings obj) => obj._ptr; - } + private extern Backend Internal_GetBackend(); + private extern void Internal_SetBackend(Backend backend); + + internal Backend _backend + { + get => Internal_GetBackend(); + set => Internal_SetBackend(value); } + internal static class BindingsMarshaller + { + public static IntPtr ConvertToNative(DeviceSettings obj) => obj._ptr; + } + } + [NativeHeader("Editor/Src/GI/LightBaker/LightBaker.Bindings.h")] + [StaticAccessor("LightBakerBindings", StaticAccessorType.DoubleColon)] + internal static partial class LightBaker + { public static Result PopulateWorld(BakeInput bakeInput, LightmapRequests lightmapRequests, LightProbeRequests lightProbeRequests, BakeProgressState progress, UnityEngine.LightTransport.IDeviceContext context, UnityEngine.LightTransport.IWorld world) { - Result result = new (); + Result result = new(); if (context is RadeonRaysContext radeonRaysContext) { - IntegrationContext integrationContext = new (); + IntegrationContext integrationContext = new(); result = PopulateWorldRadeonRays(bakeInput, lightmapRequests, lightProbeRequests, progress, radeonRaysContext, integrationContext); Debug.Assert(world is RadeonRaysWorld); var rrWorld = world as RadeonRaysWorld; @@ -846,7 +852,7 @@ public static Result PopulateWorld(BakeInput bakeInput, LightmapRequests lightma } else if (context is WintermuteContext wintermuteContext) { - IntegrationContext integrationContext = new (); + IntegrationContext integrationContext = new(); result = PopulateWorldWintermute(bakeInput, lightmapRequests, lightProbeRequests, progress, wintermuteContext, integrationContext); Debug.Assert(world is WintermuteWorld); var wmWorld = world as WintermuteWorld; diff --git a/Editor/Mono/GI/Lightmapping.bindings.cs b/Editor/Mono/GI/Lightmapping.bindings.cs index aea32b2be7..111cdda85a 100644 --- a/Editor/Mono/GI/Lightmapping.bindings.cs +++ b/Editor/Mono/GI/Lightmapping.bindings.cs @@ -3,6 +3,7 @@ // https://unity3d.com/legal/licenses/Unity_Reference_Only_License using System; +using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; using UnityEditor.SceneManagement; @@ -12,8 +13,12 @@ using Scene = UnityEngine.SceneManagement.Scene; using NativeArrayUnsafeUtility = Unity.Collections.LowLevel.Unsafe.NativeArrayUnsafeUtility; using Unity.Collections; +using Unity.Scripting.LifecycleManagement; using UnityEditor.LightBaking; using UnityEngine.Rendering; +using Light = UnityEngine.Light; +using LightingSettings = UnityEngine.LightingSettings; +using Terrain = UnityEngine.Terrain; namespace UnityEditor { @@ -145,6 +150,7 @@ public static float bounceBoost get { return GetLightingSettingsOrDefaultsFallback().albedoBoost; } set { GetOrCreateLightingsSettings().albedoBoost = value; } } + internal static bool UnifiedBaker { get; set; } = false; [RequiredByNativeCode] internal static bool ShouldBakeInteractively() @@ -365,15 +371,15 @@ internal static void Internal_CallOnWroteLightingDataAsset() // This event is fired when BakeInput has been populated, but before passing it to Bake(). // Do not store and access BakeInput beyond the call-back. - internal static event Action createdBakeInput; + internal static event Action createdBakeInput; internal static void Internal_CallOnCreatedBakeInput(IntPtr p_BakeInput, IntPtr p_LightmapRequests, IntPtr LightProbeRequests, IntPtr p_SourceMap) { if (createdBakeInput != null) { - using var bakeInput = new LightBaker.BakeInput(p_BakeInput); - using var lightmapRequests = new LightBaker.LightmapRequests(p_LightmapRequests); - using var lightProbeRequests = new LightBaker.LightProbeRequests(LightProbeRequests); + using var bakeInput = new BakeInput(p_BakeInput); + using var lightmapRequests = new LightmapRequests(p_LightmapRequests); + using var lightProbeRequests = new LightProbeRequests(LightProbeRequests); using var sourceMap = new InputExtraction.SourceMap(p_SourceMap); createdBakeInput(bakeInput, lightmapRequests, lightProbeRequests, sourceMap); } @@ -413,6 +419,30 @@ private static void Internal_CallBakeAnalyticsFunctions(string analytics) bakeAnalytics(analytics); } + public delegate void InputExtractionFunction(UnityEngine.LightTransport.InputExtraction.BakeInput bakeInput); + + [AutoStaticsCleanupOnCodeReload] + public static event InputExtractionFunction inputExtraction; + + [RequiredByNativeCode] + private static void Internal_CallInputExtractionFunctions(IntPtr p_BakeInput, IntPtr p_LightmapRequests, IntPtr LightProbeRequests, IntPtr p_PostProcessRequests) + { + if (inputExtraction != null) + { + using var lightBakerBakeInput = new UnityEditor.LightBaking.BakeInput(p_BakeInput); + using var lightmapRequests = new UnityEditor.LightBaking.LightmapRequests(p_LightmapRequests); + using var lightProbeRequests = new UnityEditor.LightBaking.LightProbeRequests(LightProbeRequests); + var postProcessRequests = new UnityEditor.LightBaking.PostProcessRequests(p_PostProcessRequests); + + var wrappedBakeInput = new UnityEngine.LightTransport.InputExtraction.BakeInput(lightBakerBakeInput); + wrappedBakeInput.lightmapRequests = lightmapRequests; + wrappedBakeInput.lightProbeRequests = lightProbeRequests; + wrappedBakeInput.postProcessRequests = postProcessRequests; + + inputExtraction(wrappedBakeInput); + } + } + // Returns the progress of a build when the bake job is running, returns 0 when no bake job is running. public static extern float buildProgress {[FreeFunction] get; } @@ -668,6 +698,14 @@ public static void BakeMultipleScenes(string[] paths) [RequiredByNativeCode] public static void SetAdditionalBakeDelegate(AdditionalBakeDelegate del) { s_AdditionalBakeDelegate = del != null ? del : s_DefaultAdditionalBakeDelegate; } + public delegate void BakeDelegate(ref float progress, out bool done, UnityEngine.LightTransport.InputExtraction.BakeInput bakeInput); + + [RequiredByNativeCode] + public static void AddBakeDelegate(BakeDelegate del) => s_BakeDelegates.Add(del); + + [RequiredByNativeCode] + public static void RemoveBakeDelegate(BakeDelegate del) => s_BakeDelegates.RemoveAll(d => d.GetHashCode() == del.GetHashCode()); + [RequiredByNativeCode] public static AdditionalBakeDelegate GetAdditionalBakeDelegate() { return s_AdditionalBakeDelegate; } @@ -680,6 +718,31 @@ internal static void AdditionalBake(ref float progress, ref bool done) s_AdditionalBakeDelegate(ref progress, ref done); } + // We want to control the order of delegate invocations, and we want to explicitly provide the logic for handling each delegate's potential change of ref values + // - done is true iff all delegates return true + // - progress is the reported progress by delegates, averaged + [RequiredByNativeCode] + private static void Internal_CallBakeWithBakeInputFunctions(ref float progress, out bool done, IntPtr pBakeInput) + { + bool retVal = true; + List bakeDelegates = new() { }; // A copy of the list which will not be modified during iteration, whereas s_BakeDelegates could be modified during iteration + bakeDelegates.AddRange(s_BakeDelegates); + float progressSum = 0.0f; + foreach (BakeDelegate bakeDelegate in bakeDelegates) + { + using var lightBakerBakeInput = new UnityEditor.LightBaking.BakeInput(pBakeInput); + + var wrappedBakeInput = new UnityEngine.LightTransport.InputExtraction.BakeInput(lightBakerBakeInput); + float progressValue = 0.0f; + bakeDelegate(ref progressValue, out bool thisDelegateIsDone, wrappedBakeInput); + progressSum += progressValue; + retVal = retVal && thisDelegateIsDone; + } + if (bakeDelegates.Count > 0) + progress = progressSum / bakeDelegates.Count; + done = retVal; + } + [RequiredByNativeCode] private static readonly AdditionalBakeDelegate s_DefaultAdditionalBakeDelegate = (ref float progress, ref bool done) => { @@ -688,6 +751,9 @@ internal static void AdditionalBake(ref float progress, ref bool done) }; [RequiredByNativeCode] private static AdditionalBakeDelegate s_AdditionalBakeDelegate = s_DefaultAdditionalBakeDelegate; + [RequiredByNativeCode] + [AutoStaticsCleanupOnCodeReload] + private static List s_BakeDelegates = new() { }; } } diff --git a/Editor/Mono/GI/ProbeIntegrator.bindings.cs b/Editor/Mono/GI/ProbeIntegrator.bindings.cs index a09b927310..dfd0b6da35 100644 --- a/Editor/Mono/GI/ProbeIntegrator.bindings.cs +++ b/Editor/Mono/GI/ProbeIntegrator.bindings.cs @@ -100,7 +100,7 @@ public unsafe IProbeIntegrator.Result IntegrateDirectRadiance(IDeviceContext con _bounceCount, directSampleCount, giSampleCount, envSampleCount, ignoreDirectEnvironment, ignoreIndirectEnvironment, wmContext, _progress, shPtr); // TODO: Fix this in LIGHT-1479, synchronization and read-back should be done by the user. - if (lightBakerResult.type != LightBaker.ResultType.Success) + if (lightBakerResult.type != ResultType.Success) return lightBakerResult.ConvertToIProbeIntegratorResult(); eventId = context.CreateEvent(); @@ -109,7 +109,7 @@ public unsafe IProbeIntegrator.Result IntegrateDirectRadiance(IDeviceContext con Debug.Assert(waitResult, "Failed to write radiance to context."); context.DestroyEvent(eventId); if (!waitResult) - lightBakerResult = new LightBaker.Result {type = LightBaker.ResultType.IOFailed, message = "Failed to write radiance to context."}; + lightBakerResult = new Result {type = ResultType.IOFailed, message = "Failed to write radiance to context."}; return lightBakerResult.ConvertToIProbeIntegratorResult(); } @@ -139,7 +139,7 @@ public unsafe IProbeIntegrator.Result IntegrateIndirectRadiance(IDeviceContext c _bounceCount, directSampleCount, giSampleCount, envSampleCount, ignoreDirectEnvironment, ignoreIndirectEnvironment, wmContext, _progress, shPtr); // TODO: Fix this in LIGHT-1479, synchronization and read-back should be done by the user. - if (lightBakerResult.type != LightBaker.ResultType.Success) + if (lightBakerResult.type != ResultType.Success) return lightBakerResult.ConvertToIProbeIntegratorResult(); eventId = context.CreateEvent(); @@ -148,7 +148,7 @@ public unsafe IProbeIntegrator.Result IntegrateIndirectRadiance(IDeviceContext c Debug.Assert(waitResult, "Failed to write radiance to context."); context.DestroyEvent(eventId); if (!waitResult) - lightBakerResult = new LightBaker.Result {type = LightBaker.ResultType.IOFailed, message = "Failed to write radiance to context."}; + lightBakerResult = new Result {type = ResultType.IOFailed, message = "Failed to write radiance to context."}; return lightBakerResult.ConvertToIProbeIntegratorResult(); } @@ -175,7 +175,7 @@ public unsafe IProbeIntegrator.Result IntegrateValidity(IDeviceContext context, _bounceCount, directSampleCount, giSampleCount, envSampleCount, wmContext, _progress, validityPtr); // TODO: Fix this in LIGHT-1479, synchronization and read-back should be done by the user. - if (lightBakerResult.type != LightBaker.ResultType.Success) + if (lightBakerResult.type != ResultType.Success) return lightBakerResult.ConvertToIProbeIntegratorResult(); eventId = context.CreateEvent(); @@ -184,7 +184,7 @@ public unsafe IProbeIntegrator.Result IntegrateValidity(IDeviceContext context, Debug.Assert(waitResult, "Failed to write validity to context."); context.DestroyEvent(eventId); if (!waitResult) - lightBakerResult = new LightBaker.Result {type = LightBaker.ResultType.IOFailed, message = "Failed to write validity to context."}; + lightBakerResult = new Result {type = ResultType.IOFailed, message = "Failed to write validity to context."}; return lightBakerResult.ConvertToIProbeIntegratorResult(); } @@ -222,7 +222,7 @@ public unsafe IProbeIntegrator.Result IntegrateOcclusion(IDeviceContext context, _pushoff, _bounceCount, directSampleCount, giSampleCount, envSampleCount, wmContext, _progress, occlusionPtr); // TODO: Fix this in LIGHT-1479, synchronization and read-back should be done by the user. - if (lightBakerResult.type != LightBaker.ResultType.Success) + if (lightBakerResult.type != ResultType.Success) return lightBakerResult.ConvertToIProbeIntegratorResult(); eventId = context.CreateEvent(); @@ -231,7 +231,7 @@ public unsafe IProbeIntegrator.Result IntegrateOcclusion(IDeviceContext context, Debug.Assert(waitResult, "Failed to write validity to context."); context.DestroyEvent(eventId); if (!waitResult) - lightBakerResult = new LightBaker.Result { type = LightBaker.ResultType.IOFailed, message = "Failed to write validity to context." }; + lightBakerResult = new Result { type = ResultType.IOFailed, message = "Failed to write validity to context." }; return lightBakerResult.ConvertToIProbeIntegratorResult(); } @@ -288,7 +288,7 @@ public unsafe IProbeIntegrator.Result IntegrateDirectRadiance(IDeviceContext con _bounceCount, directSampleCount, giSampleCount, envSampleCount, ignoreDirectEnvironment, ignoreIndirectEnvironment, rrContext, _progress, shPtr); // TODO: Fix this in LIGHT-1479, synchronization and read-back should be done by the user. - if (lightBakerResult.type != LightBaker.ResultType.Success) + if (lightBakerResult.type != ResultType.Success) return lightBakerResult.ConvertToIProbeIntegratorResult(); eventId = context.CreateEvent(); @@ -297,7 +297,7 @@ public unsafe IProbeIntegrator.Result IntegrateDirectRadiance(IDeviceContext con Debug.Assert(waitResult, "Failed to write radiance to context."); context.DestroyEvent(eventId); if (!waitResult) - lightBakerResult = new LightBaker.Result {type = LightBaker.ResultType.IOFailed, message = "Failed to write radiance to context."}; + lightBakerResult = new Result { type = ResultType.IOFailed, message = "Failed to write radiance to context." }; return lightBakerResult.ConvertToIProbeIntegratorResult(); } @@ -327,7 +327,7 @@ public unsafe IProbeIntegrator.Result IntegrateIndirectRadiance(IDeviceContext c _bounceCount, directSampleCount, giSampleCount, envSampleCount, ignoreDirectEnvironment, ignoreIndirectEnvironment, rrContext, _progress, shPtr); // TODO: Fix this in LIGHT-1479, synchronization and read-back should be done by the user. - if (lightBakerResult.type != LightBaker.ResultType.Success) + if (lightBakerResult.type != ResultType.Success) return lightBakerResult.ConvertToIProbeIntegratorResult(); eventId = context.CreateEvent(); @@ -336,7 +336,7 @@ public unsafe IProbeIntegrator.Result IntegrateIndirectRadiance(IDeviceContext c Debug.Assert(waitResult, "Failed to write radiance to context."); context.DestroyEvent(eventId); if (!waitResult) - lightBakerResult = new LightBaker.Result {type = LightBaker.ResultType.IOFailed, message = "Failed to write radiance to context."}; + lightBakerResult = new Result { type = ResultType.IOFailed, message = "Failed to write radiance to context." }; return lightBakerResult.ConvertToIProbeIntegratorResult(); } @@ -363,7 +363,7 @@ public unsafe IProbeIntegrator.Result IntegrateValidity(IDeviceContext context, _bounceCount, directSampleCount, giSampleCount, envSampleCount, rrContext, _progress, validityPtr); // TODO: Fix this in LIGHT-1479, synchronization and read-back should be done by the user. - if (lightBakerResult.type != LightBaker.ResultType.Success) + if (lightBakerResult.type != ResultType.Success) return lightBakerResult.ConvertToIProbeIntegratorResult(); eventId = context.CreateEvent(); @@ -372,7 +372,7 @@ public unsafe IProbeIntegrator.Result IntegrateValidity(IDeviceContext context, Debug.Assert(waitResult, "Failed to write validity to context."); context.DestroyEvent(eventId); if (!waitResult) - lightBakerResult = new LightBaker.Result {type = LightBaker.ResultType.IOFailed, message = "Failed to write validity to context."}; + lightBakerResult = new Result { type = ResultType.IOFailed, message = "Failed to write validity to context." }; return lightBakerResult.ConvertToIProbeIntegratorResult(); } @@ -409,7 +409,7 @@ public unsafe IProbeIntegrator.Result IntegrateOcclusion(IDeviceContext context, var lightBakerResult = LightBaker.IntegrateProbeOcclusionRadeonRays(positionsPtr, perProbeLightIndicesPtr, positionCount, _pushoff, _bounceCount, directSampleCount, giSampleCount, envSampleCount, rrContext, _progress, occlusionPtr); - if (lightBakerResult.type != LightBaker.ResultType.Success) + if (lightBakerResult.type != ResultType.Success) return lightBakerResult.ConvertToIProbeIntegratorResult(); eventId = context.CreateEvent(); @@ -419,7 +419,7 @@ public unsafe IProbeIntegrator.Result IntegrateOcclusion(IDeviceContext context, Debug.Assert(waitResult, "Failed to write validity to context."); context.DestroyEvent(eventId); if (!waitResult) - lightBakerResult = new LightBaker.Result { type = LightBaker.ResultType.IOFailed, message = "Failed to write validity to context." }; + lightBakerResult = new Result { type = ResultType.IOFailed, message = "Failed to write validity to context." }; return lightBakerResult.ConvertToIProbeIntegratorResult(); } diff --git a/Editor/Mono/GUI/AboutWindow.cs b/Editor/Mono/GUI/AboutWindow.cs index 6040e802c2..48f34935e3 100644 --- a/Editor/Mono/GUI/AboutWindow.cs +++ b/Editor/Mono/GUI/AboutWindow.cs @@ -13,21 +13,34 @@ namespace UnityEditor { internal class AboutWindow : EditorWindow { - const int VersionBoxLineHeight = 13; - const int VersionBoxHeight = VersionBoxLineHeight * 4; - static readonly Vector2 WindowSize = new Vector2(573, 545); - private const string AboutTitle = ""; + // s_Instance is nulled when the window is closed (OnDestroy) + static AboutWindow s_Instance; [RequiredByNativeCode] internal static void ShowAboutWindow() { + // UUM-92333 HACK: In order for position to be correct, we need to close the existing instance + // Otherwise, the new instance will open with the wrong sizing. + s_Instance?.Close(); + var mainWindowRect = EditorGUIUtility.GetMainWindowPosition(); - var aboutRect = EditorGUIUtility.GetCenteredWindowPosition(mainWindowRect, WindowSize); + var aboutRect = EditorGUIUtility.GetCenteredWindowPosition(mainWindowRect, new Vector2(573, 545)); + + // UUM-92333 HACK: Clear any stored window position so that we always open in the center of the main window + // If not, we run the risk of opening the about window at the wrong size if the main window was moved or resized between monitor setups + var key = typeof(AboutWindow).ToString(); - AboutWindow w = GetWindowWithRect(aboutRect, true, AboutTitle); + EditorPrefs.DeleteKey(key + "x"); + EditorPrefs.DeleteKey(key + "y"); + EditorPrefs.DeleteKey(key + "w"); + EditorPrefs.DeleteKey(key + "h"); + EditorPrefs.DeleteKey(key + "z"); + + AboutWindow w = GetWindow(utility: true, title: string.Empty); w.position = aboutRect; - w.minSize = w.maxSize = WindowSize; - w.m_Parent.window.m_DontSaveToLayout = true; + w.minSize = w.maxSize = w.position.size; + + s_Instance = w; } bool m_ShowDetailedVersion = false; diff --git a/Editor/Mono/GUI/AssetPopupBackend.cs b/Editor/Mono/GUI/AssetPopupBackend.cs index 380b4cb748..ccc34dac63 100644 --- a/Editor/Mono/GUI/AssetPopupBackend.cs +++ b/Editor/Mono/GUI/AssetPopupBackend.cs @@ -75,7 +75,7 @@ public override void Cancelled(int instanceId, string pathName, string resourceF { GenericMenu gm = new GenericMenu(); - int selectedInstanceID = serializedProperty.objectReferenceValue != null ? serializedProperty.objectReferenceValue.GetInstanceID() : 0; + EntityId selectedEntityId = serializedProperty.objectReferenceValue != null ? serializedProperty.objectReferenceValue.GetEntityId() : EntityId.None; bool foundDefaultAsset = false; @@ -91,7 +91,7 @@ public override void Cancelled(int instanceId, string pathName, string resourceF { if (resource.m_Name == defaultFieldName) { - gm.AddItem(new GUIContent(resource.m_Name), resource.m_EntityId == selectedInstanceID, AssetPopupMenuCallback, new object[] { resource.m_EntityId, serializedProperty }); + gm.AddItem(new GUIContent(resource.m_Name), resource.m_EntityId == selectedEntityId, AssetPopupMenuCallback, new object[] { resource.m_EntityId, serializedProperty }); resourceList = resourceList.Where(x => x != resource).ToArray(); foundDefaultAsset = true; break; @@ -102,13 +102,13 @@ public override void Cancelled(int instanceId, string pathName, string resourceF // If no defalut asset was found, add defualt null value. if (!foundDefaultAsset) { - gm.AddItem(new GUIContent(defaultFieldName), selectedInstanceID == 0, AssetPopupMenuCallback, new object[] { 0, serializedProperty }); + gm.AddItem(new GUIContent(defaultFieldName), selectedEntityId == 0, AssetPopupMenuCallback, new object[] { EntityId.None, serializedProperty }); } // Add items from asset database foreach (var property in AssetDatabase.FindAllAssets(new SearchFilter() { classNames = new[] { typeName } })) { - gm.AddItem(new GUIContent(property.name), property.entityId == selectedInstanceID, AssetPopupMenuCallback, new object[] { property.entityId, serializedProperty }); + gm.AddItem(new GUIContent(property.name), property.entityId == selectedEntityId, AssetPopupMenuCallback, new object[] { property.entityId, serializedProperty }); } // Add builtin items, except for the already added default item. @@ -116,7 +116,7 @@ public override void Cancelled(int instanceId, string pathName, string resourceF { foreach (var resource in resourceList) { - gm.AddItem(new GUIContent(resource.m_Name), resource.m_EntityId == selectedInstanceID, AssetPopupMenuCallback, new object[] { resource.m_EntityId, serializedProperty }); + gm.AddItem(new GUIContent(resource.m_Name), resource.m_EntityId == selectedEntityId, AssetPopupMenuCallback, new object[] { resource.m_EntityId, serializedProperty }); } } @@ -148,7 +148,7 @@ public override void Cancelled(int instanceId, string pathName, string resourceF static void AssetPopupMenuCallback(object userData) { var data = userData as object[]; - var instanceID = (int)data[0]; + var instanceID = (EntityId)data[0]; var serializedProperty = (SerializedProperty)data[1]; serializedProperty.objectReferenceValue = EditorUtility.EntityIdToObject(instanceID); diff --git a/Editor/Mono/GUI/ColorPicker.cs b/Editor/Mono/GUI/ColorPicker.cs index ef7afc8a6c..5fae01cf69 100644 --- a/Editor/Mono/GUI/ColorPicker.cs +++ b/Editor/Mono/GUI/ColorPicker.cs @@ -1401,8 +1401,8 @@ public static Color GetLastPickedColor() return s_LastPickedColor; } - public static bool IsOpened => s_Instance?.m_IsOpened == true; - public static bool IsCancelled => s_Instance?.m_IsCancelled == true; + public static bool IsOpened => s_Instance != null && s_Instance.m_IsOpened; + public static bool IsCancelled => s_Instance != null && s_Instance.m_IsCancelled; static class Styles { diff --git a/Editor/Mono/GUI/PackageImportTreeView.cs b/Editor/Mono/GUI/PackageImportTreeView.cs index 40a9b5fcb7..a670032afd 100644 --- a/Editor/Mono/GUI/PackageImportTreeView.cs +++ b/Editor/Mono/GUI/PackageImportTreeView.cs @@ -532,10 +532,6 @@ void DoPreviewPopup(PackageImportTreeViewItem pitem, Rect rowRect) if (item != null) { - // Ensure preview is shown when clicking on an already selected item (the preview might have been closed) - if (Event.current.type == EventType.MouseDown && rowRect.Contains(Event.current.mousePosition) && !PopupWindowWithoutFocus.IsVisible()) - showPreviewForID = pitem.id; - // Show preview if (pitem.id == showPreviewForID && Event.current.type != EventType.Layout) { diff --git a/Editor/Mono/GUI/Toolbars/Toolbar.cs b/Editor/Mono/GUI/Toolbars/Toolbar.cs index a2455b998d..97caa9d2aa 100644 --- a/Editor/Mono/GUI/Toolbars/Toolbar.cs +++ b/Editor/Mono/GUI/Toolbars/Toolbar.cs @@ -255,7 +255,7 @@ partial class Toolbar : HostView public const float ToolbarHeight = 36f; internal static Toolbar instance => s_Instance; - internal const string k_MainToolbarAPIDocumentationLink = "https://docs.unity3d.com/ScriptingReference/Toolbars.MainToolbar.html"; + internal static readonly string k_MainToolbarAPIDocumentationLink = $"https://docs.unity3d.com/{Application.unityVersionVer}.{Application.unityVersionMaj}/Documentation/ScriptReference/Toolbars.MainToolbar.html"; Toolbar() { diff --git a/Editor/Mono/GUI/TreeView/AssetsTreeViewGUI.cs b/Editor/Mono/GUI/TreeView/AssetsTreeViewGUI.cs index 63d6d2b8e4..b2ddcc5118 100644 --- a/Editor/Mono/GUI/TreeView/AssetsTreeViewGUI.cs +++ b/Editor/Mono/GUI/TreeView/AssetsTreeViewGUI.cs @@ -66,7 +66,7 @@ public AssetsTreeViewGUI(TreeViewController treeView) override public void BeginRowGUI() { s_VCEnabled = VersionControlUtils.isVersionControlConnected; - iconLeftPadding = iconRightPadding = s_VCEnabled ? k_IconOverlayPadding : 0f; + iconLeftPadding = iconRightPadding = 0f; base.BeginRowGUI(); } diff --git a/Editor/Mono/GameObjectUtility.bindings.cs b/Editor/Mono/GameObjectUtility.bindings.cs index 1c38577ce6..639532da93 100644 --- a/Editor/Mono/GameObjectUtility.bindings.cs +++ b/Editor/Mono/GameObjectUtility.bindings.cs @@ -2,11 +2,11 @@ // Copyright (c) Unity Technologies. For terms of use, see // https://unity3d.com/legal/licenses/Unity_Reference_Only_License -using System.Collections.Generic; -using System.Linq; +using System; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.Bindings; +using Object = UnityEngine.Object; namespace UnityEditor { @@ -48,11 +48,6 @@ internal static bool ContainsMainStageGameObjects(GameObject[] objects) return false; } - internal static bool HasChildren(IEnumerable gameObjects) - { - return gameObjects.Any(go => go.transform.childCount > 0); - } - internal enum ShouldIncludeChildren { HasNoChildren = -1, @@ -61,12 +56,30 @@ internal enum ShouldIncludeChildren Cancel = 2 } - internal static ShouldIncludeChildren DisplayUpdateChildrenDialogIfNeeded(IEnumerable gameObjects, - string title, string message) + internal static bool HasChildren(ReadOnlySpan objects) + { + foreach (var o in objects) + { + if (o is GameObject go && go && go.transform.childCount > 0) + return true; + } + + return false; + } + + internal static bool HasChildren(ReadOnlySpan gameObjects) { - if (!HasChildren(gameObjects)) - return ShouldIncludeChildren.HasNoChildren; + foreach (var go in gameObjects) + { + if (go && go.transform.childCount > 0) + return true; + } + return false; + } + + internal static ShouldIncludeChildren DisplayUpdateChildrenDialog(string title, string message) + { var result = EditorDialog.DisplayComplexDecisionDialog( title, message, diff --git a/Editor/Mono/GenerateIconsWithMipLevels.cs b/Editor/Mono/GenerateIconsWithMipLevels.cs index 7d1e83cf74..08db889e4f 100644 --- a/Editor/Mono/GenerateIconsWithMipLevels.cs +++ b/Editor/Mono/GenerateIconsWithMipLevels.cs @@ -69,7 +69,7 @@ private static InputData GetInputData() }; } - // Called from BuildEditorAssetBundles + // Called from BuildEditorResources [RequiredByNativeCode] public static void GenerateAllIconsWithMipLevels() { diff --git a/Editor/Mono/GlobalObjectId.bindings.cs b/Editor/Mono/GlobalObjectId.bindings.cs index aceae1730b..ea6c451f4c 100644 --- a/Editor/Mono/GlobalObjectId.bindings.cs +++ b/Editor/Mono/GlobalObjectId.bindings.cs @@ -120,9 +120,16 @@ public static bool TryParse(string stringValue, out GlobalObjectId id) // Converting one object at a time is incredibly slow. (Have to iterate whole scene to grab one object...) // Always prefer using batch API when multiple objects need to be looked up. - [FreeFunction] - extern public static int GlobalObjectIdentifierToInstanceIDSlow(GlobalObjectId id); + [Obsolete("GlobalObjectIdentifierToInstanceIDSlow is obsolete. Use GlobalObjectIdentifierToEntityIdSlow instead.")] + public static int GlobalObjectIdentifierToInstanceIDSlow(GlobalObjectId id) => GlobalObjectIdentifierToEntityIdSlow(id); + [Obsolete("GlobalObjectIdentifiersToInstanceIDsSlow is obsolete. Use GlobalObjectIdentifiersToEntityIdsSlow instead.")] [FreeFunction] extern public static void GlobalObjectIdentifiersToInstanceIDsSlow(GlobalObjectId[] identifiers, [Out] int[] outputInstanceIDs); + + [FreeFunction] + extern public static EntityId GlobalObjectIdentifierToEntityIdSlow(GlobalObjectId id); + [FreeFunction] + extern public static void GlobalObjectIdentifiersToEntityIdsSlow(GlobalObjectId[] identifiers, [Out] EntityId[] outputEntityIds); + } } diff --git a/Editor/Mono/Handles/HandleUtility.cs b/Editor/Mono/Handles/HandleUtility.cs index 34892d9e90..aaf862fa72 100644 --- a/Editor/Mono/Handles/HandleUtility.cs +++ b/Editor/Mono/Handles/HandleUtility.cs @@ -1226,7 +1226,7 @@ internal static PickingObject PickObject(Vector2 guiPosition, } else { - // If isEntity is false, then pickingID stores the object instanceID. + // If isEntity is false, then pickingID stores the object EntityId. EntityId entityId = EntityId.From(pickingID); pickedObject = EditorUtility.EntityIdToObject(entityId); } @@ -1932,30 +1932,30 @@ static bool TryGetPlane(out Plane plane) return false; } - internal static void FilterRendererIDs(Renderer[] renderers, out int[] parentRendererIDs, out int[] childRendererIDs) + internal static void FilterRendererIDs(Renderer[] renderers, out EntityId[] parentRendererIDs, out EntityId[] childRendererIDs) { if (renderers == null) { Debug.LogWarning("The Renderer array is null. Handles.DrawOutline will not be rendered."); - parentRendererIDs = new int[0]; - childRendererIDs = new int[0]; + parentRendererIDs = new EntityId[0]; + childRendererIDs = new EntityId[0]; return; } var parentIndex = 0; - parentRendererIDs = new int[renderers.Length]; + parentRendererIDs = new EntityId[renderers.Length]; foreach (var renderer in renderers) - parentRendererIDs[parentIndex++] = renderer.GetInstanceID(); + parentRendererIDs[parentIndex++] = renderer.GetEntityId(); - var tempChildRendererIDs = new HashSet(); + var tempChildRendererIDs = new HashSet(); foreach (var renderer in renderers) { var children = renderer.GetComponentsInChildren(); for (int i = 1; i < children.Length; i++) { - var id = children[i].GetInstanceID(); - if (!HasMatchingInstanceID(parentRendererIDs, id, parentIndex)) + var id = children[i].GetEntityId(); + if (!HasMatchingEntityId(parentRendererIDs, id, parentIndex)) tempChildRendererIDs.Add(id); } } @@ -1963,44 +1963,44 @@ internal static void FilterRendererIDs(Renderer[] renderers, out int[] parentRen childRendererIDs = tempChildRendererIDs.ToArray(); } - internal static void FilterInstanceIDs(IEnumerable gameObjects, out int[] parentInstanceIDs, out int[] childInstanceIDs, out HashSet childInstanceIDsHashSet) + internal static void FilterEntityIds(IEnumerable gameObjects, out EntityId[] parentEntityIds, out EntityId[] childEntityIds, out HashSet childEntityIdsHashSet) { if (gameObjects.Count() == 0) { - parentInstanceIDs = new int[0]; - childInstanceIDs = new int[0]; - childInstanceIDsHashSet = null; + parentEntityIds = new EntityId[0]; + childEntityIds = new EntityId[0]; + childEntityIdsHashSet = null; return; } - var tempParentInstanceIDs = new HashSet(); + var tempParentEntityIds = new HashSet(); foreach (var go in gameObjects) { if (go.TryGetComponent(out Renderer renderer)) - tempParentInstanceIDs.Add(renderer.GetInstanceID()); + tempParentEntityIds.Add(renderer.GetEntityId()); else if (go.TryGetComponent(out Terrain terrain)) - tempParentInstanceIDs.Add(terrain.GetInstanceID()); - // Render commands from the Graphics API can use the gameobject instance ID for selection and outline rendering - tempParentInstanceIDs.Add(go.GetInstanceID()); + tempParentEntityIds.Add(terrain.GetEntityId()); + // Render commands from the Graphics API can use the gameobject entity ID for selection and outline rendering + tempParentEntityIds.Add(go.GetEntityId()); } - childInstanceIDsHashSet = new HashSet(); + childEntityIdsHashSet = new HashSet(); foreach (var go in gameObjects) { var childRenderers = go.GetComponentsInChildren(); for (int i = 0; i < childRenderers.Length; i++) { - var id = childRenderers[i].GetInstanceID(); - if (!tempParentInstanceIDs.Contains(id)) - childInstanceIDsHashSet.Add(id); + var id = childRenderers[i].GetEntityId(); + if (!tempParentEntityIds.Contains(id)) + childEntityIdsHashSet.Add(id); } var childTerrains = go.GetComponentsInChildren(); for (int i = 0; i < childTerrains.Length; i++) { - var id = childTerrains[i].GetInstanceID(); - if (!tempParentInstanceIDs.Contains(id)) - childInstanceIDsHashSet.Add(id); + var id = childTerrains[i].GetEntityId(); + if (!tempParentEntityIds.Contains(id)) + childEntityIdsHashSet.Add(id); } // Script components can issue Render commands that are rendered in the outline so we need to take that in account @@ -2010,17 +2010,17 @@ internal static void FilterInstanceIDs(IEnumerable gameObjects, out var script = userScriptObjects[i]; if (script == null) continue; - var id = script.gameObject.GetInstanceID(); - if (!tempParentInstanceIDs.Contains(id)) - childInstanceIDsHashSet.Add(id); + var id = script.gameObject.GetEntityId(); + if (!tempParentEntityIds.Contains(id)) + childEntityIdsHashSet.Add(id); } } - parentInstanceIDs = tempParentInstanceIDs.ToArray(); - childInstanceIDs = childInstanceIDsHashSet.ToArray(); + parentEntityIds = tempParentEntityIds.ToArray(); + childEntityIds = childEntityIdsHashSet.ToArray(); } - static bool HasMatchingInstanceID(int[] ids, int id, int cutoff) + static bool HasMatchingEntityId(EntityId[] ids, EntityId id, int cutoff) { for (int i = 0; i < ids.Length; i++) { @@ -2154,7 +2154,7 @@ static bool DoRenderPicking(int pickingIndex) } [RequiredByNativeCode] - static int ResolvePickingObject(int pickingIndex, Vector3 worldPos, float depth) + static void ResolvePickingObject(int pickingIndex, Vector3 worldPos, float depth, out EntityId result) { foreach (var (begin, end, resolver, resolverWithWorldPos) in s_RenderPickingResults) { @@ -2162,10 +2162,12 @@ static int ResolvePickingObject(int pickingIndex, Vector3 worldPos, float depth) { Debug.Assert((resolver == null) != (resolverWithWorldPos == null)); var obj = resolver != null ? resolver(pickingIndex - begin) : resolverWithWorldPos(pickingIndex - begin, worldPos, depth); - return obj != null ? obj.GetInstanceID() : 0; + result = obj != null ? obj.GetEntityId() : EntityId.None; + return; } } - return 0; + + result = EntityId.None; } [RequiredByNativeCode] diff --git a/Editor/Mono/Handles/Handles.cs b/Editor/Mono/Handles/Handles.cs index 5f38aed537..9dffcd8160 100644 --- a/Editor/Mono/Handles/Handles.cs +++ b/Editor/Mono/Handles/Handles.cs @@ -1452,20 +1452,26 @@ public static Vector2 GetMainGameViewSize() return PlayModeView.GetMainPlayModeViewTargetSize(); } + [Obsolete("Deprecated. Use DrawOutline(EntityId[], EntityId[], Color, Color, float) instead.")] public static void DrawOutline(int[] parentRenderers, int[] childRenderers, Color parentNodeColor, Color childNodeColor, float fillOpacity = 0) + => DrawOutline(parentRenderers.AsEntityIdArray(), childRenderers.AsEntityIdArray(), parentNodeColor, childNodeColor, fillOpacity); + public static void DrawOutline(EntityId[] parentRenderers, EntityId[] childRenderers, Color parentNodeColor, Color childNodeColor, float fillOpacity = 0) { if(Event.current.type != EventType.Repaint) return; - Internal_DrawOutline(parentNodeColor, childNodeColor, 0, parentRenderers.ToEntityIdArray(), childRenderers.ToEntityIdArray(), OutlineDrawMode.SelectionOutline, fillOpacity, fillOpacity); + Internal_DrawOutline(parentNodeColor, childNodeColor, 0, parentRenderers, childRenderers, OutlineDrawMode.SelectionOutline, fillOpacity, fillOpacity); Internal_FinishDrawingCamera(Camera.current, true); } + [Obsolete("Deprecated. Use DrawOutline(EntityId[], Color, float) instead.")] public static void DrawOutline(int[] renderers, Color color, float fillOpacity = 0) => + DrawOutline(renderers.AsEntityIdArray(), null, color, color, fillOpacity); + public static void DrawOutline(EntityId[] renderers, Color color, float fillOpacity = 0) => DrawOutline(renderers, null, color, color, fillOpacity); public static void DrawOutline(Renderer[] renderers, Color parentNodeColor, Color childNodeColor, float fillOpacity = 0) { - int[] parentRenderers, childRenderers; + EntityId[] parentRenderers, childRenderers; HandleUtility.FilterRendererIDs(renderers, out parentRenderers, out childRenderers); DrawOutline(parentRenderers, childRenderers, parentNodeColor, childNodeColor, fillOpacity); } @@ -1475,54 +1481,54 @@ public static void DrawOutline(Renderer[] renderers, Color color, float fillOpac public static void DrawOutline(GameObject[] objects, Color parentNodeColor, Color childNodeColor, float fillOpacity = 0) { - int[] parentRenderers, childRenderers; - HandleUtility.FilterInstanceIDs(objects, out parentRenderers, out childRenderers, out _); + EntityId[] parentRenderers, childRenderers; + HandleUtility.FilterEntityIds(objects, out parentRenderers, out childRenderers, out _); DrawOutline(parentRenderers, childRenderers, parentNodeColor, childNodeColor, fillOpacity); } public static void DrawOutline(GameObject[] objects, Color color, float fillOpacity = 0) { var index = 0; - var ids = new int[objects.Length]; + var ids = new EntityId[objects.Length]; foreach (var go in objects) if (go.TryGetComponent(out Renderer renderer)) - ids[index++] = renderer.GetInstanceID(); + ids[index++] = renderer.GetEntityId(); DrawOutline(ids, null, color, color, fillOpacity); } public static void DrawOutline(List objects, Color parentNodeColor, Color childNodeColor, float fillOpacity = 0) { - int[] parentRenderers, childRenderers; - HandleUtility.FilterInstanceIDs((GameObject[])NoAllocHelpers.ExtractArrayFromList(objects), out parentRenderers, out childRenderers, out _); + EntityId[] parentRenderers, childRenderers; + HandleUtility.FilterEntityIds((GameObject[])NoAllocHelpers.ExtractArrayFromList(objects), out parentRenderers, out childRenderers, out _); DrawOutline(parentRenderers, childRenderers, parentNodeColor, childNodeColor, fillOpacity); } public static void DrawOutline(List objects, Color color, float fillOpacity = 0) { var index = 0; - var ids = new int[objects.Count]; + var ids = new EntityId[objects.Count]; foreach (var go in objects) { if (go.TryGetComponent(out Renderer renderer)) - ids[index++] = renderer.GetInstanceID(); + ids[index++] = renderer.GetEntityId(); } DrawOutline(ids, null, color, color, fillOpacity); } - internal static void DrawOutlineOrWireframeInternal(Color parentNodeColor, Color childNodeColor, float outlineAlpha, int[] parentRenderers, int[] childRenderers, OutlineDrawMode outlineMode) + internal static void DrawOutlineOrWireframeInternal(Color parentNodeColor, Color childNodeColor, float outlineAlpha, EntityId[] parentRenderers, EntityId[] childRenderers, OutlineDrawMode outlineMode) { // RenderOutline will swap color.a and outlineAlpha so we reverse it here to preserve correct behavior wrt Color settings in Preferences var parentOutlineAlpha = parentNodeColor.a; var childOutlineAlpha = childNodeColor.a; parentNodeColor.a = outlineAlpha; childNodeColor.a = outlineAlpha; - Internal_DrawOutline(parentNodeColor, childNodeColor, 0, parentRenderers.ToEntityIdArray(), childRenderers.ToEntityIdArray(), outlineMode, parentOutlineAlpha, childOutlineAlpha); + Internal_DrawOutline(parentNodeColor, childNodeColor, 0, parentRenderers, childRenderers, outlineMode, parentOutlineAlpha, childOutlineAlpha); } internal static void DrawSubmeshOutline(Color parentNodeColor, Color childNodeColor, float outlineAlpha, int submeshOutlineMaterialId) { - int[] parentRenderers, childRenderers; - HandleUtility.FilterInstanceIDs(Selection.gameObjects, out parentRenderers, out childRenderers, out _); + EntityId[] parentRenderers, childRenderers; + HandleUtility.FilterEntityIds(Selection.gameObjects, out parentRenderers, out childRenderers, out _); // RenderOutline will swap color.a and outlineAlpha so we reverse it here to preserve correct behavior wrt Color settings in Preferences var parentOutlineAlpha = parentNodeColor.a; @@ -1530,7 +1536,7 @@ internal static void DrawSubmeshOutline(Color parentNodeColor, Color childNodeCo parentNodeColor.a = outlineAlpha; childNodeColor.a = outlineAlpha; - Internal_DrawOutline(parentNodeColor, childNodeColor, submeshOutlineMaterialId, parentRenderers.ToEntityIdArray(), childRenderers.ToEntityIdArray(), OutlineDrawMode.SelectionOutline, parentOutlineAlpha, childOutlineAlpha); + Internal_DrawOutline(parentNodeColor, childNodeColor, submeshOutlineMaterialId, parentRenderers, childRenderers, OutlineDrawMode.SelectionOutline, parentOutlineAlpha, childOutlineAlpha); Internal_FinishDrawingCamera(Camera.current, true); } diff --git a/Editor/Mono/HierarchyProperty.bindings.cs b/Editor/Mono/HierarchyProperty.bindings.cs index 4f1ee5e17a..89a1a2dfe0 100644 --- a/Editor/Mono/HierarchyProperty.bindings.cs +++ b/Editor/Mono/HierarchyProperty.bindings.cs @@ -120,7 +120,8 @@ void Dispose() ~HierarchyProperty() { Dispose(false); } - public extern int instanceID { get; } + extern EntityId entityId { get; } + public int instanceID => entityId; public extern Object pptrValue { [FreeFunction("HierarchyPropertyBindings::PPtrValue", HasExplicitThis = true)] get; } public extern string name { get; } @@ -161,8 +162,8 @@ void Dispose() public bool Previous(int[] expanded) => Previous_internal(expanded, expanded != null && expanded.Length == 0); public extern bool Parent(); [FreeFunction("HierarchyPropertyBindings::Find", HasExplicitThis = true)] - private extern bool Find_internal(int instanceID, int[] expanded, bool nonNullEmptyArray); - public bool Find(int instanceID, int[] expanded) => Find_internal(instanceID, expanded, expanded != null && expanded.Length == 0); + private extern bool Find_internal(EntityId instanceID, int[] expanded, bool nonNullEmptyArray); + public bool Find(int instanceID, int[] expanded) => Find_internal((EntityId)instanceID, expanded, expanded != null && expanded.Length == 0); [FreeFunction("HierarchyPropertyBindings::Skip", HasExplicitThis = true)] private extern bool Skip_internal(int count, int[] expanded, bool nonNullEmptyArray); public bool Skip(int count, int[] expanded) =>Skip_internal(count, expanded, expanded != null && expanded.Length == 0); @@ -190,9 +191,11 @@ internal void SetSearchFilter(SearchFilter filter) [FreeFunction("HierarchyPropertyBindings::SetSearchFilterImpl", HasExplicitThis = true)] extern void SetSearchFilterImpl(string[] nameFilters, string[] classNames, string[] assetLabels, string[] assetBundleNames, string[] versionControlStates, string[] softLockControlStates, int[] referencingInstanceIDs, SceneHandle[] sceneHandles, string[] regex, int[] productIds, bool anyWithAssetOrigin, bool showAllHits, ImportLogFlags importLogFlags, bool filterByTypeIntersection); - + [FreeFunction("HierarchyPropertyBindings::FilterSingleSceneObject")] - public static extern void FilterSingleSceneObject(int instanceID, bool otherVisibilityState); + static extern void FilterSingleSceneObject(EntityId instanceID, bool otherVisibilityState); + + public static void FilterSingleSceneObject(int instanceID, bool otherVisibilityState) => FilterSingleSceneObject((EntityId)instanceID, otherVisibilityState); [FreeFunction("HierarchyPropertyBindings::FindAllAncestors", HasExplicitThis = true)] public extern int[] FindAllAncestors(int[] instanceIDs); diff --git a/Editor/Mono/Inspector/AvatarMaskInspector.cs b/Editor/Mono/Inspector/AvatarMaskInspector.cs index e871193c92..ff09b8dc71 100644 --- a/Editor/Mono/Inspector/AvatarMaskInspector.cs +++ b/Editor/Mono/Inspector/AvatarMaskInspector.cs @@ -752,13 +752,14 @@ protected override void EnabledGUI(Rect cellRect, SerializedNodeInfo node, ref R EditorGUI.EndDisabled(); } + private static readonly Color s_InvalidColor = new Color(1f, 0f, 0f, 0.66f); protected override void NameGUI(Rect position, SerializedNodeInfo node, ref RowGUIArgs args) { var serializedNode = node; - var color = GUI.contentColor; - color = serializedNode.m_State == SerializedNodeInfo.State.Invalid ? new Color(1f, 0f, 0f, 0.66f) : color; + var originalColor = GUI.contentColor; + GUI.contentColor = serializedNode.m_State == SerializedNodeInfo.State.Invalid ? s_InvalidColor : originalColor; base.NameGUI(position, node, ref args); - GUI.contentColor = color; + GUI.contentColor = originalColor; } protected override void ToggleAll() diff --git a/Editor/Mono/Inspector/EditorSettingsInspector.cs b/Editor/Mono/Inspector/EditorSettingsInspector.cs index cc7b616308..6a550eb35b 100644 --- a/Editor/Mono/Inspector/EditorSettingsInspector.cs +++ b/Editor/Mono/Inspector/EditorSettingsInspector.cs @@ -51,8 +51,6 @@ class Content public static GUIContent defaultBehaviorMode = EditorGUIUtility.TrTextContent("Default Behaviour Mode"); public static GUIContent buildPipelineHeader = EditorGUIUtility.TrTextContent("Build Pipeline"); - public static GUIContent ucbpEnableAssetBundles = EditorGUIUtility.TrTextContent("Multi-Process AssetBundle Building", "Enable experimental improvements to the AssetBundle Build Pipeline aimed at reducing build times with multi-process importing and providing more efficient incremental content building"); - public static readonly GUIContent ucbpLearnMore = new GUIContent("Learn more...", "Review official Unity documentation for important considerations around these experimental improvements."); public static GUIContent sceneHandlingHeader = EditorGUIUtility.TrTextContent("Scene Handling"); public static GUIContent forceAssetUnloadAndGCOnSceneLoad = EditorGUIUtility.TrTextContent("Force Asset Unload & GC on Scene Load", "Force a managed heap garbage collection and unload unused assets after loading scenes in single mode in the Editor or exiting Prefab Mode. In complex projects, this can slow down performance. Disable this if you do not require class finalizers to run at the end of scene loading. Note that regular dynamic GC and unused asset unloading still occur when memory usage is high, but without this option, class finalizers might not run immediately after each scene load."); @@ -462,25 +460,6 @@ public override void OnInspectorGUI() GUILayout.Space(10); - GUILayout.BeginHorizontal(); - GUI.enabled = true; - GUILayout.Label(Content.buildPipelineHeader, EditorStyles.boldLabel); - GUI.enabled = editorEnabled; - if (GUILayout.Button(Content.ucbpLearnMore, EditorStyles.linkLabel)) - { - var help = Help.FindHelpNamed("Build-MultiProcess"); - Application.OpenURL(help); - } - GUILayout.EndHorizontal(); - - EditorGUI.BeginChangeCheck(); - bool parallelAssetBundleBuilding = EditorBuildSettings.UseParallelAssetBundleBuilding; - parallelAssetBundleBuilding = EditorGUILayout.Toggle(Content.ucbpEnableAssetBundles, parallelAssetBundleBuilding); - if (EditorGUI.EndChangeCheck()) - EditorBuildSettings.UseParallelAssetBundleBuilding = parallelAssetBundleBuilding; - if(parallelAssetBundleBuilding) - EditorGUILayout.HelpBox("Please review official documentation before building any content with these experimental improvements enabled. These improvements apply only to AssetBundles built with BuildPipeline.BuildAssetBundles() and do not apply to AssetBundles built with Scriptable Build Pipeline or Addressables.", MessageType.Info); - GUILayout.Label(Content.sceneHandlingHeader, EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); bool forceAssetUnloadAndGCOnSceneLoad = EditorSettings.forceAssetUnloadAndGCOnSceneLoad; diff --git a/Editor/Mono/Inspector/GameObjectInspector.cs b/Editor/Mono/Inspector/GameObjectInspector.cs index adac69016a..3070b2091e 100644 --- a/Editor/Mono/Inspector/GameObjectInspector.cs +++ b/Editor/Mono/Inspector/GameObjectInspector.cs @@ -12,6 +12,7 @@ using UnityObject = UnityEngine.Object; using UnityEditor.Experimental; using System.IO; +using UnityEngine.Pool; namespace UnityEditor { @@ -374,7 +375,7 @@ internal void OnDisable() ClearPreviewCache(); m_PreviewCache = null; - if (string.IsNullOrEmpty(m_Name.stringValue) && !(string.IsNullOrEmpty(m_GOPreviousName))) + if (m_Name != null && string.IsNullOrEmpty(m_Name.stringValue) && !(string.IsNullOrEmpty(m_GOPreviousName))) { Debug.LogWarning("A GameObject name cannot be set to an empty string."); m_Name.stringValue = m_GOPreviousName; @@ -415,7 +416,7 @@ void ClearPreviewCache() private static StaticEditorFlags[] s_StaticEditorFlagValues; - private static bool ShowMixedStaticEditorFlags(StaticEditorFlags mask) + internal static bool ShowMixedStaticEditorFlags(StaticEditorFlags mask) { uint countedBits = 0; uint numFlags = 0; @@ -833,13 +834,17 @@ private void DoLayerField(GameObject go) int layer = EditorGUI.LayerField(layerRect, Styles.layerContent, go.layer, Styles.layerPopup); if (EditorGUI.EndChangeCheck()) { - GameObjectUtility.ShouldIncludeChildren includeChildren = GameObjectUtility.DisplayUpdateChildrenDialogIfNeeded(targets.OfType(), - L10n.Tr("Change Layer"), string.Format(L10n.Tr("Do you want to set layer to {0} for all child objects as well?"), InternalEditorUtility.GetLayerName(layer))); - if (includeChildren != GameObjectUtility.ShouldIncludeChildren.Cancel) + // filter out non gameobject targets + using var r = new RentSpan(targets.Length); + var goCount = 0; + foreach (var obj in targets) { - m_Layer.intValue = layer; - SetLayer(layer, includeChildren == GameObjectUtility.ShouldIncludeChildren.IncludeChildren); + if (obj is GameObject g) + r.Span[goCount++] = g; } + + SceneModeUtility.SetLayer(r.Span[..goCount], layer, targetTitle); + // Displaying the dialog to ask the user whether to update children nukes the gui state EditorGUIUtility.ExitGUI(); } @@ -913,22 +918,6 @@ private void DoStaticToggleField(GameObject go) EditorGUI.EndProperty(); } - UnityObject[] GetObjects(bool includeChildren) - { - return SceneModeUtility.GetObjects(targets, includeChildren); - } - - void SetLayer(int layer, bool includeChildren) - { - UnityObject[] objects = GetObjects(includeChildren); - Undo.RecordObjects(objects, "Change Layer of " + targetTitle); - foreach (var o in objects) - { - var go = (GameObject)o; - go.layer = layer; - } - } - void ReloadPreviewInstance(string prefabAssetPath) { foreach (var pair in m_PreviewInstances) diff --git a/Editor/Mono/Inspector/LODGroupEditor.cs b/Editor/Mono/Inspector/LODGroupEditor.cs index 54074d9f4f..d1fc042711 100644 --- a/Editor/Mono/Inspector/LODGroupEditor.cs +++ b/Editor/Mono/Inspector/LODGroupEditor.cs @@ -407,6 +407,7 @@ void DrawLODGroupFoldout(Camera camera, int lodGroupIndex, ref SavedBool foldout { serializedObject.ApplyModifiedProperties(); ResetValuesAfterLODObjectIsModified(); + UpdateEnabledMeshLods(); } } @@ -673,6 +674,10 @@ public override void OnInspectorGUI() ResetFoldoutLists(); } + // Flush this editor's mesh LOD state if it's out of sync with serialized data + if (m_EnabledMeshLods.Length != m_LODs.arraySize) + UpdateEnabledMeshLods(); + EditorGUILayout.PropertyField(m_FadeMode); m_ShowAnimateCrossFading.target = m_FadeMode.intValue != (int)LODFadeMode.None; @@ -1086,6 +1091,7 @@ private void AddGameObjectRenderers(IEnumerable toAdd, bool add) serializedObject.ApplyModifiedProperties(); m_LODGroup.RecalculateBounds(); ResetValuesAfterLODObjectIsModified(); + UpdateEnabledMeshLods(); ExpandSelectedHeaderAndCloseRemaining(activeLOD); } @@ -1177,11 +1183,18 @@ public void DeleteLOD() } } - private void DeletedLOD() + void OnInsertLOD() + { + ResetValuesAfterLODObjectIsModified(); + UpdateEnabledMeshLods(); + } + + void OnDeleteLOD() { m_SelectedLOD--; ResetValuesAfterLODObjectIsModified(); + UpdateEnabledMeshLods(); } // Set the camera distance so that the current LOD group covers the desired percentage of the screen @@ -1255,7 +1268,7 @@ private void DrawLODLevelSlider(Rect sliderPosition, List lods) else { pm.AddItem(EditorGUIUtility.TrTextContent("Insert Before"), false, - new LODAction(lods, cameraPercent, evt.mousePosition, m_LODs, ResetValuesAfterLODObjectIsModified). + new LODAction(lods, cameraPercent, evt.mousePosition, m_LODs, OnInsertLOD). InsertLOD); } @@ -1268,7 +1281,7 @@ private void DrawLODLevelSlider(Rect sliderPosition, List lods) pm.AddDisabledItem(EditorGUIUtility.TrTextContent("Delete")); else pm.AddItem(EditorGUIUtility.TrTextContent("Delete"), false, - new LODAction(lods, cameraPercent, evt.mousePosition, m_LODs, DeletedLOD). + new LODAction(lods, cameraPercent, evt.mousePosition, m_LODs, OnDeleteLOD). DeleteLOD); pm.ShowAsContext(); diff --git a/Editor/Mono/Inspector/LightingSettingsEditor.cs b/Editor/Mono/Inspector/LightingSettingsEditor.cs index 4ee87f6e10..31682bcc2a 100644 --- a/Editor/Mono/Inspector/LightingSettingsEditor.cs +++ b/Editor/Mono/Inspector/LightingSettingsEditor.cs @@ -3,12 +3,10 @@ // https://unity3d.com/legal/licenses/Unity_Reference_Only_License using System; -using System.Linq; using UnityEngine.Rendering; using UnityEngine; using UnityEngineInternal; using Object = UnityEngine.Object; -using System.Runtime.InteropServices; namespace UnityEditor { @@ -125,18 +123,23 @@ static class Styles { public static readonly float buttonWidth = 200; - public static readonly int[] bakeBackendValues = + static readonly int[] k_BakeBackendValues = { (int)LightingSettings.Lightmapper.ProgressiveCPU, - (int)LightingSettings.Lightmapper.ProgressiveGPU, - //(int)LightingSettings.Lightmapper.UnityComputeGPU + (int)LightingSettings.Lightmapper.ProgressiveGPU }; - public static readonly GUIContent[] bakeBackendStrings = + static readonly int[] k_BakeBackendValuesWithUnityComputeGPU = + k_BakeBackendValues.ConcatValue(3); // Cannot make LightingSettings.Lightmapper.UnityComputeGPU public just yet + public static int[] bakeBackendValues => Lightmapping.UnifiedBaker ? k_BakeBackendValuesWithUnityComputeGPU : k_BakeBackendValues; + + public static readonly GUIContent[] k_BakeBackendStrings = { EditorGUIUtility.TrTextContent("Progressive CPU"), - EditorGUIUtility.TrTextContent("Progressive GPU"), - //EditorGUIUtility.TrTextContent("Unity Compute (GPU)"), + EditorGUIUtility.TrTextContent("Progressive GPU") }; + static readonly GUIContent[] k_BakeBackendStringsWithUnityComputeGPU = + k_BakeBackendStrings.ConcatValue(EditorGUIUtility.TrTextContent("Unity Compute (GPU)")); + public static GUIContent[] bakeBackendStrings => Lightmapping.UnifiedBaker ? k_BakeBackendStringsWithUnityComputeGPU : k_BakeBackendStrings; public static readonly int[] lightmapDirectionalModeValues = { (int)LightmapsMode.NonDirectional, (int)LightmapsMode.CombinedDirectional }; public static readonly GUIContent[] lightmapDirectionalModeStrings = @@ -1069,4 +1072,17 @@ internal void ClampMaxRanges() maxXAtlasPackingAttempts = Mathf.Max(m_XAtlasPackingAttempts.intValue, 131072); } } + + // Extension methods for concatenating arrays with a single value (since we cannot use LINQ) + static class LocalExtensions + { + public static T[] ConcatValue(this T[] array, T value) + { + var result = new T[array.Length + 1]; + Array.Copy(array, result, array.Length); + result[array.Length] = value; + + return result; + } + } } diff --git a/Editor/Mono/Inspector/PlayerSettingsEditor/PlayerSettingsEditor.cs b/Editor/Mono/Inspector/PlayerSettingsEditor/PlayerSettingsEditor.cs index d63eb74065..8f73f5b7db 100644 --- a/Editor/Mono/Inspector/PlayerSettingsEditor/PlayerSettingsEditor.cs +++ b/Editor/Mono/Inspector/PlayerSettingsEditor/PlayerSettingsEditor.cs @@ -532,6 +532,12 @@ internal static void SyncEditors(BuildTarget target) bool isPresetWindowOpen = false; bool hasPresetWindowClosed = false; + // True when current graphics API mismatches with top of the list one + private static bool hasPendingGraphicsAPIChange = false; + + // True when user has modified auto graphics API setting in the current session + private static bool isAutoGraphicsAPITouched = false; + /// /// Internal callback set by the build profile window when tracking /// changes to settings not represented by a serialized property. @@ -1496,6 +1502,23 @@ private bool CanRemoveGraphicsDeviceElement(ReorderableList list) return list.list.Count >= 2; } + private bool CheckRemoveFallbackGraphicsDeviceElement(GraphicsDeviceType removed, BuildTarget target, ReorderableList list) + { + bool isWindows = ((target == BuildTarget.StandaloneWindows) || (target == BuildTarget.StandaloneWindows64)); + bool isUWP = (target == BuildTarget.WSAPlayer); + + bool fallbackWindows = ((isUWP || isWindows) && (removed == GraphicsDeviceType.Direct3D11)); + bool fallbackAndroid = ((target == BuildTarget.Android) && (removed == GraphicsDeviceType.OpenGLES3)); + + if (fallbackWindows || fallbackAndroid) + { + string text = $"It is recommended to keep {GraphicsDeviceTypeToString(target, removed)} as a fallback graphics API. Removing this from the list may prevent the application from running on older and lower-end devices."; + var result = EditorUtility.DisplayDialog("Removing fallback graphics API", text, "Proceed", "Cancel"); + return result; + } + return true; + } + private void RemoveGraphicsDeviceElement(BuildTarget target, ReorderableList list) { var apis = m_CurrentTarget.GetGraphicsAPIs_Internal(target); @@ -1509,10 +1532,14 @@ private void RemoveGraphicsDeviceElement(BuildTarget target, ReorderableList lis } var apiList = apis.ToList(); - apiList.RemoveAt(list.index); - apis = apiList.ToArray(); + var removedElement = apiList[list.index]; + if (CheckRemoveFallbackGraphicsDeviceElement(removedElement, target, list)) + { + apiList.RemoveAt(list.index); + apis = apiList.ToArray(); - ApplyChangedGraphicsAPIList(target, apis, list.index == 0); + ApplyChangedGraphicsAPIList(target, apis, list.index == 0); + } } private void ReorderGraphicsDeviceElement(BuildTarget target, ReorderableList list) @@ -1520,9 +1547,12 @@ private void ReorderGraphicsDeviceElement(BuildTarget target, ReorderableList li var previousAPIs = m_CurrentTarget.GetGraphicsAPIs_Internal(target); var apiList = (List)list.list; var apis = apiList.ToArray(); + var currentDevice = SystemInfo.graphicsDeviceType; var firstAPIDifferent = (previousAPIs[0] != apis[0]); - ApplyChangedGraphicsAPIList(target, apis, firstAPIDifferent); + var requiresRestart = apis[0] != currentDevice; + + ApplyChangedGraphicsAPIList(target, apis, firstAPIDifferent && requiresRestart); } // these two methods are needed for cases when you want to take some action depending on user choice @@ -1533,7 +1563,7 @@ private struct ChangeGraphicsApiAction public readonly bool changeList, reloadGfx; public ChangeGraphicsApiAction(bool doChange, bool doReload) { changeList = doChange; reloadGfx = doReload; } } - private ChangeGraphicsApiAction CheckApplyGraphicsAPIList(BuildTarget target, bool firstEntryChanged) + private ChangeGraphicsApiAction CheckApplyGraphicsAPIList(BuildTarget target, bool firstEntryChanged, bool cancelAPIChange) { bool doRestart = false; // If we're changing the first API for relevant editor, this will cause editor to switch: ask for scene save & confirmation @@ -1552,7 +1582,7 @@ private ChangeGraphicsApiAction CheckApplyGraphicsAPIList(BuildTarget target, bo { var result = EditorUtility.DisplayDialogComplex("Changing editor graphics API", "You've changed the active graphics API. This requires a restart of the Editor. Do you want to save the Scene when restarting?", - "Save and Restart", "Cancel Changing API", "Discard Changes and Restart"); + "Save and Restart", cancelAPIChange ? "Cancel Changing API" : "Not now", "Discard Changes and Restart"); if (result == 1) { doRestart = false; // Cancel was selected @@ -1592,15 +1622,18 @@ private ChangeGraphicsApiAction CheckApplyGraphicsAPIList(BuildTarget target, bo } } - private void ApplyChangeGraphicsApiAction(BuildTarget target, GraphicsDeviceType[] apis, ChangeGraphicsApiAction action) + private void ApplyChangeGraphicsApiAction(BuildTarget target, GraphicsDeviceType[] apis, ChangeGraphicsApiAction action, bool skipRemoveCached) { + hasPendingGraphicsAPIChange = true; if (action.changeList) { m_CurrentTarget.SetGraphicsAPIs_Internal(target, apis, true); OnTargetObjectChangedDirectly(); } - else + else if (!skipRemoveCached) + { m_GraphicsDeviceLists.Remove(target); // we cancelled the list change, so remove the cached one + } if (action.reloadGfx) { @@ -1611,8 +1644,8 @@ private void ApplyChangeGraphicsApiAction(BuildTarget target, GraphicsDeviceType private void ApplyChangedGraphicsAPIList(BuildTarget target, GraphicsDeviceType[] apis, bool firstEntryChanged) { - ChangeGraphicsApiAction action = CheckApplyGraphicsAPIList(target, firstEntryChanged); - ApplyChangeGraphicsApiAction(target, apis, action); + ChangeGraphicsApiAction action = CheckApplyGraphicsAPIList(target, firstEntryChanged, true); + ApplyChangeGraphicsApiAction(target, apis, action, false); } private void DrawGraphicsDeviceElement(BuildTarget target, Rect rect, int index, bool selected, bool focused) @@ -1748,65 +1781,87 @@ void GraphicsAPIsGUIOnePlatform(BuildTargetGroup targetGroup, BuildTarget target automatic = EditorGUILayout.Toggle(platformTitleContent ?? GUIContent.none, automatic); if (EditorGUI.EndChangeCheck()) { + isAutoGraphicsAPITouched = true; Undo.RecordObject(target, SettingsContent.undoChangedGraphicsAPIString); m_CurrentTarget.SetUseDefaultGraphicsAPIs_Internal(targetPlatform, automatic); OnTargetObjectChangedDirectly(); + if (WillEditorUseFirstGraphicsAPI(targetPlatform)) + hasPendingGraphicsAPIChange = false; } - // graphics API list if not automatic - if (!automatic) + string displayTitle = String.Empty; + if (platformTitleContent != null) { - // note that editor will use first item, when we're in standalone settings - if (WillEditorUseFirstGraphicsAPI(targetPlatform)) - { - EditorGUILayout.HelpBox(SettingsContent.recordingInfo.text, MessageType.Info, true); - } + displayTitle = platformTitleContent.text; + if (displayTitle.StartsWith("Auto ")) + displayTitle = displayTitle.Substring(5); + } - string displayTitle = String.Empty; - if (platformTitleContent != null) - { - displayTitle = platformTitleContent.text; - if (displayTitle.StartsWith("Auto ")) - displayTitle = displayTitle.Substring(5); - } + if (targetPlatform == BuildTarget.PS5) + { + ExclusiveGraphicsAPIsGUI(targetPlatform, displayTitle); + return; + } - if (targetPlatform == BuildTarget.PS5) - { - ExclusiveGraphicsAPIsGUI(targetPlatform, displayTitle); - return; - } + GraphicsDeviceType[] devices = m_CurrentTarget.GetGraphicsAPIs_Internal(targetPlatform); + var devicesList = (devices != null) ? devices.ToList() : new List(); + // create reorderable list for this target if needed + if (!m_GraphicsDeviceLists.ContainsKey(targetPlatform)) + { + var rlist = new ReorderableList(devicesList, typeof(GraphicsDeviceType), true, true, true, true); + rlist.onAddDropdownCallback = (rect, list) => AddGraphicsDeviceElement(targetPlatform, rect, list); + rlist.onCanRemoveCallback = CanRemoveGraphicsDeviceElement; + rlist.onRemoveCallback = (list) => RemoveGraphicsDeviceElement(targetPlatform, list); + rlist.onReorderCallback = (list) => ReorderGraphicsDeviceElement(targetPlatform, list); + rlist.drawElementCallback = (rect, index, isActive, isFocused) => DrawGraphicsDeviceElement(targetPlatform, rect, index, isActive, isFocused); + rlist.drawHeaderCallback = (rect) => GUI.Label(rect, displayTitle, EditorStyles.label); + rlist.elementHeight = 16; - GraphicsDeviceType[] devices = m_CurrentTarget.GetGraphicsAPIs_Internal(targetPlatform); - var devicesList = (devices != null) ? devices.ToList() : new List(); - // create reorderable list for this target if needed - if (!m_GraphicsDeviceLists.ContainsKey(targetPlatform)) - { - var rlist = new ReorderableList(devicesList, typeof(GraphicsDeviceType), true, true, true, true); - rlist.onAddDropdownCallback = (rect, list) => AddGraphicsDeviceElement(targetPlatform, rect, list); - rlist.onCanRemoveCallback = CanRemoveGraphicsDeviceElement; - rlist.onRemoveCallback = (list) => RemoveGraphicsDeviceElement(targetPlatform, list); - rlist.onReorderCallback = (list) => ReorderGraphicsDeviceElement(targetPlatform, list); - rlist.drawElementCallback = (rect, index, isActive, isFocused) => DrawGraphicsDeviceElement(targetPlatform, rect, index, isActive, isFocused); - rlist.drawHeaderCallback = (rect) => GUI.Label(rect, displayTitle, EditorStyles.label); - rlist.elementHeight = 16; - - m_GraphicsDeviceLists.Add(targetPlatform, rlist); - } + m_GraphicsDeviceLists.Add(targetPlatform, rlist); + } - if (targetPlatform == BuildTarget.StandaloneOSX && m_GraphicsDeviceLists[BuildTarget.StandaloneOSX].list.Contains(GraphicsDeviceType.OpenGLCore)) + var deviceList = m_GraphicsDeviceLists[targetPlatform]; + GraphicsDeviceType? selectedDevice = deviceList.count > 0 ? (GraphicsDeviceType)deviceList.list[0] : null; + var currentDevice = SystemInfo.graphicsDeviceType; + bool firstAPIDifferent = currentDevice != selectedDevice; + + if (selectedDevice != null && firstAPIDifferent && WillEditorUseFirstGraphicsAPI(targetPlatform) && isAutoGraphicsAPITouched) + { + string text = $"Auto Graphics API was changed, but requires an Editor restart to take Effect. The Editor will restart using {GraphicsDeviceTypeToString(targetPlatform, (GraphicsDeviceType)selectedDevice)}"; + EditorGUILayout.HelpBox(text, MessageType.Warning, true); + if (!hasPendingGraphicsAPIChange) { - EditorGUILayout.HelpBox(SettingsContent.appleSiliconOpenGLWarning.text, MessageType.Warning, true); + ChangeGraphicsApiAction action = CheckApplyGraphicsAPIList(targetPlatform, true, false); + var apiList = (List)deviceList.list; + var apis = apiList.ToArray(); + ApplyChangeGraphicsApiAction(targetPlatform, apis, action, true); } + } - m_GraphicsDeviceLists[targetPlatform].DoLayoutList(); + EditorGUI.BeginDisabledGroup(automatic); - bool containsDeprecatedAPIs = devicesList.Exists(device => IsGraphicsDeviceTypeDeprecated(targetPlatform, device)); - if (containsDeprecatedAPIs) - EditorGUILayout.HelpBox(SettingsContent.graphicsAPIDeprecationMessage.text, MessageType.Info, true); + // graphics API list if not automatic + // note that editor will use first item, when we're in standalone settings + if (WillEditorUseFirstGraphicsAPI(targetPlatform)) + { + EditorGUILayout.HelpBox(SettingsContent.recordingInfo.text, MessageType.Info, true); + } - //@TODO: undo + if (targetPlatform == BuildTarget.StandaloneOSX && m_GraphicsDeviceLists[BuildTarget.StandaloneOSX].list.Contains(GraphicsDeviceType.OpenGLCore)) + { + EditorGUILayout.HelpBox(SettingsContent.appleSiliconOpenGLWarning.text, MessageType.Warning, true); } + deviceList.DoLayoutList(); + + bool containsDeprecatedAPIs = devicesList.Exists(device => IsGraphicsDeviceTypeDeprecated(targetPlatform, device)); + if (containsDeprecatedAPIs) + EditorGUILayout.HelpBox(SettingsContent.graphicsAPIDeprecationMessage.text, MessageType.Info, true); + + //@TODO: undo + + EditorGUI.EndDisabledGroup(); + // ES3.1 options OpenGLES31OptionsGUI(targetGroup, targetPlatform); } @@ -2365,6 +2420,7 @@ private void OtherSectionRenderingGUI(BuildPlatform platform, ISettingEditorExte foreach (GraphicsDeviceType api in gfxAPIs) { if (api == GraphicsDeviceType.Switch || + api == GraphicsDeviceType.Switch2 || api == GraphicsDeviceType.PlayStation5 || api == GraphicsDeviceType.PlayStation5NGGC || api == GraphicsDeviceType.Direct3D11 || @@ -2702,7 +2758,7 @@ private void OtherSectionRenderingGUI(BuildPlatform platform, ISettingEditorExte if (oldUseHDRDisplay != m_UseHDRDisplay.boolValue) requestRepaint = true; - if (platform.namedBuildTarget.ToBuildTargetGroup() == BuildTargetGroup.Standalone || platform.namedBuildTarget == NamedBuildTarget.WindowsStoreApps || platform.namedBuildTarget == NamedBuildTarget.iOS) + if (platform.namedBuildTarget.ToBuildTargetGroup() == BuildTargetGroup.Standalone || platform.namedBuildTarget == NamedBuildTarget.WindowsStoreApps || platform.namedBuildTarget == NamedBuildTarget.iOS || platform.namedBuildTarget == NamedBuildTarget.NintendoSwitch2) { using (new EditorGUI.DisabledScope(!m_UseHDRDisplay.boolValue)) { diff --git a/Editor/Mono/Inspector/ReorderableListWrapper.cs b/Editor/Mono/Inspector/ReorderableListWrapper.cs index bbd241016d..901a886136 100644 --- a/Editor/Mono/Inspector/ReorderableListWrapper.cs +++ b/Editor/Mono/Inspector/ReorderableListWrapper.cs @@ -225,7 +225,11 @@ void DrawChildren(Rect listRect, Rect headerRect, Rect sizeRect, Rect visibleRec } else continue; - if (Event.current.type == EventType.DragPerform) ReorderableList.defaultBehaviours.DoAddButton(m_ReorderableList, validatedObject); + if (Event.current.type == EventType.DragPerform) + { + ReorderableList.defaultBehaviours.DoAddButton(m_ReorderableList, validatedObject); + GUI.changed = true; + } } DragAndDrop.AcceptDrag(); Event.current.Use(); diff --git a/Editor/Mono/Inspector/TagManagerInspector.cs b/Editor/Mono/Inspector/TagManagerInspector.cs index 461e2dfcd7..d8b3489ce9 100644 --- a/Editor/Mono/Inspector/TagManagerInspector.cs +++ b/Editor/Mono/Inspector/TagManagerInspector.cs @@ -485,14 +485,13 @@ class EnterTagNamePopup : PopupWindowContent readonly EnterDelegate m_EnterCallback; string m_NewTagName = "New tag"; bool m_NeedsFocus = true; - readonly List m_ExistingTagNames = new (); + readonly List m_ExistingTagNames = new List(InternalEditorUtility.tags); bool m_IsExistingTag; public EnterTagNamePopup(SerializedProperty tags, EnterDelegate callback) { m_EnterCallback = callback; - m_ExistingTagNames.Clear(); for (var i = 0; i < tags.arraySize; i++) { var tagName = tags.GetArrayElementAtIndex(i).stringValue; @@ -512,6 +511,7 @@ public override void OnGUI(Rect windowRect) GUILayout.Space(5); var evt = Event.current; var hitEnter = evt.type == EventType.KeyDown && evt.keyCode is KeyCode.Return or KeyCode.KeypadEnter; + bool previousExistingTagState = m_IsExistingTag; GUI.SetNextControlName("TagName"); // If on previous OnGUI there was attempt saving existing name, show error until name is changed @@ -543,7 +543,7 @@ public override void OnGUI(Rect windowRect) m_IsExistingTag = true; // Hitting enter won't repaint the window, we need to do it manually - if(hitEnter) + if(hitEnter && previousExistingTagState != m_IsExistingTag) editorWindow.RepaintImmediately(); return; diff --git a/Editor/Mono/Networking/PlayerConnection/ConnectionDropDown.cs b/Editor/Mono/Networking/PlayerConnection/ConnectionDropDown.cs index 0502661c1c..a5107d8ff4 100644 --- a/Editor/Mono/Networking/PlayerConnection/ConnectionDropDown.cs +++ b/Editor/Mono/Networking/PlayerConnection/ConnectionDropDown.cs @@ -145,6 +145,7 @@ public static GUIContent GetIcon(string name) "WSAPlayerX64" => EditorGUIUtility.IconContent("BuildSettings.Metro.Small"), "WSAPlayerARM" => EditorGUIUtility.IconContent("BuildSettings.Metro.Small"), "Switch" => EditorGUIUtility.IconContent("BuildSettings.Switch.Small"), + "Switch2" => EditorGUIUtility.IconContent("BuildSettings.Switch2.Small"), "EmbeddedLinuxArm64" => EditorGUIUtility.IconContent("BuildSettings.EmbeddedLinux.Small"), "EmbeddedLinuxArm32" => EditorGUIUtility.IconContent("BuildSettings.EmbeddedLinux.Small"), "EmbeddedLinuxX64" => EditorGUIUtility.IconContent("BuildSettings.EmbeddedLinux.Small"), diff --git a/Editor/Mono/ObjectNames.bindings.cs b/Editor/Mono/ObjectNames.bindings.cs index 627ea6a049..e87fa595ea 100644 --- a/Editor/Mono/ObjectNames.bindings.cs +++ b/Editor/Mono/ObjectNames.bindings.cs @@ -25,7 +25,7 @@ public sealed partial class ObjectNames public static extern void SetNameSmart(UnityObject obj, string name); [FreeFunction("SetNameSmartWithInstanceID_Internal")] - internal static extern void SetNameSmartWithInstanceID(int instanceID, string name); + internal static extern void SetNameSmartWithInstanceID(UnityEngine.EntityId instanceID, string name); [FreeFunction("GetUniqueName_Internal")] public static extern string GetUniqueName(string[] existingNames, string name); diff --git a/Editor/Mono/Overlays/Overlay.cs b/Editor/Mono/Overlays/Overlay.cs index 94fed8ee31..d8195ad13d 100644 --- a/Editor/Mono/Overlays/Overlay.cs +++ b/Editor/Mono/Overlays/Overlay.cs @@ -935,7 +935,7 @@ internal void SetHighlightEnabled(bool highlight) internal void Initialize(string _id, string _uss, string _display, Vector2 defaultSize, Vector2 minSize, Vector2 maxSize, int menuPriority, string menuGroup) { m_RootVisualElementName = _uss; - string name = string.IsNullOrEmpty(_display) ? m_RootVisualElementName : _display; + string name = string.IsNullOrEmpty(_display) ? GetType().Name : _display; m_Id = string.IsNullOrEmpty(_id) ? name : _id; displayName = L10n.Tr(name); rootVisualElement.style.display = DisplayStyle.None; diff --git a/Editor/Mono/Overlays/OverlayCanvas.cs b/Editor/Mono/Overlays/OverlayCanvas.cs index 5a1fcab68d..c374c3f435 100644 --- a/Editor/Mono/Overlays/OverlayCanvas.cs +++ b/Editor/Mono/Overlays/OverlayCanvas.cs @@ -1094,6 +1094,7 @@ void AddOverlay(Overlay overlay, bool transient = false) return; } + OverlayUtilities.ValidateName(overlay); overlay.canvas = this; m_Overlays.Add(overlay); if (transient) diff --git a/Editor/Mono/Overlays/OverlayUtilities.cs b/Editor/Mono/Overlays/OverlayUtilities.cs index 1dadadd3d5..e63fa06812 100644 --- a/Editor/Mono/Overlays/OverlayUtilities.cs +++ b/Editor/Mono/Overlays/OverlayUtilities.cs @@ -30,7 +30,7 @@ static class OverlayUtilities internal const string k_StyleCommon = "StyleSheets/Overlays/OverlayCommon.uss"; internal const string k_StyleLight = "StyleSheets/Overlays/OverlayLight.uss"; internal const string k_StyleDark = "StyleSheets/Overlays/OverlayDark.uss"; - + internal class OverlayEditorWindowAssociation { public Type overlay; @@ -251,6 +251,13 @@ internal static string GetSignificantLettersForIcon(string s) return words[0].Substring(0, 1) + words[1].Substring(0, 1); } + internal static void ValidateName(Overlay overlay) + { + if (overlay == null || !string.IsNullOrEmpty(overlay.displayName)) + return; + overlay.displayName = $"{overlay.GetType().Name}"; + } + internal static bool EnsureValidId(IEnumerable existing, Overlay overlay) { if (overlay == null) @@ -281,7 +288,7 @@ static string EnsureUniqueId(IEnumerable existing, string name) return null; } - + internal static void AddStyleSheets(VisualElement ve) { StyleSheet sheet; @@ -293,7 +300,7 @@ internal static void AddStyleSheets(VisualElement ve) else sheet = EditorGUIUtility.Load(k_StyleLight) as StyleSheet; - ve.styleSheets.Add(sheet); + ve.styleSheets.Add(sheet); } public static bool IsOverlayWindowValid(OverlayAttribute attribute) diff --git a/Editor/Mono/Prefabs/PrefabImporterEditor.cs b/Editor/Mono/Prefabs/PrefabImporterEditor.cs index 2bf6acaf24..d88569332c 100644 --- a/Editor/Mono/Prefabs/PrefabImporterEditor.cs +++ b/Editor/Mono/Prefabs/PrefabImporterEditor.cs @@ -55,11 +55,6 @@ bool isTextFieldCaretShowing get { return EditorGUI.IsEditingTextField() && !EditorGUIUtility.textFieldHasSelection; } } - internal bool readyToAutoSave - { - get { return !m_SavingHasFailed && !hasMissingScripts && GUIUtility.hotControl == 0 && !isTextFieldCaretShowing && !EditorApplication.isCompiling; } - } - bool hasMissingScripts { get { return m_PrefabsWithMissingScript.Count > 0; } @@ -77,7 +72,9 @@ public override void OnDisable() { EditorApplication.update -= WaitToApplyChanges; m_HasPendingChanges = false; - SaveDirtyPrefabAssets(false); + + // (UUM-111102) Do not call SaveDirtyPrefabAssets() from here in OnDisable as we might be in the beginning of a domain reload + // where saving prefabs are not allowed. Any changes will be ensured to be saved in OnDestroy } ObjectChangeEvents.changesPublished -= ObjectChangeEventPublished; @@ -109,7 +106,7 @@ private void ObjectChangeEventPublished(ref ObjectChangeEventStream stream) var asset = EditorUtility.EntityIdToObject(instanceId); if (IsTargetAsset(asset)) { - if (CanSave()) + if (CanAutoSave()) { SaveDirtyPrefabAssets(true); } @@ -146,7 +143,7 @@ protected override void Awake() void OnDestroy() { // Ensure to save unsaved changes (regardless of hotcontrol etc) - if (!m_SavingHasFailed && !hasMissingScripts) + if (!m_SavingHasFailed && !hasMissingScripts && !EditorApplication.isCompiling) SaveDirtyPrefabAssets(false); } @@ -155,8 +152,12 @@ void OnDestroy() /// Auto-saving is disabled if a UI field is focused or the CurveEditorWindow, ColorPicker or GradientPicker is visible. /// /// Returns true if auto-saving is allowed; otherwise, returns false. - internal bool CanSave() => !EditorFocusMonitor.AreBindableElementsSelected() && - readyToAutoSave && + internal bool CanAutoSave() => !EditorFocusMonitor.AreBindableElementsSelected() && + !m_SavingHasFailed && + !hasMissingScripts && + GUIUtility.hotControl == 0 && + !isTextFieldCaretShowing && + !EditorApplication.isCompiling && !CurveEditorWindow.visible && !ColorPicker.visible && !GradientPicker.visible; @@ -168,7 +169,7 @@ void WaitToApplyChanges() { m_NextUpdate = time + 0.2; - if (CanSave()) + if (CanAutoSave()) SaveDirtyPrefabAssets(true); } } @@ -182,8 +183,8 @@ internal void SaveDirtyPrefabAssets(bool reloadInspectors) if (assetTarget == null) return; - if (reloadInspectors && !CanSave()) - Debug.LogWarning("SaveDirtyPrefabAssets should not be called when CanSave is false and reloading inspectors."); + if (reloadInspectors && !CanAutoSave()) + Debug.LogWarning("SaveDirtyPrefabAssets should not be called when CanAutoSave is false and reloading inspectors."); m_DirtyPrefabAssets.Clear(); foreach (var asset in assetTargets) diff --git a/Editor/Mono/Prefabs/PrefabUtility.bindings.cs b/Editor/Mono/Prefabs/PrefabUtility.bindings.cs index 243ccaae1b..961182f8ac 100644 --- a/Editor/Mono/Prefabs/PrefabUtility.bindings.cs +++ b/Editor/Mono/Prefabs/PrefabUtility.bindings.cs @@ -385,7 +385,7 @@ internal static void AddGameObjectsToPrefabAndConnect(GameObject[] gameObjects, // which leads to managed null references (unity null) even though we have a native object. See handling for missing // scripts for Prefab instances in GenericInspector.cs [FreeFunction] - extern internal static bool IsInstanceIDPartOfNonAssetPrefabInstance(int componentOrGameObjectInstanceID); + extern internal static bool IsInstanceIDPartOfNonAssetPrefabInstance(EntityId componentOrGameObjectInstanceID); // Returns true if the object is from a regular prefab or instance of regular prefab [FreeFunction] @@ -438,7 +438,7 @@ internal static void AddGameObjectsToPrefabAndConnect(GameObject[] gameObjects, extern internal static void ShowCyclicNestingWarningDialog(); [NativeMethod("PrefabUtilityBindings::GetVariantParentGUID_Internal", IsFreeFunction = true, ThrowsException = true)] - extern internal static string GetVariantParentGUID(int prefabAssetInstanceID); + extern internal static string GetVariantParentGUID(EntityId prefabAssetInstanceID); internal static string GetVariantParentGUID(GameObject prefabAsset) { diff --git a/Editor/Mono/ProjectBrowser/ProjectBrowser.cs b/Editor/Mono/ProjectBrowser/ProjectBrowser.cs index d744a85e7f..cd45b25a0e 100644 --- a/Editor/Mono/ProjectBrowser/ProjectBrowser.cs +++ b/Editor/Mono/ProjectBrowser/ProjectBrowser.cs @@ -26,6 +26,13 @@ internal class ProjectBrowser : EditorWindow, IHasCustomMenu, ISearchableContain public const int kPackagesFolderInstanceId = int.MaxValue; public const int kAssetCreationInstanceID_ForNonExistingAssets = Int32.MaxValue - 1; + internal static readonly SavedBool k_ShowFoldersFirst = new SavedBool("ShowFoldersFirst", Application.platform != RuntimePlatform.OSXEditor); + + static void ToggleShowFoldersFirst() + { + k_ShowFoldersFirst.value = !k_ShowFoldersFirst.value; + } + private static readonly Color kFadedOutAssetsColor = new Color(1, 1, 1, 0.5f); public static Color GetAssetItemColor(int instanceID) @@ -269,6 +276,8 @@ void OnEnable() SearchService.SearchService.syncSearchChanged += OnSyncSearchChanged; + k_ShowFoldersFirst.valueChanged += OnShowFoldersFirstChanged; + // Keep for debugging //EditorApplication.projectWindowItemOnGUI += TestProjectItemOverlayCallback; } @@ -289,6 +298,7 @@ void OnDisable() EditorApplication.assetLabelsChanged -= OnAssetLabelsChanged; EditorApplication.assetBundleNameChanged -= OnAssetBundleNameChanged; AssemblyReloadEvents.afterAssemblyReload -= OnAfterAssemblyReload; + k_ShowFoldersFirst.valueChanged -= OnShowFoldersFirstChanged; s_ProjectBrowsers.Remove(this); } @@ -347,6 +357,13 @@ void OnAssetBundleNameChanged() InitListArea(); } + void OnShowFoldersFirstChanged() + { + m_ListArea.foldersFirst = k_ShowFoldersFirst.value; + InitViewMode(m_ViewMode); + ResetViews(); + } + void Awake() { if (m_ListAreaState != null) @@ -516,7 +533,7 @@ public void Init() m_ListArea.allowBuiltinResources = false; m_ListArea.allowUserRenderingHook = true; m_ListArea.allowFindNextShortcut = true; - m_ListArea.foldersFirst = GetShouldShowFoldersFirst(); + m_ListArea.foldersFirst = k_ShowFoldersFirst.value; m_ListArea.repaintCallback += Repaint; m_ListArea.itemSelectedCallback += ListAreaItemSelectedCallback; m_ListArea.keyboardCallback += ListAreaKeyboardCallback; @@ -769,7 +786,7 @@ private void InitOneColumnView() m_AssetTree.dragEndedCallback += AssetTreeDragEnded; var data = new AssetsTreeViewDataSource(m_AssetTree, m_SkipHiddenPackages); - data.foldersFirst = GetShouldShowFoldersFirst(); + data.foldersFirst = k_ShowFoldersFirst.value; m_AssetTree.Init(m_TreeViewRect, data, @@ -823,11 +840,6 @@ void InitViewMode(ViewMode viewMode) maxSize = new Vector2(10000, 10000); } - private bool GetShouldShowFoldersFirst() - { - return Application.platform != RuntimePlatform.OSXEditor; - } - // Called when user changes view mode void SetViewMode(ViewMode newViewMode) { @@ -2308,6 +2320,12 @@ public virtual void AddItemsToMenu(GenericMenu menu) { if (m_EnableOldAssetTree) { + if (Application.platform == RuntimePlatform.OSXEditor) + { + GUIContent showFoldersFirstText = EditorGUIUtility.TrTextContent("Keep folders on top"); // Matches macOS preference name + menu.AddItem(showFoldersFirstText, k_ShowFoldersFirst.value, ToggleShowFoldersFirst); + } + GUIContent assetTreeText = EditorGUIUtility.TrTextContent("One Column Layout"); GUIContent assetBrowserText = EditorGUIUtility.TrTextContent("Two Column Layout"); diff --git a/Editor/Mono/RenderPipelineGraphicsSettingsCollectionPropertyDrawer.cs b/Editor/Mono/RenderPipelineGraphicsSettingsCollectionPropertyDrawer.cs index 4c042ed5fa..f4e7c537bd 100644 --- a/Editor/Mono/RenderPipelineGraphicsSettingsCollectionPropertyDrawer.cs +++ b/Editor/Mono/RenderPipelineGraphicsSettingsCollectionPropertyDrawer.cs @@ -19,6 +19,7 @@ namespace UnityEditor.Rendering.GraphicsSettingsInspectors internal class RenderPipelineGraphicsSettingsCollectionPropertyDrawer : PropertyDrawer { const string k_LineClass = "contextual-menu-button--handler"; + const string k_MoreOptionsButtonClass = "more-options-button"; const string k_GraphicsSettingsClass = "project-settings-section__graphics-settings"; const string k_GraphicsSettingsHighlightableClass = "graphics-settings__highlightable"; const string k_GraphicsSettingsContentFollowupClass = "project-settings-section__content-followup"; @@ -99,7 +100,8 @@ void ShowContextualMenu(Rect rect, List> siblings) void DrawContextualMenuButton(VisualElement root, LeafElement settingsInfo) { - var button = new Button(Background.FromTexture2D(EditorGUIUtility.LoadIcon("pane options"))); + var button = new Button(); + button.AddToClassList(k_MoreOptionsButtonClass); button.clicked += () => ShowContextualMenu(button.worldBound, settingsInfo.parent.content); root.Add(button); } diff --git a/Editor/Mono/SceneModeWindows/SceneModeUtility.cs b/Editor/Mono/SceneModeWindows/SceneModeUtility.cs index d56ef25e7d..feaaa8644b 100644 --- a/Editor/Mono/SceneModeWindows/SceneModeUtility.cs +++ b/Editor/Mono/SceneModeWindows/SceneModeUtility.cs @@ -6,6 +6,8 @@ using System.Linq; using UnityEngine; using System.Collections.Generic; +using UnityEditorInternal; +using UnityEngine.Pool; using Object = UnityEngine.Object; namespace UnityEditor @@ -182,6 +184,18 @@ public static bool StaticFlagField(string label, SerializedProperty property, in } public static bool SetStaticFlags(Object[] targetObjects, int changedFlags, bool flagValue) + { + return SetStaticFlags(targetObjects.AsSpan(), changedFlags, flagValue); + } + + internal static bool SetStaticFlags(GameObject gameObject, int changedFlags, bool flagValue) + { + using var r = new RentSpan(1); + r.Span[0] = gameObject; + return SetStaticFlags(r.Span, changedFlags, flagValue); + } + + internal static bool SetStaticFlags(ReadOnlySpan targetObjects, int changedFlags, bool flagValue) { bool allFlagsAreChanged = (changedFlags == int.MaxValue); var msgChangedFlags = changedFlags; @@ -198,23 +212,35 @@ public static bool SetStaticFlags(Object[] targetObjects, int changedFlags, bool msgChangedFlags = msgChangedFlags & allPossibleValues; } - StaticEditorFlags flag = allFlagsAreChanged ? - (StaticEditorFlags)0 : - (StaticEditorFlags)Enum.Parse(typeof(StaticEditorFlags), msgChangedFlags.ToString()); + StaticEditorFlags flag = allFlagsAreChanged ? (StaticEditorFlags)0 : (StaticEditorFlags)Enum.Parse(typeof(StaticEditorFlags), msgChangedFlags.ToString()); + + var includeChildren = GameObjectUtility.ShouldIncludeChildren.HasNoChildren; // Should we include child objects? - GameObjectUtility.ShouldIncludeChildren includeChildren = GameObjectUtility.DisplayUpdateChildrenDialogIfNeeded(targetObjects.OfType(), "Change Static Flags", - allFlagsAreChanged ? - "Do you want to " + (flagValue ? "enable" : "disable") + " the static flags for all the child objects as well?" : - "Do you want to " + (flagValue ? "enable" : "disable") + " the " + ObjectNames.NicifyVariableName(flag.ToString()) + " flag for all the child objects as well?"); + if (GameObjectUtility.HasChildren(targetObjects)) + { + includeChildren = GameObjectUtility.DisplayUpdateChildrenDialog("Change Static Flags", + allFlagsAreChanged ? "Do you want to " + (flagValue ? "enable" : "disable") + " the static flags for all the child objects as well?" : "Do you want to " + (flagValue ? "enable" : "disable") + " the " + ObjectNames.NicifyVariableName(flag.ToString()) + " flag for all the child objects as well?"); + + if (includeChildren == GameObjectUtility.ShouldIncludeChildren.Cancel) + { + EditorGUIUtility.ExitGUI(); + return false; + } + } - if (includeChildren == GameObjectUtility.ShouldIncludeChildren.Cancel) + // filter out non GameObjects in targetObjects + using var r = new RentSpan(targetObjects.Length); + int count = 0; + foreach (var obj in targetObjects) { - EditorGUIUtility.ExitGUI(); - return false; + if (obj is GameObject go) + r.Span[count++] = go; } - var objects = GetObjects(targetObjects, includeChildren == GameObjectUtility.ShouldIncludeChildren.IncludeChildren); + var targetGameObjectsSpan = r.Span[..count]; + + var objects = GetObjectsSpan(targetGameObjectsSpan, includeChildren == GameObjectUtility.ShouldIncludeChildren.IncludeChildren); Undo.RecordObjects(objects, "Change Static Flags"); // Calculate new flags value separately for each object so other flags are not affected. @@ -231,9 +257,7 @@ public static bool SetStaticFlags(Object[] targetObjects, int changedFlags, bool if (goFlags == int.MaxValue && flagValue == false) goFlags = (int)Math.Pow(2, Enum.GetNames(typeof(StaticEditorFlags)).Length - 1) - 1; - goFlags = flagValue ? - goFlags | changedFlags : - goFlags & ~changedFlags; + goFlags = flagValue ? goFlags | changedFlags : goFlags & ~changedFlags; GameObjectUtility.SetStaticEditorFlags(go, (StaticEditorFlags)goFlags); } @@ -248,8 +272,11 @@ static void GetObjectsRecurse(Transform root, List arr) } public static GameObject[] GetObjects(Object[] gameObjects, bool includeChildren) + => GetObjectsSpan(gameObjects.OfType().ToArray(), includeChildren); + + internal static GameObject[] GetObjectsSpan(ReadOnlySpan gameObjects, bool includeChildren) { - List allObjects = new List(); + using var pooledList = ListPool.Get(out var allObjects); if (!includeChildren) { foreach (GameObject go in gameObjects) @@ -262,5 +289,31 @@ public static GameObject[] GetObjects(Object[] gameObjects, bool includeChildren } return allObjects.ToArray(); } + + internal static void SetLayer(GameObject gameObject, int value, string targetTitle) + { + using var r = new RentSpan(1); + r.Span[0] = gameObject; + SetLayer(r.Span, value, targetTitle); + } + + internal static void SetLayer(ReadOnlySpan gameObjects, int layer, string targetTitle) + { + var includeChildren = GameObjectUtility.ShouldIncludeChildren.HasNoChildren; + + if (GameObjectUtility.HasChildren(gameObjects)) + { + includeChildren = GameObjectUtility.DisplayUpdateChildrenDialog(L10n.Tr("Change Layer"), string.Format(L10n.Tr("Do you want to set layer to {0} for all child objects as well?"), InternalEditorUtility.GetLayerName(layer))); + if (includeChildren == GameObjectUtility.ShouldIncludeChildren.Cancel) + return; + } + + var objects = GetObjectsSpan(gameObjects, includeChildren is GameObjectUtility.ShouldIncludeChildren.IncludeChildren); + Undo.RecordObjects(objects, "Change Layer of " + targetTitle); + foreach (var o in objects) + { + o.layer = layer; + } + } } } diff --git a/Editor/Mono/SceneView/SceneView.cs b/Editor/Mono/SceneView/SceneView.cs index 2484720459..487a0d83be 100644 --- a/Editor/Mono/SceneView/SceneView.cs +++ b/Editor/Mono/SceneView/SceneView.cs @@ -464,8 +464,8 @@ public bool sceneLighting // used by tests internal bool m_WasFocused = false; - static int[] s_CachedParentRenderersForOutlining, s_CachedChildRenderersForOutlining; - static HashSet s_CachedChildRenderersForOutliningHashSet; + static EntityId[] s_CachedParentRenderersForOutlining, s_CachedChildRenderersForOutlining; + static HashSet s_CachedChildRenderersForOutliningHashSet; [Serializable] public class SceneViewState @@ -2335,7 +2335,7 @@ private void DoDrawCamera(Rect windowSpaceCameraRect, Rect groupSpaceCameraRect, { if (s_SelectionCacheDirty) { - HandleUtility.FilterInstanceIDs(Selection.gameObjects, out s_CachedParentRenderersForOutlining, out s_CachedChildRenderersForOutlining, out s_CachedChildRenderersForOutliningHashSet); + HandleUtility.FilterEntityIds(Selection.gameObjects, out s_CachedParentRenderersForOutlining, out s_CachedChildRenderersForOutlining, out s_CachedChildRenderersForOutliningHashSet); s_SelectionCacheDirty = false; } @@ -2454,7 +2454,7 @@ void RenderFilteredScene(Rect groupSpaceCameraRect) { if (s_SelectionCacheDirty) { - HandleUtility.FilterInstanceIDs(Selection.gameObjects, out s_CachedParentRenderersForOutlining, out s_CachedChildRenderersForOutlining, out s_CachedChildRenderersForOutliningHashSet); + HandleUtility.FilterEntityIds(Selection.gameObjects, out s_CachedParentRenderersForOutlining, out s_CachedChildRenderersForOutlining, out s_CachedChildRenderersForOutliningHashSet); s_SelectionCacheDirty = false; } diff --git a/Editor/Mono/Scripting/ScriptCompilation/VersionDefinesConsoleLogs.bindings.cs b/Editor/Mono/Scripting/ScriptCompilation/VersionDefinesConsoleLogs.bindings.cs index 3e036dde38..7db54b1ae1 100644 --- a/Editor/Mono/Scripting/ScriptCompilation/VersionDefinesConsoleLogs.bindings.cs +++ b/Editor/Mono/Scripting/ScriptCompilation/VersionDefinesConsoleLogs.bindings.cs @@ -21,7 +21,7 @@ class VersionDefinesConsoleLogs : IVersionDefinesConsoleLogs public void LogVersionDefineError(TargetAssembly targetAssembly, ExpressionNotValidException validationError) { var asset = AssetDatabase.LoadAssetAtPath(EditorCompilationInterface.Instance.FindCustomTargetAssemblyFromTargetAssembly(targetAssembly).FilePath); - var instanceID = asset.GetInstanceID(); + var instanceID = asset.GetEntityId(); InternalLogVersionDefineError(validationError, instanceID); } @@ -31,7 +31,7 @@ public void ClearVersionDefineErrors() } [FreeFunction(nameof(InternalLogVersionDefineError))] - static extern void InternalLogVersionDefineError(Exception ex, int assetInstanceID); + static extern void InternalLogVersionDefineError(Exception ex, UnityEngine.EntityId assetInstanceID); [FreeFunction(nameof(InternalClearVersionDefineErrors))] diff --git a/Editor/Mono/SerializedProperty.bindings.cs b/Editor/Mono/SerializedProperty.bindings.cs index 7142991986..6b148f1dc6 100644 --- a/Editor/Mono/SerializedProperty.bindings.cs +++ b/Editor/Mono/SerializedProperty.bindings.cs @@ -1438,7 +1438,7 @@ public int objectReferenceInstanceIDValue private extern int GetPPtrValueFromInstanceIDInternal(); [FreeFunction(Name = "SerializedPropertyBindings::SetPPtrValueFromInstanceIDInternal", HasExplicitThis = true)] - private extern void SetPPtrValueFromInstanceIDInternal(int instanceID); + private extern void SetPPtrValueFromInstanceIDInternal(EntityId instanceID); internal string objectReferenceStringValue { diff --git a/Editor/Mono/StateMachine.bindings.cs b/Editor/Mono/StateMachine.bindings.cs index 791852a8b9..48cd70bdd0 100644 --- a/Editor/Mono/StateMachine.bindings.cs +++ b/Editor/Mono/StateMachine.bindings.cs @@ -200,7 +200,7 @@ extern public bool timeParameterActive set; } - extern internal void AddBehaviour(int instanceID); + extern internal void AddBehaviour(EntityId instanceID); extern internal void RemoveBehaviour(int index); extern public AnimatorStateTransition[] transitions { get; set; } @@ -291,7 +291,7 @@ extern public AnimatorState defaultState extern public void SetStateMachineTransitions(AnimatorStateMachine sourceStateMachine, AnimatorTransition[] transitions); - extern internal void AddBehaviour(int instanceID); + extern internal void AddBehaviour(EntityId instanceID); extern internal void RemoveBehaviour(int index); [FreeFunction(Name = "ScriptingAddStateMachineBehaviourWithType", HasExplicitThis = true)] diff --git a/Editor/Mono/Tools/EditorToolManager.cs b/Editor/Mono/Tools/EditorToolManager.cs index ac028c6cdd..cc71ee68a7 100644 --- a/Editor/Mono/Tools/EditorToolManager.cs +++ b/Editor/Mono/Tools/EditorToolManager.cs @@ -13,6 +13,14 @@ namespace UnityEditor.EditorTools { + [Icon(k_IconPath)] + public sealed class CreationToolsGroup + { + const string k_IconPath = "Icons/Toolbars/CreationToolsGroup.png"; + internal static readonly string k_Tooltip = L10n.Tr("Creation Tools"); + CreationToolsGroup() {} + } + sealed class EditorToolManager : ScriptableSingleton { [SerializeField] @@ -841,24 +849,55 @@ void AddToolEntry(Type tool, ToolEntry.Scope scope) foreach(var global in EditorToolUtility.GetCustomEditorToolsForType(null)) if (global.targetContext == null || global.targetContext == ToolManager.activeContextType) AddToolEntry(global.editor, global.group == null ? ToolEntry.Scope.CustomGlobal : ToolEntry.Scope.Grouped); - + // 4. component tools foreach (var tool in instance.componentTools) if ((tool.typeAssociation.targetContext == null || tool.typeAssociation.targetContext == context.GetType()) + && tool.editorType != null // The editor type can be null on domain reload after renaming an EditorTool (UUM-113403) && !tool.lockedInspector && !tools.Any(entry => entry.tools.Any(x => x == tool.editor))) AddToolEntry(tool.editorType, tool.typeAssociation.group == null ? ToolEntry.Scope.Component : ToolEntry.Scope.Grouped); } - internal static List OrderAvailableTools(List tools) + internal static void OrderAvailableTools(List tools) { - return tools.OrderBy(x => x.scope) // Group by scope (Built-in, additional, global, grouped, component) - .ThenBy(x => (x.group == null ? string.Empty : x.group.Name)) // Ensure tools of same group stay adjacent - .ThenBy(x => (x.targetBehaviour == null ? string.Empty : x.targetBehaviour.Name)) // Ensure tools targeting same components stay adjacent - .ThenBy(x => x.priority) - .ThenBy(x => x.GetHashCode()) - .ToList(); + tools.Sort((a, b) => + { + // Sort by scope first + var result = a.scope.CompareTo(b.scope); + if (result != 0) + return result; + + // For tool groups, ensure CreationToolGroups appears first + if (a.scope == ToolEntry.Scope.Grouped && b.scope == ToolEntry.Scope.Grouped) + { + if (a.group == typeof(CreationToolsGroup) && b.group != typeof(CreationToolsGroup)) + return -1; + if (a.group != typeof(CreationToolsGroup) && b.group == typeof(CreationToolsGroup)) + return 1; + } + + // Ensure tools of same group stay adjacent + result = String.Compare(a.group == null ? string.Empty : a.group.Name, + b.group == null ? string.Empty : b.group.Name, StringComparison.Ordinal); + if (result != 0) + return result; + + // Ensure tools targeting same components stay adjacent + result = String.Compare(a.targetBehaviour == null ? string.Empty : a.targetBehaviour.Name, + b.targetBehaviour == null ? string.Empty : b.targetBehaviour.Name, StringComparison.Ordinal); + if (result != 0) + return result; + + // Sort by priority next + result = a.priority.CompareTo(b.priority); + if (result != 0) + return result; + + // Finally by hash code + return a.GetHashCode().CompareTo(b.GetHashCode()); + }); } } } diff --git a/Editor/Mono/UIElements/BaseLiveReloadAssetTracker.cs b/Editor/Mono/UIElements/BaseLiveReloadAssetTracker.cs index f893106c6e..dd59a6e282 100644 --- a/Editor/Mono/UIElements/BaseLiveReloadAssetTracker.cs +++ b/Editor/Mono/UIElements/BaseLiveReloadAssetTracker.cs @@ -71,6 +71,16 @@ public bool IsTrackingAsset(T asset) return m_TrackedAssets.ContainsKey(asset.GetInstanceID()); } + public bool IsTrackingAsset(string assetPath) + { + foreach (var value in m_TrackedAssets.Values) + { + if (value.m_AssetPath == assetPath) + return true; + } + return false; + } + public bool IsTrackingAssets() { return m_TrackedAssets.Count > 0; diff --git a/Editor/Mono/UIElements/Controls/ColorField.cs b/Editor/Mono/UIElements/Controls/ColorField.cs index d2acecafae..90d148f86b 100644 --- a/Editor/Mono/UIElements/Controls/ColorField.cs +++ b/Editor/Mono/UIElements/Controls/ColorField.cs @@ -160,7 +160,6 @@ public bool hdr bool m_ShowAlpha; bool m_ShowEyeDropper; bool m_HDR; - Color m_ColorBeforeEyeDrop; IVisualElementScheduledItem m_EyeDropperScheduler; Label m_HDRLabel; @@ -352,44 +351,61 @@ void OnEyeDropperClicked(PointerDownEvent evt) if (EyeDropper.IsOpened || evt.button != (int)MouseButton.LeftMouse) return; - m_ColorBeforeEyeDrop = value; - EyeDropper.Start(UpdateColorProperties); - m_EyeDropperScheduler = schedule.Execute(OnEyeDropperMove).Every(10).StartingIn(10) + EyeDropper.Start(OnEyeDropperColorSelected); + m_EyeDropperScheduler = schedule + .Execute(OnEyeDropperMove) + .Every(10) + .StartingIn(10) .Until(ShouldStopWatchingEyeDropper); evt.StopPropagation(); } - bool ShouldStopWatchingEyeDropper() + void OnEyeDropperMove(TimerState state) { - if (EyeDropper.IsOpened) - return false; - if (EyeDropper.IsCancelled) + if (!EyeDropper.IsOpened) + return; + + var pickerColor = CorrectPickedColorAlpha(EyeDropper.GetPickedColor()); + if (pickerColor != value) + UpdateColorProperties(pickerColor); + } + + void OnEyeDropperColorSelected(Color pickedColor) + { + var newValue = CorrectPickedColorAlpha(pickedColor); + value = newValue; + UpdateColorProperties(value); + } + + private Color CorrectPickedColorAlpha(Color pickedColor) + { + if (setAlphaIfTransparentWhenPicked && Mathf.Approximately(value.a, 0.0f)) { - value = m_ColorBeforeEyeDrop; - UpdateColorProperties(value); + pickedColor.a = 1.0f; } else { - var pickedColor = EyeDropper.GetPickedColor(); - - if (setAlphaIfTransparentWhenPicked && value.a == 0) - { - pickedColor.a = 1.0f; - } // Eyedropper color picking should not impact the previous color alpha. - else - { - pickedColor.a = value.a; - } - - value = pickedColor; + pickedColor.a = value.a; } + return pickedColor; + } + + bool ShouldStopWatchingEyeDropper() + { + if (EyeDropper.IsOpened) + return false; + if (m_EyeDropperScheduler != null) { m_EyeDropperScheduler.Pause(); m_EyeDropperScheduler = null; } + + // Make sure the UI is updated with the final picked color. + // or if canceled, revert the UI to the original color as the value was never changed. + UpdateColorProperties(value); return true; } @@ -404,7 +420,7 @@ void OnCommandExecute(ExecuteCommandEvent evt) void UpdateColorProperties(Color color) { - if (panel == null || showMixedValue) + if (panel == null || (showMixedValue && !EyeDropper.IsOpened)) return; if (m_AlphaElement != null) @@ -447,25 +463,6 @@ void UpdateColorProperties(Color color) m_ColorElement.style.backgroundColor = color; } - void OnEyeDropperMove(TimerState state) - { - var pickerColor = EyeDropper.GetPickedColor(); - if (pickerColor != value) - { - if (setAlphaIfTransparentWhenPicked && value.a == 0) - { - pickerColor.a = 1.0f; - } - // Eyedropper color picking should not impact the previous color alpha. - else - { - pickerColor.a = rawValue.a; - } - - UpdateColorProperties(pickerColor); - } - } - void OnAttach(AttachToPanelEvent evt) { UpdateColorProperties(value); @@ -475,21 +472,29 @@ protected override void UpdateMixedValueContent() { m_ColorElement.EnableInClassList(mixedValueColorUssClassName, showMixedValue); + mixedValueLabel.style.display = DisplayStyle.None; + m_GradientContainer.style.display = DisplayStyle.None; + m_AlphaGradientContainer.style.display = DisplayStyle.None; + m_AlphaElement.style.display = DisplayStyle.None; + m_HDRLabel.style.display = DisplayStyle.None; + if (showMixedValue) { mixedValueLabel.style.display = DisplayStyle.Flex; - m_GradientContainer.style.display = DisplayStyle.None; - m_AlphaGradientContainer.style.display = DisplayStyle.None; - m_AlphaElement.style.display = DisplayStyle.None; - m_HDRLabel.style.display = DisplayStyle.None; } else { - mixedValueLabel.style.display = DisplayStyle.None; - m_GradientContainer.style.display = hdr ? DisplayStyle.Flex : DisplayStyle.None; - m_AlphaGradientContainer.style.display = hdr ? DisplayStyle.Flex : DisplayStyle.None; - m_AlphaElement.style.display = showAlpha ? DisplayStyle.Flex : DisplayStyle.None; - m_HDRLabel.style.display = hdr ? DisplayStyle.Flex : DisplayStyle.None; + if (hdr) + { + m_GradientContainer.style.display = DisplayStyle.Flex; + m_AlphaGradientContainer.style.display = DisplayStyle.Flex; + m_HDRLabel.style.display = DisplayStyle.Flex; + } + + if (showAlpha) + { + m_AlphaElement.style.display = DisplayStyle.Flex; + } UpdateColorProperties(value); } diff --git a/Editor/Mono/UIElements/Controls/PropertyField.cs b/Editor/Mono/UIElements/Controls/PropertyField.cs index cc62d78534..1a3bc848b7 100644 --- a/Editor/Mono/UIElements/Controls/PropertyField.cs +++ b/Editor/Mono/UIElements/Controls/PropertyField.cs @@ -693,10 +693,7 @@ private VisualElement CreateFoldout(SerializedProperty property, object original foldout.bindingPath = property.propertyPath; foldout.name = "unity-foldout-" + property.propertyPath; - // Make PropertyField foldout react even when disabled, like EditorGUILayout.Foldout. var foldoutToggle = foldout.Q(className: Foldout.toggleUssClassName); - foldoutToggle.acceptClicksIfDisabled = true; - // Get Foldout label. var foldoutLabel = foldoutToggle.Q