From 14a7d93a42d4562daefa4c1cec29675d40b2b40b Mon Sep 17 00:00:00 2001 From: NoiseCrime Date: Tue, 23 Mar 2021 18:49:53 +0000 Subject: [PATCH] Initial Upload --- .editorconfig | 73 +++ .gitignore | 37 ++ Assets/NoiseCrimeStudios.meta | 9 + Assets/NoiseCrimeStudios/Core.meta | 9 + Assets/NoiseCrimeStudios/Core/Extensions.meta | 9 + .../Core/Extensions/LinqExtensions.cs | 29 + .../Core/Extensions/LinqExtensions.cs.meta | 12 + Assets/NoiseCrimeStudios/Core/Formatting.meta | 9 + .../Core/Formatting/Numerical.cs | 142 +++++ .../Core/Formatting/Numerical.cs.meta | 12 + Assets/NoiseCrimeStudios/Core/IO.meta | 9 + .../Core/IO/DirectoryCopy.cs | 85 +++ .../Core/IO/DirectoryCopy.cs.meta | 12 + .../Core/IO/DirectoryUtil.cs | 312 ++++++++++ .../Core/IO/DirectoryUtil.cs.meta | 11 + Assets/NoiseCrimeStudios/Core/IO/PathUtils.cs | 116 ++++ .../Core/IO/PathUtils.cs.meta | 11 + .../Core/IO/ValidationOfFilePaths.cs | 127 ++++ .../Core/IO/ValidationOfFilePaths.cs.meta | 11 + Assets/NoiseCrimeStudios/Core/Unity.meta | 9 + .../Core/Unity/UnityConsoleHelper.cs | 56 ++ .../Core/Unity/UnityConsoleHelper.cs.meta | 8 + Assets/NoiseCrimeStudios/Core/Utilities.meta | 9 + .../Core/Utilities/StringBuilderDebugLog.cs | 204 +++++++ .../Utilities/StringBuilderDebugLog.cs.meta | 11 + Assets/NoiseCrimeStudios/Editor.meta | 9 + Assets/NoiseCrimeStudios/Editor/Internal.meta | 8 + .../Editor/Internal/InternalDebugIMGUI.cs | 35 ++ .../Internal/InternalDebugIMGUI.cs.meta | 11 + .../Editor/Internal/InternalDebugUndo.cs | 22 + .../Editor/Internal/InternalDebugUndo.cs.meta | 11 + .../Editor/Internal/InternalScreenShotting.cs | 93 +++ .../Internal/InternalScreenShotting.cs.meta | 11 + .../Editor/NoiseCrimeStudioToolEnum.cs | 77 +++ .../Editor/NoiseCrimeStudioToolEnum.cs.meta | 12 + .../NoiseCrimeStudios/Editor/Resources.meta | 9 + .../Editor/Resources/GoogleMaterialIcons.meta | 9 + .../baseline_cancel_black_18dp_1x.png | Bin 0 -> 265 bytes .../baseline_cancel_black_18dp_1x.png.meta | 59 ++ .../baseline_cancel_black_18dp_x2.png | Bin 0 -> 411 bytes .../baseline_cancel_black_18dp_x2.png.meta | 59 ++ .../baseline_cancel_white_18dp_1x.png | Bin 0 -> 267 bytes .../baseline_cancel_white_18dp_1x.png.meta | 59 ++ .../baseline_cancel_white_18dp_2x.png | Bin 0 -> 413 bytes .../baseline_cancel_white_18dp_2x.png.meta | 59 ++ .../baseline_check_circle_black_18dp_1x.png | Bin 0 -> 254 bytes ...seline_check_circle_black_18dp_1x.png.meta | 59 ++ .../baseline_check_circle_black_18dp_2x.png | Bin 0 -> 402 bytes ...seline_check_circle_black_18dp_2x.png.meta | 59 ++ .../baseline_check_circle_white_18dp_1x.png | Bin 0 -> 261 bytes ...seline_check_circle_white_18dp_1x.png.meta | 59 ++ .../baseline_check_circle_white_18dp_2x.png | Bin 0 -> 398 bytes ...seline_check_circle_white_18dp_2x.png.meta | 59 ++ .../ic_add_box_black_18dp_1x.png | Bin 0 -> 139 bytes .../ic_add_box_black_18dp_1x.png.meta | 59 ++ .../ic_add_box_black_18dp_2x.png | Bin 0 -> 189 bytes .../ic_add_box_black_18dp_2x.png.meta | 59 ++ .../ic_add_box_white_18dp_1x.png | Bin 0 -> 142 bytes .../ic_add_box_white_18dp_1x.png.meta | 59 ++ .../ic_add_box_white_18dp_2x.png | Bin 0 -> 193 bytes .../ic_add_box_white_18dp_2x.png.meta | 59 ++ .../ic_file_download_black_18dp_1x.png | Bin 0 -> 136 bytes .../ic_file_download_black_18dp_1x.png.meta | 59 ++ .../ic_file_download_black_18dp_2x.png | Bin 0 -> 148 bytes .../ic_file_download_black_18dp_2x.png.meta | 59 ++ .../ic_file_download_white_18dp_1x.png | Bin 0 -> 139 bytes .../ic_file_download_white_18dp_1x.png.meta | 59 ++ .../ic_file_download_white_18dp_2x.png | Bin 0 -> 163 bytes .../ic_file_download_white_18dp_2x.png.meta | 59 ++ .../ic_folder_black_18dp_1x.png | Bin 0 -> 99 bytes .../ic_folder_black_18dp_1x.png.meta | 59 ++ .../ic_folder_black_18dp_2x.png | Bin 0 -> 131 bytes .../ic_folder_black_18dp_2x.png.meta | 59 ++ .../ic_folder_white_18dp_1x.png | Bin 0 -> 100 bytes .../ic_folder_white_18dp_1x.png.meta | 59 ++ .../ic_folder_white_18dp_2x.png | Bin 0 -> 135 bytes .../ic_folder_white_18dp_2x.png.meta | 59 ++ .../ic_info_outline_black_18dp_1x.png | Bin 0 -> 254 bytes .../ic_info_outline_black_18dp_1x.png.meta | 59 ++ .../ic_info_outline_black_18dp_2x.png | Bin 0 -> 487 bytes .../ic_info_outline_black_18dp_2x.png.meta | 59 ++ .../ic_info_outline_white_18dp_1x.png | Bin 0 -> 271 bytes .../ic_info_outline_white_18dp_1x.png.meta | 59 ++ .../ic_info_outline_white_18dp_2x.png | Bin 0 -> 485 bytes .../ic_info_outline_white_18dp_2x.png.meta | 59 ++ .../ic_pin_drop_black_18dp_1x.png | Bin 0 -> 212 bytes .../ic_pin_drop_black_18dp_1x.png.meta | 59 ++ .../ic_pin_drop_black_18dp_2x.png | Bin 0 -> 328 bytes .../ic_pin_drop_black_18dp_2x.png.meta | 59 ++ .../ic_pin_drop_white_18dp_1x.png | Bin 0 -> 215 bytes .../ic_pin_drop_white_18dp_1x.png.meta | 59 ++ .../ic_pin_drop_white_18dp_2x.png | Bin 0 -> 330 bytes .../ic_pin_drop_white_18dp_2x.png.meta | 59 ++ .../ic_square_white_18dp_1x.png | Bin 0 -> 81 bytes .../ic_square_white_18dp_1x.png.meta | 100 ++++ .../ic_square_white_18dp_2x.png | Bin 0 -> 139 bytes .../ic_square_white_18dp_2x.png.meta | 100 ++++ .../ic_star_black_18dp_1x.png | Bin 0 -> 217 bytes .../ic_star_black_18dp_1x.png.meta | 59 ++ .../ic_star_black_18dp_2x.png | Bin 0 -> 369 bytes .../ic_star_black_18dp_2x.png.meta | 59 ++ .../ic_star_border_black_18dp_1x.png | Bin 0 -> 253 bytes .../ic_star_border_black_18dp_1x.png.meta | 59 ++ .../ic_star_border_black_18dp_2x.png | Bin 0 -> 500 bytes .../ic_star_border_black_18dp_2x.png.meta | 59 ++ .../ic_star_border_white_18dp_1x.png | Bin 0 -> 269 bytes .../ic_star_border_white_18dp_1x.png.meta | 59 ++ .../ic_star_border_white_18dp_2x.png | Bin 0 -> 504 bytes .../ic_star_border_white_18dp_2x.png.meta | 59 ++ .../ic_star_white_18dp_1x.png | Bin 0 -> 221 bytes .../ic_star_white_18dp_1x.png.meta | 59 ++ .../ic_star_white_18dp_2x.png | Bin 0 -> 370 bytes .../ic_star_white_18dp_2x.png.meta | 59 ++ Assets/NoiseCrimeStudios/Editor/Support.meta | 9 + .../Editor/Support/EditorGUI.meta | 9 + .../EditorGUI/EditorGUIClippedScrollView.cs | 56 ++ .../EditorGUIClippedScrollView.cs.meta | 11 + .../Support/EditorGUI/EditorGUIMethods.cs | 101 ++++ .../EditorGUI/EditorGUIMethods.cs.meta | 10 + .../Support/EditorGUI/EditorGUIStyles.cs | 161 ++++++ .../Support/EditorGUI/EditorGUIStyles.cs.meta | 12 + Assets/NoiseCrimeStudiosToolbox.meta | 9 + Assets/NoiseCrimeStudiosToolbox/Editor.meta | 9 + .../Editor/AssetStoreOrganizer.meta | 9 + .../AssetStoreOrganizer/AssetPackage.cs | 246 ++++++++ .../AssetStoreOrganizer/AssetPackage.cs.meta | 12 + .../AssetStoreOrganizer/OrganizerArchiver.cs | 288 ++++++++++ .../OrganizerArchiver.cs.meta | 12 + .../AssetStoreOrganizer/OrganizerEditor.cs | 544 ++++++++++++++++++ .../OrganizerEditor.cs.meta | 12 + .../AssetStoreOrganizer/OrganizerMethods.cs | 74 +++ .../OrganizerMethods.cs.meta | 12 + .../OrganizerOptionsPopup.cs | 47 ++ .../OrganizerOptionsPopup.cs.meta | 12 + .../AssetStoreOrganizer/OrganizerPaths.cs | 135 +++++ .../OrganizerPaths.cs.meta | 12 + .../AssetStoreOrganizer/PackageFilters.cs | 249 ++++++++ .../PackageFilters.cs.meta | 12 + .../AssetStoreOrganizer/PackageLibrary.cs | 231 ++++++++ .../PackageLibrary.cs.meta | 12 + ProjectSettings/AudioManager.asset | Bin 0 -> 4140 bytes ProjectSettings/ClusterInputManager.asset | Bin 0 -> 4104 bytes ProjectSettings/DynamicsManager.asset | Bin 0 -> 4280 bytes ProjectSettings/EditorBuildSettings.asset | Bin 0 -> 4104 bytes ProjectSettings/EditorSettings.asset | Bin 0 -> 4168 bytes ProjectSettings/GraphicsSettings.asset | Bin 0 -> 4390 bytes ProjectSettings/InputManager.asset | Bin 0 -> 5520 bytes ProjectSettings/NavMeshAreas.asset | Bin 0 -> 4460 bytes ProjectSettings/NetworkManager.asset | Bin 0 -> 4112 bytes ProjectSettings/Physics2DSettings.asset | Bin 0 -> 4380 bytes ProjectSettings/ProjectSettings.asset | Bin 0 -> 54050 bytes ProjectSettings/ProjectVersion.txt | 1 + ProjectSettings/QualitySettings.asset | Bin 0 -> 5000 bytes ProjectSettings/TagManager.asset | Bin 0 -> 4308 bytes ProjectSettings/TimeManager.asset | Bin 0 -> 4116 bytes ProjectSettings/UnityConnectSettings.asset | Bin 0 -> 4216 bytes README.md | 159 +++++ Screenshots/OrganizerEditor000.png | Bin 0 -> 138585 bytes Screenshots/OrganizerEditor001.png | Bin 0 -> 135733 bytes 159 files changed, 6429 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 Assets/NoiseCrimeStudios.meta create mode 100644 Assets/NoiseCrimeStudios/Core.meta create mode 100644 Assets/NoiseCrimeStudios/Core/Extensions.meta create mode 100644 Assets/NoiseCrimeStudios/Core/Extensions/LinqExtensions.cs create mode 100644 Assets/NoiseCrimeStudios/Core/Extensions/LinqExtensions.cs.meta create mode 100644 Assets/NoiseCrimeStudios/Core/Formatting.meta create mode 100644 Assets/NoiseCrimeStudios/Core/Formatting/Numerical.cs create mode 100644 Assets/NoiseCrimeStudios/Core/Formatting/Numerical.cs.meta create mode 100644 Assets/NoiseCrimeStudios/Core/IO.meta create mode 100644 Assets/NoiseCrimeStudios/Core/IO/DirectoryCopy.cs create mode 100644 Assets/NoiseCrimeStudios/Core/IO/DirectoryCopy.cs.meta create mode 100644 Assets/NoiseCrimeStudios/Core/IO/DirectoryUtil.cs create mode 100644 Assets/NoiseCrimeStudios/Core/IO/DirectoryUtil.cs.meta create mode 100644 Assets/NoiseCrimeStudios/Core/IO/PathUtils.cs create mode 100644 Assets/NoiseCrimeStudios/Core/IO/PathUtils.cs.meta create mode 100644 Assets/NoiseCrimeStudios/Core/IO/ValidationOfFilePaths.cs create mode 100644 Assets/NoiseCrimeStudios/Core/IO/ValidationOfFilePaths.cs.meta create mode 100644 Assets/NoiseCrimeStudios/Core/Unity.meta create mode 100644 Assets/NoiseCrimeStudios/Core/Unity/UnityConsoleHelper.cs create mode 100644 Assets/NoiseCrimeStudios/Core/Unity/UnityConsoleHelper.cs.meta create mode 100644 Assets/NoiseCrimeStudios/Core/Utilities.meta create mode 100644 Assets/NoiseCrimeStudios/Core/Utilities/StringBuilderDebugLog.cs create mode 100644 Assets/NoiseCrimeStudios/Core/Utilities/StringBuilderDebugLog.cs.meta create mode 100644 Assets/NoiseCrimeStudios/Editor.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Internal.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Internal/InternalDebugIMGUI.cs create mode 100644 Assets/NoiseCrimeStudios/Editor/Internal/InternalDebugIMGUI.cs.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Internal/InternalDebugUndo.cs create mode 100644 Assets/NoiseCrimeStudios/Editor/Internal/InternalDebugUndo.cs.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Internal/InternalScreenShotting.cs create mode 100644 Assets/NoiseCrimeStudios/Editor/Internal/InternalScreenShotting.cs.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/NoiseCrimeStudioToolEnum.cs create mode 100644 Assets/NoiseCrimeStudios/Editor/NoiseCrimeStudioToolEnum.cs.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_black_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_black_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_black_18dp_x2.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_black_18dp_x2.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_white_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_white_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_white_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_white_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_black_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_black_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_black_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_black_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_white_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_white_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_white_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_white_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_black_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_black_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_black_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_black_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_white_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_white_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_white_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_white_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_black_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_black_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_black_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_black_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_white_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_white_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_white_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_white_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_folder_black_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_folder_black_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_folder_black_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_folder_black_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_folder_white_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_folder_white_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_folder_white_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_folder_white_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_black_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_black_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_black_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_black_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_white_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_white_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_white_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_white_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_pin_drop_black_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_pin_drop_black_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_pin_drop_black_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_pin_drop_black_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_pin_drop_white_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_pin_drop_white_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_pin_drop_white_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_pin_drop_white_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_square_white_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_square_white_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_square_white_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_square_white_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_black_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_black_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_black_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_black_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_border_black_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_border_black_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_border_black_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_border_black_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_border_white_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_border_white_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_border_white_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_border_white_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_white_18dp_1x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_white_18dp_1x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_white_18dp_2x.png create mode 100644 Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_white_18dp_2x.png.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Support.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Support/EditorGUI.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIClippedScrollView.cs create mode 100644 Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIClippedScrollView.cs.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIMethods.cs create mode 100644 Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIMethods.cs.meta create mode 100644 Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIStyles.cs create mode 100644 Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIStyles.cs.meta create mode 100644 Assets/NoiseCrimeStudiosToolbox.meta create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor.meta create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer.meta create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/AssetPackage.cs create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/AssetPackage.cs.meta create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerArchiver.cs create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerArchiver.cs.meta create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerEditor.cs create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerEditor.cs.meta create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerMethods.cs create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerMethods.cs.meta create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerOptionsPopup.cs create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerOptionsPopup.cs.meta create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerPaths.cs create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerPaths.cs.meta create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/PackageFilters.cs create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/PackageFilters.cs.meta create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/PackageLibrary.cs create mode 100644 Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/PackageLibrary.cs.meta create mode 100644 ProjectSettings/AudioManager.asset create mode 100644 ProjectSettings/ClusterInputManager.asset create mode 100644 ProjectSettings/DynamicsManager.asset create mode 100644 ProjectSettings/EditorBuildSettings.asset create mode 100644 ProjectSettings/EditorSettings.asset create mode 100644 ProjectSettings/GraphicsSettings.asset create mode 100644 ProjectSettings/InputManager.asset create mode 100644 ProjectSettings/NavMeshAreas.asset create mode 100644 ProjectSettings/NetworkManager.asset create mode 100644 ProjectSettings/Physics2DSettings.asset create mode 100644 ProjectSettings/ProjectSettings.asset create mode 100644 ProjectSettings/ProjectVersion.txt create mode 100644 ProjectSettings/QualitySettings.asset create mode 100644 ProjectSettings/TagManager.asset create mode 100644 ProjectSettings/TimeManager.asset create mode 100644 ProjectSettings/UnityConnectSettings.asset create mode 100644 README.md create mode 100644 Screenshots/OrganizerEditor000.png create mode 100644 Screenshots/OrganizerEditor001.png diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f269ed3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,73 @@ +# see http://editorconfig.org/ for docs on this file + +root = true + +[*] +# help with sharing files across os's (i.e. network share or through local vm) +#end_of_line = lf +#charset temporarily disabled due to bug in VS2017 changing to UTF-8 with BOM (https://favro.com/card/c564ede4ed3337f7b17986b6/Uni-17877) +#charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +# formattable file extensions (keep in sync with format.ini from unity-meta repo) +# +# Note: We need to split the formattable files configs into shorter duplicate entries (logically grouped) +# due to known issue in VS editorconfig extension where there is a limit of 51 characters (empirically determined). +# see: https://github.com/editorconfig/editorconfig-visualstudio/issues/21 +# +## uncrustify +[*.{c,h,cpp,hpp,m,mm,cc,cs}] +indent_style = space +indent_size = 4 + +## generic formatter (shaders) +[*.{cg,cginc,glslinc,hlsl,shader,y,ypp,yy}] +indent_style = space +indent_size = 4 + +## generic formatter (misc) +[*.{asm,s,S,pch,pchmm,java,sh,uss}] +indent_style = space +indent_size = 4 + +## perltidy +[*.{pl,pm,t,it}] +indent_style = space +indent_size = 4 + +## unity special +[*.{bindings,mem.xml}] +indent_style = space +indent_size = 4 + +# other filetypes we want to overwrite default configuration to preserve the standard +[{Makefile,makefile}] +# TAB characters are part of the Makefile format +indent_style = tab + +[*.{md,markdown}] +# trailing whitespace is significant in markdown (bad choice, bad!) +trim_trailing_whitespace = false + +# keep these and the VS stuff below in sync with .hgeol's CRLF extensions +[*.{vcproj,bat,cmd,xaml,tt,t4,ttinclude}] +end_of_line = crlf + +# this VS-specific stuff is based on experiments to see how VS will modify a file after it has been manually edited. +# the settings are meant to closely match what VS does to minimize unnecessary diffs. this duplicates some settings in * +# but let's be explicit here to be safe (in case someone wants to copy-paste this out to another .editorconfig). +[*.{vcxproj,vcxproj.filters,csproj,props,targets}] +indent_style = space +indent_size = 2 +end_of_line = crlf +charset = utf-8-bom +trim_trailing_whitespace = true +insert_final_newline = false +[*.{sln,sln.template}] +indent_style = tab +indent_size = 4 +end_of_line = crlf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = false \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..884376f --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +/[Ll]ibrary/ +/[Tt]emp/ +/[Oo]bj/ +/[Bb]uild/ +/[Bb]uilds/ +/Assets/AssetStoreTools* +**/Excluded/ +**/Excluded.meta + + +# Visual Studio 2015 cache directory +/.vs/ + +# Autogenerated VS/MD/Consulo solution and project files +ExportedObj/ +.consulo/ +*.csproj +*.unityproj +*.sln +*.suo +*.tmp +*.user +*.userprefs +*.pidb +*.booproj +*.svd +*.pdb + +# Unity3D generated meta files +*.pidb.meta + +# Unity3D Generated File On Crash Reports +sysinfo.txt + +# Builds +*.apk +*.unitypackage diff --git a/Assets/NoiseCrimeStudios.meta b/Assets/NoiseCrimeStudios.meta new file mode 100644 index 0000000..a9734a0 --- /dev/null +++ b/Assets/NoiseCrimeStudios.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 42e1031f523a6024cbe193f8c1c75ba9 +folderAsset: yes +timeCreated: 1500169863 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Core.meta b/Assets/NoiseCrimeStudios/Core.meta new file mode 100644 index 0000000..ac74c77 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e2b478f2fd6738742819a976fb75dafd +folderAsset: yes +timeCreated: 1499618612 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Core/Extensions.meta b/Assets/NoiseCrimeStudios/Core/Extensions.meta new file mode 100644 index 0000000..3eb5eb6 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/Extensions.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7fc7664799552564593c28a3df63d86c +folderAsset: yes +timeCreated: 1494060174 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Core/Extensions/LinqExtensions.cs b/Assets/NoiseCrimeStudios/Core/Extensions/LinqExtensions.cs new file mode 100644 index 0000000..f87d351 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/Extensions/LinqExtensions.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace NoiseCrimeStudios.Core +{ + public static class LinqExtensions + { + /// Helper method to choose between ascending or descending Order. + /// Taken from Unity's TreeViewExamples demo. + public static IOrderedEnumerable OrderBy( this IEnumerable source, Func selector, bool ascending ) + { + if ( ascending ) + return source.OrderBy( selector ); + + return source.OrderByDescending( selector ); + } + + /// Helper method to choose between ascending or descending ThenBy. + /// Taken from Unity's TreeViewExamples demo. + public static IOrderedEnumerable ThenBy( this IOrderedEnumerable source, Func selector, bool ascending ) + { + if ( ascending ) + return source.ThenBy( selector ); + + return source.ThenByDescending( selector ); + } + } +} diff --git a/Assets/NoiseCrimeStudios/Core/Extensions/LinqExtensions.cs.meta b/Assets/NoiseCrimeStudios/Core/Extensions/LinqExtensions.cs.meta new file mode 100644 index 0000000..2b6eb6d --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/Extensions/LinqExtensions.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 16482c3b3cd301c4ba3f9c6ae579f319 +timeCreated: 1593827514 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Core/Formatting.meta b/Assets/NoiseCrimeStudios/Core/Formatting.meta new file mode 100644 index 0000000..7a45ff7 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/Formatting.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 4ede789b7a190564cbc45a0a4f063d5c +folderAsset: yes +timeCreated: 1593124127 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Core/Formatting/Numerical.cs b/Assets/NoiseCrimeStudios/Core/Formatting/Numerical.cs new file mode 100644 index 0000000..d1e4db9 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/Formatting/Numerical.cs @@ -0,0 +1,142 @@ +using UnityEngine; + +// String.Format Notes +// http://azuliadesigns.com/string-formatting-examples/ +// https://msdn.microsoft.com/en-us/library/system.string.format(v=vs.110).aspx + +namespace NoiseCrimeStudios.Core.Formatting +{ + public static class Numerical + { + // Overall this has proven to be the most efficeint method to use from this page + // https://stackoverflow.com/questions/281640/how-do-i-get-a-human-readable-file-size-in-bytes-abbreviation-using-net#4975942 + // Returns the human-readable file size for an arbitrary, 64-bit file size. However it reverts to bytes for long.MinValue + public static string ByteCountToSuffixHumbads( long byteCount ) + { + // Get absolute value + long absolute_i = (byteCount < 0 ? -byteCount : byteCount); + + // Determine the suffix and readable value + string suffix; + double readable; + + if ( absolute_i >= 0x1000000000000000 ) // Exabyte + { + suffix = "EB"; + readable = ( byteCount >> 50 ); + } + else if ( absolute_i >= 0x4000000000000 ) // Petabyte + { + suffix = "PB"; + readable = ( byteCount >> 40 ); + } + else if ( absolute_i >= 0x10000000000 ) // Terabyte + { + suffix = "TB"; + readable = ( byteCount >> 30 ); + } + else if ( absolute_i >= 0x40000000 ) // Gigabyte + { + suffix = "GB"; + readable = ( byteCount >> 20 ); + } + else if ( absolute_i >= 0x100000 ) // Megabyte + { + suffix = "MB"; + readable = ( byteCount >> 10 ); + } + else if ( absolute_i >= 0x400 ) // Kilobyte + { + suffix = "KB"; + readable = byteCount; + } + else + { + return string.Format( "{0:F1} B", byteCount); // Byte + } + + // Divide by 1024 to get fractional value + readable = ( readable / 1024 ); + + // Return formatted number with suffix + return string.Format( "{0:F1} {1}", readable, suffix ); + } + +#if UNITY_EDITOR + [UnityEditor.MenuItem( "Window/NoiseCrimeStudios/Validations/Support_Formatting", false, 1300 )] + public static void TestByteCountToSuffix() + { + long[] testValues = new long[]{ -1, 0, 1, 1000, 10000, 100000, 1000000, int.MaxValue, int.MinValue, long.MaxValue }; //, long.MinValue }; + + string result; + + result = ""; + for ( int i = 0; i < testValues.Length; i++ ) + result += string.Format( "ByteCountToSuffixHumbads: {0} = {1}\n", testValues[ i ], ByteCountToSuffixHumbads( testValues[ i ] ) ); + + Debug.Log( result ); + } +#endif + + + +#if ALTERNATIVES + // Don't use these methods, they are just for reference and not as efficeint as ByteCountToSuffixHumbads() + + static string[] suffixArray = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; //Longs run out around EB + + // Note: Reverts to bytes for int.MinValue & long.MinValue + [System.Obsolete("Obsolete. For reference only. Reverts to bytes for int.MinValue & long.MinValue")] + public static string ByteCountToSuffixNC( long byteCount ) + { + int index = 0; + double output = byteCount; + + while ( output >= 1024 ) + { + output = output / 1024.0; + index++; + } + + if ( index >= suffixArray.Length ) return "err"; + + return string.Format( "{0:F1} {1}", output, suffixArray[ index ] ); + } + + + // Note: Fails on long.MinValue - DO NOT USE! + [System.Obsolete("Obsolete. For reference only. Fails on long.MinValue with exception error.")] + public static string ByteCountToSuffixDeepee( long byteCount ) + { + if ( byteCount == 0 ) return "0" + suffixArray[ 0 ]; + + long bytes = Math.Abs(byteCount); + int index = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024))); + double num = Math.Round(bytes / Math.Pow(1024, index), 1); + + return string.Format( "{0:F1} {1}", Math.Sign( byteCount ) * num, suffixArray[ index ] ); + } + + + // Requires NoiseCrimeStudio's StopWatchProfiler + public static void PerformanceTestByteCountToSuffix() + { + long[] testValues = new long[]{ -1, 0, 1, 1000, 10000, 100000, 1000000, int.MaxValue, int.MinValue, long.MaxValue }; //, long.MinValue }; + + StopWatchProfiler.NewFrame(); + + StopWatchProfiler.BeginSample( "ByteCountToSuffixHumbads" ); + for ( int p = 0; p < 100000; p++ ) + { + for ( int i = 0; i < testValues.Length; i++ ) + ByteCountToSuffixHumbads( testValues[ i ] ); + } + StopWatchProfiler.EndSample(); + + Debug.Log( StopWatchProfiler.GetResults() ); + } +#endif + + } + +} diff --git a/Assets/NoiseCrimeStudios/Core/Formatting/Numerical.cs.meta b/Assets/NoiseCrimeStudios/Core/Formatting/Numerical.cs.meta new file mode 100644 index 0000000..cd1b6f6 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/Formatting/Numerical.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1d7174494930b0147866403931a36b07 +timeCreated: 1524668507 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Core/IO.meta b/Assets/NoiseCrimeStudios/Core/IO.meta new file mode 100644 index 0000000..e3d38eb --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/IO.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 28c663276da777449a6f536a04fec86f +folderAsset: yes +timeCreated: 1593125167 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Core/IO/DirectoryCopy.cs b/Assets/NoiseCrimeStudios/Core/IO/DirectoryCopy.cs new file mode 100644 index 0000000..93494d5 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/IO/DirectoryCopy.cs @@ -0,0 +1,85 @@ +using System.IO; + +namespace NoiseCrimeStudios.Core.IO +{ + public static partial class DirectoryUtils + { + /// Provides various settings for use when Copying Directories. + public class CopyDirectorySettings + { + public bool enablePackageSizeLimit; + public int packageSizeByteLimit; + public string[] excludeSubDirectories; + } + + + // Copy Directory Contents + // https://stackoverflow.com/questions/58744/how-to-copy-the-entire-contents-of-directory-in-c#3822913 + // TODO: Improve this - write class for stringBuilder, enable debug output or not etc. + // See CustomAssetStoreBackUp.cs - originally used for copying Unity assetStore folder to a back up location. + // Note - we could try Unity's own FileUtil.CopyFileOrDirectory() + public static void CopyDirectory( string sourceDirectory, string targetDirectory, CopyDirectorySettings copyDirectorySettings, bool enableLogging ) + { + DirectoryInfo diSource = new DirectoryInfo(sourceDirectory); + DirectoryInfo diTarget = new DirectoryInfo(targetDirectory); + + StringBuilderDebugLog output = new StringBuilderDebugLog( enableLogging ); + + if ( output.ExternalEnableLogging ) output.AppendLine( "-- FileCopying:CopyDirectory -- " ); + + CopyDirectoryAll( diSource, diTarget, copyDirectorySettings, output ); + + if ( output.ExternalEnableLogging ) + { + output.InsertHardBreak(); + output.AppendLine( "-- FileCopying:CopyDirectory -- " ); + output.LogToConsole( true ); + } + } + + + static void CopyDirectoryAll( DirectoryInfo source, DirectoryInfo target, CopyDirectorySettings copyDirectorySettings, StringBuilderDebugLog output ) + { + // Will create all directories up to target. + Directory.CreateDirectory( target.FullName ); + + if ( output.ExternalEnableLogging ) + { + output.AppendFormat( "Copying Directory:\n\tSrc: {0}\n\tDst: {1}\n", source.FullName, target.FullName ); + output.IndentIncrement(); + } + + // Copy each file into the new directory. + foreach ( FileInfo fi in source.GetFiles() ) + { + if ( output.ExternalEnableLogging ) output.AppendFormat( "{0}", fi.Name ); + fi.CopyTo( Path.Combine( target.FullName, fi.Name ), true ); + } + + // Copy each subdirectory using recursion. + foreach ( DirectoryInfo diSourceSubDir in source.GetDirectories() ) + { + string subDirectoryName = diSourceSubDir.Name; + bool isExcluded = false; + + foreach ( string exclusion in copyDirectorySettings.excludeSubDirectories ) + { + if ( subDirectoryName == exclusion ) + { + isExcluded = true; + if ( output.ExternalEnableLogging ) output.AppendFormat( "{0} is Excluded", subDirectoryName ); + break; + } + } + + if ( !isExcluded ) + { + DirectoryInfo nextTargetSubDir = target.CreateSubdirectory(subDirectoryName); + CopyDirectoryAll( diSourceSubDir, nextTargetSubDir, copyDirectorySettings, output ); + } + } + + if ( output.ExternalEnableLogging ) output.IndentDecrement(); + } + } +} diff --git a/Assets/NoiseCrimeStudios/Core/IO/DirectoryCopy.cs.meta b/Assets/NoiseCrimeStudios/Core/IO/DirectoryCopy.cs.meta new file mode 100644 index 0000000..f85e460 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/IO/DirectoryCopy.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: cac56d9b22a5c264883932c397526de5 +timeCreated: 1538917426 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Core/IO/DirectoryUtil.cs b/Assets/NoiseCrimeStudios/Core/IO/DirectoryUtil.cs new file mode 100644 index 0000000..17fa154 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/IO/DirectoryUtil.cs @@ -0,0 +1,312 @@ +#define USE_NEW_ENUMERATION + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using UnityEngine; + +namespace NoiseCrimeStudios.Core.IO +{ + /// Collection of System.IO Utility Methods. + /// + /// + /// FilePathValidation + /// + /// UnityEditor.FileUtil is Unity's own collection of useful methods + /// + /// + public static partial class DirectoryUtils + { +#if USE_NEW_ENUMERATION + public enum SearchPattern + { + Any = 1, + ImageImportable = 10, + ImageFormats = 11, + Xml = 20, + QEP = 50, + UnityPackage = 100, + Custom = 1000 + }; +#else + public enum SearchPattern { ANY, IMAGE, XML, QEP, UNITYPACKAGE, CUSTOM } +#endif + + /// Converts an index to the enum, where index is the position in the array of enums and not the value! + /// This is quite fragile so should only be used via UI selections e.g DevPanel_FileSystem + public static SearchPattern GetSearchPatternEnumFromIndex( int index ) + { + return ( SearchPattern )Enum.GetValues( typeof( SearchPattern ) ).GetValue( index ); + } + + public static string GetSearchPattern( SearchPattern searchPattern ) + { + switch ( searchPattern ) + { + case SearchPattern.Any: return "*.*"; + case SearchPattern.ImageImportable: return "*.png|*.jpg|*.jpeg"; + case SearchPattern.ImageFormats: return "*.png|*.jpg|*.jpeg|*.tiff|*.tif"; + case SearchPattern.Xml: return "*.xml"; + case SearchPattern.QEP: return "*.qet"; + case SearchPattern.UnityPackage: return "*.unitypackage"; + } + throw new NotImplementedException( "Not Implemented SearchPattern: " + searchPattern.ToString() ); + } + + public static bool IsValidPathToDirectory( string path ) + { + return ( !string.IsNullOrEmpty( path ) && Directory.Exists( path ) ); + } + + public static bool IsValidPathInProject( string path ) + { + return ( !string.IsNullOrEmpty( path ) && path.StartsWith( Application.dataPath ) && Directory.Exists( path ) ); + } + + /// Determine if directory has no files or subfolders and if it has subfolders they do not have files. + /// bool - true if no files found + public static bool IsDirectoryHeirarchyEmptyOfFiles( string sourcePath ) + { + bool hasContents = true; + + try + { + hasContents = Directory.GetDirectories( sourcePath ).Length == 0 && Directory.GetFiles( sourcePath, "*", SearchOption.AllDirectories ).Length == 0; + } + catch ( Exception ex ) + { + Debug.LogWarning( "IsDirectoryHeirarchyEmptyOfFiles " + ex.Message ); + } + + return hasContents; + } + + + public static List GetFoldersInDirectory( string sourcePath ) + { + List directoryList = new List(); + + directoryList.AddRange( Directory.GetDirectories( sourcePath ) ); + directoryList.Sort(); + + return directoryList; + } + + // TODO: Add versions that take a List so we can reuse memory. + #region GET FILE PATHS FROM DIRECTORY + /// Returns list of all files that match search patterns the top directory only, no children. + /// Absolute file path to top directory. + /// Single string of | delimited search patterns e.g. "*.png|*.jpg" + /// (Optional) Sorts the results by name. Default false. + /// (Optional) Returns only the filename without extension. Default false. + /// List of strings of absolute path names or filenames. + public static List GetFileListFromTopDirectory( string sourcePath, string multiSearchPattern, bool sortResults = false, bool filenameOnly = false ) + { + return GetFileListFromDirectory( sourcePath, multiSearchPattern, SearchOption.TopDirectoryOnly, sortResults, filenameOnly ); + } + + /// Returns list of all files that match search patterns the top directory and its sub-directories. + /// Absolute file path to top directory. + /// Single string of | delimited search patterns e.g. "*.png|*.jpg" + /// (Optional) Sorts the results by name. Default false. + /// (Optional) Returns only the filename without extension. Default false. + /// List of strings of absolute path names or filenames. + public static List GetFileListFromAllDirectories( string sourcePath, string multiSearchPattern, bool sortResults = false, bool filenameOnly = false ) + { + return GetFileListFromDirectory( sourcePath, multiSearchPattern, SearchOption.AllDirectories, sortResults, filenameOnly ); + } + + /// Returns list of all files that match search patterns in top directory and optionally subdirectories. + /// Previouly known as GetFilesFromDirectoriesAsFullPaths, GetFilesFromDirectoryAsFileNameWithoutExtension, GetFileNameNoExtListFromDirectory, GetFileNamesViaMultiplePatterns + /// Absolute file path to top directory. + /// Single string of | delimited search patterns e.g. "*.png|*.jpg" + /// SearchOptions - TopDirectory or AllDirectories + /// (Optional) Sorts the results by name. Default false. + /// (Optional) Returns only the filename without extension. Default false. + /// List of strings of absolute path names or filenames. + private static List GetFileListFromDirectory( string sourcePath, string multiSearchPattern, SearchOption searchOption, bool sortResults = false, bool filenameOnly = false ) + { + if ( !Directory.Exists( sourcePath ) ) + { + Debug.LogWarningFormat( "SupportFileIO:GetFileListFromDirectory: Directory does not exist.\n{0}", sourcePath ); + return new List(); + } + + string[] searchPatterns = multiSearchPattern.Split('|'); + List results = new List(); + + // Could probably optimise this if searchPattern is '*.*' + if ( filenameOnly ) + { + // Stripping extension per searchPattern will be more efficient overal, in performance and memory usage. + foreach ( string searchPattern in searchPatterns ) + { + string[] tmpFiles = Directory.GetFiles( sourcePath, searchPattern, searchOption ); + + foreach ( string file in tmpFiles ) + results.Add( Path.GetFileNameWithoutExtension( file ) ); + } + } + else + { + foreach ( string searchPattern in searchPatterns ) + results.AddRange( Directory.GetFiles( sourcePath, searchPattern, searchOption ) ); + } + + if ( sortResults ) results.Sort(); + + return results; + } + #endregion + + + #region DUMP DIRECTORY CONTENTS + public static string DumpDirectoryContents( string sourcePath, bool subFolders ) + { + if ( !Directory.Exists( sourcePath ) ) + { + Debug.LogWarningFormat( "SupportFileIO:DumpDirectoryContents: Directory does not exist.\n{0}", sourcePath ); + return "ERROR"; + } + + StringBuilder info = new StringBuilder(); + + DumpDirectory( sourcePath, subFolders, ref info ); + + return info.ToString(); + } + + public static void DumpDirectory( string sourcePath, bool subFolders, ref StringBuilder info ) + { + string[] directories = Directory.GetDirectories(sourcePath); + + info.AppendFormat( "Path: {0}\n", sourcePath ); + + string[] filelist = Directory.GetFiles(sourcePath); + + foreach ( string file in filelist ) + info.AppendFormat( " File: {0}\n", file ); + + if ( subFolders ) + { + foreach ( string directory in directories ) + DumpDirectory( directory, subFolders, ref info ); + } + } + #endregion + + #region VALIDATE FILEIO SUPPORT METHODS + + // TODO - Replace PrintToConsole with StringOutputLogger +#if UNITY_EDITOR + [UnityEditor.MenuItem( "Window/NoiseCrimeStudios/Validations/FileIO RelativeToAbsolutePaths", false, 1300 )] +#endif + static void ValidateRelativeToAbsolutePathExamples() + { + string realtivePath0 = @"MyFolder\MySubFolder\FinalFolder"; + string realtivePath1 = @"MyFolder/MySubFolder/FinalFolder"; + string realtivePath2 = @"..\MyFolder\MySubFolder\FinalFolder"; + string realtivePath3 = @"..\..\MyFolder\MySubFolder\FinalFolder"; + + string log = "Get Absolute Path Examples:\n"; + log += string.Format( "[{0}]\tResult: '{1}'\n", realtivePath0, PathUtils.GetAbsolutePath( realtivePath0 ) ); + log += string.Format( "[{0}]\tResult: '{1}'\n", realtivePath1, PathUtils.GetAbsolutePath( realtivePath1 ) ); + log += string.Format( "[{0}]\tResult: '{1}'\n", realtivePath2, PathUtils.GetAbsolutePath( realtivePath2 ) ); + log += string.Format( "[{0}]\tResult: '{1}'\n", realtivePath3, PathUtils.GetAbsolutePath( realtivePath3 ) ); + Debug.Log( log ); + } + +#if UNITY_EDITOR + [UnityEditor.MenuItem( "Window/NoiseCrimeStudios/Validations/FileIO GetListFromDirectory", false, 1300 )] +#endif + static void ValidateGetListFromDirectory() + { + bool truncate = true; + string sourcePath1 = Application.dataPath + Path.AltDirectorySeparatorChar + "NoiseCrimeStudios"; + string sourcePath2 = Application.dataPath + Path.AltDirectorySeparatorChar + "NoiseCrimeStudios" + Path.AltDirectorySeparatorChar; + string sourcePath3 = @"C:\Windows\System32\"; // Application.dataPath + Path.AltDirectorySeparatorChar; + string searchPattern1 = "*.*"; + string searchPattern2 = "*.meta"; + string resultsDump; + + // NOTE: + // When parsing Unity folders you'll end up with both the file and the meta file. + // When you return filename only without extension that will result in file having striped extension, but the meta file stripped will be filename.ext! + // + // sourcePath3 Cannot use AllDirectories as some system folders are restricted and throw an exception. + + FileListTest( sourcePath1, searchPattern1, SearchOption.TopDirectoryOnly, true, false, truncate ); + FileListTest( sourcePath1, searchPattern1, SearchOption.TopDirectoryOnly, true, true, truncate ); + + FileListTest( sourcePath2, searchPattern1, SearchOption.TopDirectoryOnly, true, false, truncate ); + FileListTest( sourcePath2, searchPattern1, SearchOption.TopDirectoryOnly, true, true, truncate ); + + FileListTest( sourcePath1, searchPattern1, SearchOption.AllDirectories, true, false, truncate ); + FileListTest( sourcePath1, searchPattern1, SearchOption.AllDirectories, true, true, truncate ); + FileListTest( sourcePath1, searchPattern2, SearchOption.AllDirectories, true, false, truncate ); + FileListTest( sourcePath1, searchPattern2, SearchOption.AllDirectories, true, true, truncate ); + + FileListTest( sourcePath2, searchPattern1, SearchOption.AllDirectories, true, false, truncate ); + FileListTest( sourcePath2, searchPattern1, SearchOption.AllDirectories, true, true, truncate ); + FileListTest( sourcePath2, searchPattern2, SearchOption.AllDirectories, true, false, truncate ); + FileListTest( sourcePath2, searchPattern2, SearchOption.AllDirectories, true, true, truncate ); + + FileListTest( sourcePath3, searchPattern1, SearchOption.TopDirectoryOnly, true, false, truncate ); + FileListTest( sourcePath3, searchPattern1, SearchOption.TopDirectoryOnly, true, true, truncate ); + + resultsDump = DumpDirectoryContents( sourcePath1, false ); + Debug.Log( "DumpDirectoryContents.TopDirectoryOnly\n" + resultsDump ); + + resultsDump = DumpDirectoryContents( sourcePath1, true ); + Debug.Log( "DumpDirectoryContents.AllDirectories\n" + resultsDump ); + } + + static void FileListTest( string path, string multiSearchPattern, SearchOption searchOption, bool sorted, bool filenameOnly, bool truncate ) + { + string header = string.Format("GetFileListFromDirectory - '{0}' SearchOption.{1}{2}{3}\n", + multiSearchPattern, searchOption, sorted ? " - Sorted" : "", filenameOnly ? " - filename" : "" ); + + List results = GetFileListFromDirectory( path, multiSearchPattern, searchOption, sorted, filenameOnly); + PrintToConsole( header + path, results, truncate ); + } + + /// Print list of strings to console avoiding truncation. + static void PrintToConsole( string header, List stringList, bool truncate = false ) + { + StackTraceLogType traceType = Application.GetStackTraceLogType( LogType.Log ); + Application.SetStackTraceLogType( LogType.Log, StackTraceLogType.None ); + + StringBuilder stringBuilder = new StringBuilder(); + int lineCount = 0; + + stringBuilder.AppendLine( string.Format( "{0} Count: {1}\n", header, stringList.Count ) ); + + foreach ( string s in stringList ) + { + stringBuilder.AppendLine( s ); + lineCount++; + + // Unity console will truncate a long string, so we limit and log it here if necessarry. + if ( stringBuilder.Length > 16000 ) + { + if ( truncate ) + break; + else + { + stringBuilder.AppendLine( "" ); + Debug.Log( stringBuilder.ToString() ); + + stringBuilder.Length = 0; + stringBuilder.AppendLine( string.Format( "{0} continued ... {1}", header, lineCount ) ); + } + } + } + + if ( stringBuilder.Length > 0 ) Debug.Log( stringBuilder.ToString() ); + + Application.SetStackTraceLogType( LogType.Log, traceType ); + } + #endregion + } +} diff --git a/Assets/NoiseCrimeStudios/Core/IO/DirectoryUtil.cs.meta b/Assets/NoiseCrimeStudios/Core/IO/DirectoryUtil.cs.meta new file mode 100644 index 0000000..2204d0b --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/IO/DirectoryUtil.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4d9cf5d0c6e73264caf254d5ea220b24 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Core/IO/PathUtils.cs b/Assets/NoiseCrimeStudios/Core/IO/PathUtils.cs new file mode 100644 index 0000000..cb9f8f2 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/IO/PathUtils.cs @@ -0,0 +1,116 @@ +using System.IO; +using UnityEngine; + +namespace NoiseCrimeStudios.Core.IO +{ + public enum PathType + { + Unknown, + File, + Directory + } + + /// Collection of System.IO Utility Methods. + /// + /// FilePathValidation + /// + /// UnityEditor.FileUtil is Unity's own collection of useful methods + /// + /// + public static class PathUtils + { + // Note: + // Windows Path.DirectorySeparatorChar = '\' = BackSlash + // Windows Path.AltDirectorySeparatorChar = '/' = ForwardSlash + // Could use Application.platform to avoid some processing here. + // Might want to add UnityEditor.FileUtil path methods for dealing with Windows Network! + // UnityEditor.FileUtil.NiceWinPath Replaces forward with Back Slashes! + + /// Returns the path with FORWARD slash replaced with BACK slash to match Unity style. + public static string ReplaceForwardWithBackSlash( string path ) + { + return path.Replace( "/", @"\" ); + } + + /// Returns the path with BACK slash replaced with FORWARD slash. + public static string ReplaceBackWithForwardSlash( string path ) + { + return path.Replace( @"\", "/" ); + } + + /// Splits a file path by seperator into string array. + public static string[] SplitFilePath( string path ) + { + return path.Split( new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar } ); + } + + /// Force path to use DirectorySeparatorChar instead of AltDirectorySeparatorChar to match Unity Style. Win: '/' = '\' - FORWARD replaced with BACK Slash. + public static string GetConsistentFilePath( string path ) + { + return path.Replace( Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar ); + } + + /// Force path to use AltDirectorySeparatorChar instead of DirectorySeparatorChar. Win: '\' = '/' - BACK replaced with FORWARD Slash. + public static string GetAltConsistentFilePath( string path ) + { + return path.Replace( Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar ); + } + + /// Returns the name of the final directory in the path. Works for files or folders + public static string GetNameOfDirectory( string directoryPath ) + { + return new DirectoryInfo( directoryPath ).Name; + } + + /// Returns the absolute path based on the Application.dataPath. + /// e.g. F:\Folder\SubFolder\Project\Assets + / + relativePath + public static string GetAbsolutePath( string relativePath ) + { + return Path.GetFullPath( Path.Combine( Application.dataPath, relativePath ) ); + } + + /// Returns the relative path ( to Unity Assets folder ) of an absolute path. + public static string GetRelativeAssetPath( string absolutePath ) + { + return absolutePath.Replace( Application.dataPath, "Assets" ); + } + + /// Checks if a path is to a Directory, File or Unknown + public static bool? IsPathToDirectory( string path ) + { + if ( string.IsNullOrEmpty( path ) ) return null; + if ( !Directory.Exists( path ) && !File.Exists( path ) ) return null; + FileAttributes attribute = File.GetAttributes(path); + return FileAttributes.Directory == ( attribute & FileAttributes.Directory ); + // return attribute.HasFlag(FileAttributes.Directory); + } + + /// Checks if a path is to a Directory, File or Unknown + public static PathType GetPathType( string path ) + { + if ( string.IsNullOrEmpty( path ) ) return PathType.Unknown; + if ( !Directory.Exists( path ) && !File.Exists( path ) ) return PathType.Unknown; + FileAttributes attribute = File.GetAttributes( path ); + return FileAttributes.Directory == ( attribute & FileAttributes.Directory ) ? PathType.Directory : PathType.File; + // return attribute.HasFlag(FileAttributes.Directory) ? PathType.Directory : PathType.File; + } + + /* + using System.Linq; + /// Combine Multiple paths into a single one using Path.Combine. + /// + /// https://stackoverflow.com/questions/1996139/in-c-how-do-i-combine-more-than-two-parts-of-a-file-path-at-once + /// In 2017.1 exp and 2018.1 .Net4 Path.Combine does this natively! + /// + public static string CombinePaths( string path, params string[] paths ) + { + if ( path == null ) + throw new System.ArgumentNullException( "path" ); + + if ( paths == null ) + throw new System.ArgumentNullException( "paths" ); + + return paths.Aggregate( path, ( acc, p ) => Path.Combine( acc, p ) ); + }*/ + } +} diff --git a/Assets/NoiseCrimeStudios/Core/IO/PathUtils.cs.meta b/Assets/NoiseCrimeStudios/Core/IO/PathUtils.cs.meta new file mode 100644 index 0000000..434d404 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/IO/PathUtils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 885e3139bd5ec3347853726ce20b3b64 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Core/IO/ValidationOfFilePaths.cs b/Assets/NoiseCrimeStudios/Core/IO/ValidationOfFilePaths.cs new file mode 100644 index 0000000..533be6c --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/IO/ValidationOfFilePaths.cs @@ -0,0 +1,127 @@ +using System.IO; +using System.Text; +using UnityEngine; + +/// +/// System.IO +/// Path.DirectorySeparatorChar = '\' = BackSlash +/// Path.AltDirectorySeparatorChar = '/' = ForwardSlash +/// +/// Path.Combine - Inserts BACKSLASH seperator between paths items, but retains each strings own seperators. +/// Path.GetDirectoryName - Converts all seperators to BACKSLASH. +/// Path.GetFullPath - Converts all seperators to BACKSLASH. +/// +/// UnityEngine.Application.Paths - All seperators are FORWARDSLASH. +/// +/// +/// UnityEditor.EditorUtility.OpenFolderPanel - All seperators are FORWARDSLASH +/// + +/// +/// System.IO +/// Path.DirectorySeparatorChar = '/' ? +/// Path.AltDirectorySeparatorChar = '/' ? +/// + +/// +/// System.IO +/// Path.DirectorySeparatorChar = '/' = BackSlash +/// Path.AltDirectorySeparatorChar = '/' = ForwardSlash +/// + +namespace NoiseCrimeStudios.Core.IO +{ + /// Explores descrepencies in use of directory seperators in Windows and Unity. + /// + /// UnityEditor.FileUtil is Unity's own collection of useful methods + /// + /// + public static class ValidationOfFilePaths + { +#if UNITY_EDITOR + [UnityEditor.MenuItem( "Window/NoiseCrimeStudios/Validations/FilePaths", false, 1300 )] // WindowMenuItemPriorty.Validations +#endif + public static void LogFilePathValidations() + { + string examplePathFwd = @"SubAssets/Fwd/Textures"; + string examplePathBck = @"SubAssets\Bck\Textures"; + + string pathCombineFwd = Path.Combine( Application.dataPath, examplePathFwd ) ; + string pathCombineBck = Path.Combine( Application.dataPath, examplePathBck ) ; +#if NET_4_6 + string pathCombineFwd46 = Path.Combine( new string[] { Application.dataPath, examplePathFwd } ) ; + string pathCombineBck46 = Path.Combine( new string[] { Application.dataPath, examplePathBck } ) ; +#endif + string getFullPathFwd = Path.GetFullPath( examplePathFwd ); + string getFullPathBck = Path.GetFullPath( examplePathBck ); + string directoryNameFwd = Path.GetDirectoryName( pathCombineFwd ); + string directoryNameBck = Path.GetDirectoryName( pathCombineBck ); + string getPathRootFwd = Path.GetPathRoot( pathCombineFwd ); + string getPathRootBck = Path.GetPathRoot( pathCombineBck ); + + + StringBuilder sb = new StringBuilder(); + + sb.AppendFormat( "Platform: {0} Date: {1}\n", Application.platform, System.DateTime.UtcNow ); +#if UNITY_2018_4_OR_NEWER + sb.AppendFormat( "OS Family: {0} OS: {1}\n", SystemInfo.operatingSystemFamily, SystemInfo.operatingSystem ); +#else + sb.AppendFormat( "OS: {0}\n", SystemInfo.operatingSystem ); +#endif + sb.AppendFormat( "Device: Model: {0} Type: {1} Name: {2}\n", SystemInfo.deviceModel, SystemInfo.deviceType, SystemInfo.deviceName ); + sb.AppendLine( "----------------------------------------" ); + sb.AppendFormat( "DirectorySeparatorChar\t'{0}'\n", Path.DirectorySeparatorChar ); + sb.AppendFormat( "AltDirectorySeparatorChar\t'{0}'\n", Path.AltDirectorySeparatorChar ); + sb.AppendLine( "----------------------------------------" ); + sb.AppendFormat( "[{0}]\t[Application.dataPath]\n", Application.dataPath ); + sb.AppendFormat( "[{0}]\t[Application.streamingAssetsPath]\n", Application.streamingAssetsPath ); + sb.AppendFormat( "[{0}]\t[Application.persistentDataPath]\n", Application.persistentDataPath ); + sb.AppendFormat( "[{0}]\t[Application.temporaryCachePath]\n", Application.temporaryCachePath ); + sb.AppendLine( "----------------------------------------" ); + sb.AppendFormat( "[{0}]\t[examplePathFwd]\n", examplePathFwd ); + sb.AppendFormat( "[{0}]\t[examplePathBck)]\n", examplePathBck ); + sb.AppendFormat( "[{0}]\t[Path.Combine(dataPath, pathCombineFwd]\n", pathCombineFwd ); + sb.AppendFormat( "[{0}]\t[Path.Combine(dataPath, pathCombineBck)]\n", pathCombineBck ); +#if NET_4_6 + sb.AppendFormat( "[{0}]\t[Path.Combine(dataPath, pathCombineFwd46]\n", pathCombineFwd46 ); + sb.AppendFormat( "[{0}]\t[Path.Combine(dataPath, pathCombineBck46)]\n", pathCombineBck46 ); +#endif + + sb.AppendFormat( "[{0}]\t[Path.GetFullPath(examplePathFwd)]\n", getFullPathFwd ); + sb.AppendFormat( "[{0}]\t[Path.GetFullPath(examplePathBck)]\n", getFullPathBck ); + sb.AppendFormat( "[{0}]\t[Path.GetDirectoryName(pathCombineFwd)]\n", directoryNameFwd ); + sb.AppendFormat( "[{0}]\t[Path.GetDirectoryName(pathCombineBck)]\n", directoryNameBck ); + sb.AppendFormat( "[{0}]\t[Path.GetPathRoot(pathCombineFwd)]\n", getPathRootFwd ); + sb.AppendFormat( "[{0}]\t[Path.GetPathRoot(pathCombineBck)]\n", getPathRootBck ); + sb.AppendLine( "----------------------------------------" ); + + Debug.Log( sb.ToString() ); + } + } +} + + + +/* +Platform: WindowsEditor Date: 29/06/2020 22:54:35 +OS Family: Windows OS: Windows 10 (10.0.0) 64bit +Device: Model: MS-7885 (MSI) Type: Desktop Name: TYPHOON +---------------------------------------- +DirectorySeparatorChar '\' +AltDirectorySeparatorChar '/' +---------------------------------------- +[F:/Clients_2016/QEP/Research/VoxelBusters/CPNP 1.5.7p4 (U18.4.23f)/Assets] [Application.dataPath] +[F:/Clients_2016/QEP/Research/VoxelBusters/CPNP 1.5.7p4 (U18.4.23f)/Assets/StreamingAssets] [Application.streamingAssetsPath] +[C:/Users/Noise/AppData/LocalLow/NoiseCrimeStudios/CPNP 1_5_7p4 (U18_4_23f)] [Application.persistentDataPath] +[C:/Users/Noise/AppData/Local/Temp/NoiseCrimeStudios/CPNP 1_5_7p4 (U18_4_23f)] [Application.temporaryCachePath] +---------------------------------------- +[F:/Clients_2016/QEP/Research/VoxelBusters/CPNP 1.5.7p4 (U18.4.23f)/Assets\SubAssets/Fwd/Textures] [Path.Combine(dataPath, pathCombineFwd] +[F:/Clients_2016/QEP/Research/VoxelBusters/CPNP 1.5.7p4 (U18.4.23f)/Assets\SubAssets\Bck\Textures] [Path.Combine(dataPath, pathCombineBck)] +[F:\Clients_2016\QEP\Research\VoxelBusters\CPNP 1.5.7p4 (U18.4.23f)\SubAssets\Fwd\Textures] [Path.GetFullPath(examplePathFwd)] +[F:\Clients_2016\QEP\Research\VoxelBusters\CPNP 1.5.7p4 (U18.4.23f)\SubAssets\Bck\Textures] [Path.GetFullPath(examplePathBck)] +[F:\Clients_2016\QEP\Research\VoxelBusters\CPNP 1.5.7p4 (U18.4.23f)\Assets\SubAssets\Fwd] [Path.GetDirectoryName(pathCombineFwd)] +[F:\Clients_2016\QEP\Research\VoxelBusters\CPNP 1.5.7p4 (U18.4.23f)\Assets\SubAssets\Bck] [Path.GetDirectoryName(pathCombineBck)] +[F:/] [Path.GetPathRoot(pathCombineFwd)] +[F:/] [Path.GetPathRoot(pathCombineBck)] +---------------------------------------- +*/ diff --git a/Assets/NoiseCrimeStudios/Core/IO/ValidationOfFilePaths.cs.meta b/Assets/NoiseCrimeStudios/Core/IO/ValidationOfFilePaths.cs.meta new file mode 100644 index 0000000..861ab7e --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/IO/ValidationOfFilePaths.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b8e9d416de034e418485e05b713d4ed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Core/Unity.meta b/Assets/NoiseCrimeStudios/Core/Unity.meta new file mode 100644 index 0000000..15ac95f --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/Unity.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 80997ba43ee8ee64b9dc41ddda1e525d +folderAsset: yes +timeCreated: 1525020655 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Core/Unity/UnityConsoleHelper.cs b/Assets/NoiseCrimeStudios/Core/Unity/UnityConsoleHelper.cs new file mode 100644 index 0000000..1a65aba --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/Unity/UnityConsoleHelper.cs @@ -0,0 +1,56 @@ +namespace NoiseCrimeStudios.Core.UnitySupport +{ + public static class UnityConsoleHelper + { +#if !UNITY_EDITOR + public static void ClearConsole() { } +#else + + private static void ClearConsoleSimple () + { + var method = System.Type.GetType("UnityEditor.LogEntries, UnityEditor.dll"); + var clearMethod = method.GetMethod("Clear", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public); + clearMethod.Invoke( null, null ); + } + + + public static void ClearConsole( string callerName = null ) + { +#if UNITY_2017_4_OR_NEWER + string typeName = "UnityEditor.LogEntries"; +#else + string typeName = "UnityEditorInternal.LogEntries"; +#endif + var assembly = System.Reflection.Assembly.GetAssembly( typeof( UnityEditor.Editor ) ); + var type = assembly.GetType( typeName ); + var method = type.GetMethod( "Clear", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public ); + method.Invoke( null, null ); + + if ( null != callerName ) UnityEngine.Debug.Log( " Console Cleared By Code - " + callerName ); + } +#endif + } +} + + +/* +// Old Code For Future Reference +// typeof(UnityEditor.Editor).Assembly.GetType("UnityEditorInternal.LogEntries").GetMethod("Clear", BindingFlags.Static | BindingFlags.Public).Invoke(null, null); + +#if UNITY_2017_4_OR_NEWER + var assembly = System.Reflection.Assembly.GetAssembly( typeof( UnityEditor.Editor ) ); + var type = assembly.GetType ("UnityEditor.LogEntries"); + var method = type.GetMethod ("Clear", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public); + method.Invoke( null, null ); +#elif UNITY_2017_1_OR_NEWER + var assembly = System.Reflection.Assembly.GetAssembly( typeof( UnityEditor.SceneView ) ); + var type = assembly.GetType ("UnityEditorInternal.LogEntries"); + var method = type.GetMethod ("Clear", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public); + method.Invoke( new object(), null ); +#else + var assembly = System.Reflection.Assembly.GetAssembly( typeof( UnityEditor.ActiveEditorTracker ) ); + var type = assembly.GetType("UnityEditorInternal.LogEntries"); + var method = type.GetMethod ("Clear", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public); + method.Invoke( new object(), null ); +#endif +*/ diff --git a/Assets/NoiseCrimeStudios/Core/Unity/UnityConsoleHelper.cs.meta b/Assets/NoiseCrimeStudios/Core/Unity/UnityConsoleHelper.cs.meta new file mode 100644 index 0000000..73b985f --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/Unity/UnityConsoleHelper.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: daac0bbdd5f9e51458dbf3813f718355 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/NoiseCrimeStudios/Core/Utilities.meta b/Assets/NoiseCrimeStudios/Core/Utilities.meta new file mode 100644 index 0000000..9f45eac --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/Utilities.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: c9a29ab97e7ea5642b46c0019467e049 +folderAsset: yes +timeCreated: 1462947982 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Core/Utilities/StringBuilderDebugLog.cs b/Assets/NoiseCrimeStudios/Core/Utilities/StringBuilderDebugLog.cs new file mode 100644 index 0000000..077b2b7 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/Utilities/StringBuilderDebugLog.cs @@ -0,0 +1,204 @@ +using System.Text; +using System.Collections.Generic; +using UnityEngine; + +// TODO: Search for 'PrintToConsole' in existin scripts and replace with this? + +namespace NoiseCrimeStudios.Core +{ + /// Stringbuilder based logging with features for use via Debug.Log. + /// + /// Max characters in unity Debug.Log is about 16384. + /// As we don't know how many additional characters there will be we have to guess a max value. + /// We could build the string to add with string.format and know in advance max characters but + /// this might not be as optimal as StringBuilder? + /// + /// Truncation Prevention via String Breaks: + /// String Breaks ( similar to Page Break ) help to avoid truncation of Debug.Log by splitting up the output. + /// You can specify the max character limit to be extracted from output.ToString() per Debug.Log(). + /// The SoftBreak option will insert a Hard Break if the next N characters will exceed Max Character limit. + /// + /// Indentation + /// Supports simple indentation via increment and decrement methods. + /// + public class StringBuilderDebugLog + { + private StringBuilder output = new StringBuilder(); + + /// List of indices at which to break up Debug.Log statements. + private List stringBreakIndices = new List(); + + /// Character limit at which point to automatically add a Hard break into the BreakIndices. + private int stringBreakCharLimit = 14000; + + /// Cache the previous break index. + private int previousBreakIndex = 0; + + // Allows instances to hold a flag to check whether to call instance methods. e.g. if ( instance.ExternalEnableLogging ) output.writeline() + public bool ExternalEnableLogging { get; private set; } + + + public StringBuilderDebugLog( bool enableLogging = true, int breakCharCount = 14000 ) + { + ExternalEnableLogging = enableLogging; + stringBreakCharLimit = breakCharCount; + } + + public override string ToString() + { + return output.ToString(); + } + + public void AppendLine() + { + CheckForStringBreak( 2 ); + output.AppendLine(); + } + + public void AppendLine( string value ) + { + CheckForStringBreak( value.Length + 2 + indentLevel * indentSize ); + output.Append( Indent ); + output.AppendLine( value ); + } + + public void AppendFormat( string format, params object[] args ) + { + string value = string.Format( format, args ); + CheckForStringBreak( value.Length + 2 + indentLevel * indentSize ); + + output.Append( Indent ); + output.AppendFormat( value ); + output.AppendLine(); + } + + /* + public void WriteString( string format, params object[] args ) + { + string value = string.Format( format, args ); + CheckForStringBreak( value.Length ); + output.AppendFormat( value ); + }*/ + + + /// Clears the output and resets internal break markers and indents. + public void Clear() + { + // https://stackoverflow.com/questions/1709471/best-way-to-clear-contents-of-nets-stringbuilder#1709537 + output.Length = 0; + previousBreakIndex = 0; + stringBreakIndices.Clear(); + IndentReset(); + } + + private void LogStatement( int previousIndex, int length, LogType logType ) + { + switch ( logType ) + { + case LogType.Warning: + Debug.LogWarning( output.ToString( previousIndex, length) ); + break; + case LogType.Error: + Debug.LogError( output.ToString( previousIndex, length) ); + break; + default: + Debug.Log( output.ToString( previousIndex, length) ); + break; + } + } + + public void LogToConsole( bool disableStackTraceLog = false, bool clearOnLog = true, LogType logType = LogType.Log ) + { + int previousIndex = 0; + StackTraceLogType previousTraceType = Application.GetStackTraceLogType( logType ); + + if ( disableStackTraceLog ) /// DISABLE + Application.SetStackTraceLogType( logType, StackTraceLogType.None ); + + // Print contents to console + for ( int i = 0; i < stringBreakIndices.Count; i++ ) + { + LogStatement( previousIndex, stringBreakIndices[ i ] - previousIndex, logType ); + previousIndex = stringBreakIndices[ i ] ; + } + + // Print remainder to console + if ( output.Length - 1 - previousIndex > 0 ) + LogStatement( previousIndex, output.Length - 1 - previousIndex, logType ); + + if ( disableStackTraceLog ) // RESTORE + Application.SetStackTraceLogType( logType, previousTraceType ); + + if ( clearOnLog ) + Clear(); + } + + + /// Inserts a Hard Break at current output length to split up results into debug.log statements. + public void InsertHardBreak() + { + previousBreakIndex = output.Length; + stringBreakIndices.Add( previousBreakIndex ); + } + + /// Inserts a Hard Break at current output length ONLY if breakBufferLength exceeds max character limit. + public void InsertSoftBreak( int breakBufferLength = 1024 ) + { + if ( output.Length - previousBreakIndex + breakBufferLength < stringBreakCharLimit ) return; + + previousBreakIndex = output.Length; + stringBreakIndices.Add( previousBreakIndex ); + } + + /// Check if appending the predicted number of characters will exceed next break index. + private void CheckForStringBreak( int predictedCharacterLength = 0 ) + { + if ( output.Length + predictedCharacterLength - previousBreakIndex < stringBreakCharLimit ) return; + + previousBreakIndex = output.Length; + stringBreakIndices.Add( previousBreakIndex ); + } + + + + #region Indents + private int indentLevel = 0; + private int indentSize = 4; // 16 is default Unity value + private string Indent { get; set; } + + public void IndentReset( int size = 4 ) + { + indentLevel = 0; + indentSize = size; + Indent = new string( ' ', indentLevel * indentSize ); + } + + public void IndentIncrement( int level = 1 ) + { + indentLevel += level; + Indent = new string( ' ', indentLevel * indentSize ); + } + + public void IndentDecrement( int level = 1 ) + { + indentLevel -= level; + if ( indentLevel < 0 ) indentLevel = 0; + Indent = new string( ' ', indentLevel * indentSize ); + } + #endregion + + + #region Validation + /// Simple test to validate everything works as expected. + public static void ValidateOutput() + { + StringBuilderDebugLog helper = new StringBuilderDebugLog(); + + for ( int i = 0; i < 8192; i++ ) + helper.AppendFormat( "{0:D4}+", i ); + + helper.LogToConsole(true); + } + #endregion + } +} diff --git a/Assets/NoiseCrimeStudios/Core/Utilities/StringBuilderDebugLog.cs.meta b/Assets/NoiseCrimeStudios/Core/Utilities/StringBuilderDebugLog.cs.meta new file mode 100644 index 0000000..d15c899 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Core/Utilities/StringBuilderDebugLog.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7c5f1579b009d7449b43df373a487abd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor.meta b/Assets/NoiseCrimeStudios/Editor.meta new file mode 100644 index 0000000..cf00bf6 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 24874bb605577e74ea8b76dc75c22c57 +folderAsset: yes +timeCreated: 1490217876 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Internal.meta b/Assets/NoiseCrimeStudios/Editor/Internal.meta new file mode 100644 index 0000000..7098b44 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c7d7fb8dd8a3f2845be699c5c37a295d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Internal/InternalDebugIMGUI.cs b/Assets/NoiseCrimeStudios/Editor/Internal/InternalDebugIMGUI.cs new file mode 100644 index 0000000..35b5914 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Internal/InternalDebugIMGUI.cs @@ -0,0 +1,35 @@ +#if !UNITY_2019_4_OR_NEWER +using UnityEditor; + +namespace NoiseCrimeStudios.Editor.Internal +{ + /// Adds the Internal Unity IMGUI Debugger to the Window Menu. + /// + /// Source: UnityCsReference\Editor\Mono\GUIDebugger\GUIViewDebuggerWindow.cs + /// MenuItem: [MenuItem("Window/Analysis/IMGUI Debugger", false, 102, true)] + /// + public static class InternalDebugIMGUI + { +#if UNITY_2018_2_OR_NEWER + [MenuItem( "Window/Analysis/IMGUI Debugger", false, 112 )] +#else + [MenuItem( "Window/Internal/IMGUI Debugger", false, 112 )] +#endif + static void GUIViewDebuggerWindow() + { + EditorWindow.GetWindow ( typeof( EditorApplication ).Assembly.GetType ("UnityEditor.GUIViewDebuggerWindow") ); + } + } +} +#endif + +/* +// Get existing open window or if none, make a new one: +if ( s_ActiveInspector == null ) +{ + EditorWindow window = EditorWindow.GetWindow ( GetType ("UnityEditor.UndoWindow")); + s_ActiveInspector = window; +} +s_ActiveInspector.Show(); +*/ + diff --git a/Assets/NoiseCrimeStudios/Editor/Internal/InternalDebugIMGUI.cs.meta b/Assets/NoiseCrimeStudios/Editor/Internal/InternalDebugIMGUI.cs.meta new file mode 100644 index 0000000..446b9b7 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Internal/InternalDebugIMGUI.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5445005eab73a214fa599a323f684fec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Internal/InternalDebugUndo.cs b/Assets/NoiseCrimeStudios/Editor/Internal/InternalDebugUndo.cs new file mode 100644 index 0000000..9465a52 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Internal/InternalDebugUndo.cs @@ -0,0 +1,22 @@ +using UnityEditor; + +namespace NoiseCrimeStudios.Editor.Internal +{ + /// Adds the Internal Unity Undo Debugger to the Widow Menu. + /// + /// Source: UnityCsReference\Editor\Mono\Undo\UndoWindow.cs + /// MenuItem: [MenuItem("Window/Internal/Undo", false, 1, true)] + /// + public static class InternalDebugUndo + { +#if UNITY_2018_2_OR_NEWER + [MenuItem( "Window/Analysis/Undo Window", false, 113 )] +#else + [MenuItem( "Window/Internal/Undo Window", false, 113 )] +#endif + static void GUIViewDebuggerWindow() + { + EditorWindow.GetWindow ( typeof( EditorApplication ).Assembly.GetType ("UnityEditor.UndoWindow") ); + } + } +} diff --git a/Assets/NoiseCrimeStudios/Editor/Internal/InternalDebugUndo.cs.meta b/Assets/NoiseCrimeStudios/Editor/Internal/InternalDebugUndo.cs.meta new file mode 100644 index 0000000..e9d8a82 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Internal/InternalDebugUndo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ab2e5f035dd8f3346b8ba2a1ca67f660 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Internal/InternalScreenShotting.cs b/Assets/NoiseCrimeStudios/Editor/Internal/InternalScreenShotting.cs new file mode 100644 index 0000000..06cc35a --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Internal/InternalScreenShotting.cs @@ -0,0 +1,93 @@ +using UnityEditor; +using UnityEngine; + +namespace NoiseCrimeStudios.Editor.Internal +{ + /// + /// Exposes the native Unity 'ScreenShotting' methods to Unity Menu & Shortcut keys. + /// + /// + /// Once imported you can find the menu in either Window/Analysis/Screenshot or Window/Internal/Screenshot. + /// See UnityCsReference\Editor\Mono\GUI\ScreenShotting.cs + /// Hotkey: % (ctrl on Windows, cmd on macOS), # (shift), & (alt). + /// + public static class InternalScreenShotting + { + static System.Type screenShotsType = typeof(EditorApplication).Assembly.GetType("UnityEditor.ScreenShots", false); + +#if UNITY_2018_2_OR_NEWER + const string m_MenuItemName = "Window/Analysis/Screenshot/"; +#else + const string m_MenuItemName = "Window/Internal/Screenshot/"; +#endif + + /// Sets the entire Unity Window to 762x600. + [MenuItem( m_MenuItemName + "SetMainWindowSize ( 762,600)", false, 115)] + public static void SetMainWindowSizeSmall() + { + var method = screenShotsType.GetMethod("SetMainWindowSizeSmall"); + if ( null != method ) method.Invoke(null, null); + } + + /// Sets the entire Unity Window to 1024x768. + [MenuItem( m_MenuItemName + "SetMainWindowSize (1024,768)", false, 115)] + public static void SetMainWindowSize() + { + var method = screenShotsType.GetMethod("SetMainWindowSize"); + if ( null != method ) method.Invoke(null, null); + } + + /// Screenshots the Game View Window. + [MenuItem( m_MenuItemName + "Snap Game View Content %&g", false, 115)] + public static void ScreenGameViewContent() + { + Debug.Log("Snap Game View Content"); + var method = screenShotsType.GetMethod("ScreenGameViewContent"); + if ( null != method ) method.Invoke(null, null); + } + + /// Screenshots the active Window. + [MenuItem( m_MenuItemName + "Snap Active Window %&h", false, 115)] + public static void Screenshot() + { + Debug.Log("Snap Active Window"); + var method = screenShotsType.GetMethod("Screenshot"); + if ( null != method ) method.Invoke(null, null); + } + + /// Screenshots the active Window and the rest of the screen to the right. For example Sceneview & Inspector. + [MenuItem( m_MenuItemName + "Snap Active Window Extended Right %&j", false, 115)] + public static void ScreenshotExtendedRight() + { + Debug.Log("Snap Active Window Extended Right"); + var method = screenShotsType.GetMethod("ScreenshotExtendedRight"); + if ( null != method ) method.Invoke(null, null); + } + + /// Screenshots the active window toolbar. Bit unreliable. + [MenuItem( m_MenuItemName + "Snap Active Toolbar %&k", false, 115)] + public static void ScreenshotToolbar() + { + Debug.Log("Screenshot Active Toolbar"); + var method = screenShotsType.GetMethod("ScreenshotToolbar"); + if ( null != method ) method.Invoke(null, null); + } + + /// Screenshots the Component you rollover next. Bit unreliable. + [MenuItem( m_MenuItemName + "Snap Component on Rollover %&l", false, 115)] + public static void ScreenShotComponent() + { + Debug.Log("Snap Component - Waiting for rollover on taget component"); + var method = screenShotsType.GetMethod("ScreenShotComponent", new System.Type[0]); + if ( null != method ) method.Invoke(null, new object[0]); + } + } +} + +/* +* var assembly = typeof(EditorApplication).Assembly; +* var screenShotsType = assembly.GetType("UnityEditor.ScreenShots", true); +* +* static Type unityEditorScreenShotsClassType; +* static Type GetScreenShotsClassType() { return typeof(EditorApplication).Assembly.GetType("UnityEditor.ScreenShots", true); } +*/ diff --git a/Assets/NoiseCrimeStudios/Editor/Internal/InternalScreenShotting.cs.meta b/Assets/NoiseCrimeStudios/Editor/Internal/InternalScreenShotting.cs.meta new file mode 100644 index 0000000..16953e0 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Internal/InternalScreenShotting.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d81f407713880f849959075892ca96e7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/NoiseCrimeStudioToolEnum.cs b/Assets/NoiseCrimeStudios/Editor/NoiseCrimeStudioToolEnum.cs new file mode 100644 index 0000000..4b1413c --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/NoiseCrimeStudioToolEnum.cs @@ -0,0 +1,77 @@ +namespace NoiseCrimeStudios.Editor +{ + /// + /// Setting a MenuItems priority prior to 2019.1 generally requires restarting Unity in most cases for it to be picked up. + /// Deleting, compiling, then restoring a priority may be sufficient to force Unity to reflect changes. + /// Unity Menu's and priorties link - https://blog.redbluegames.com/guide-to-extending-unity-editors-menus-b2de47a746db + /// PreviousPriorty + 11 == divider between entries. + /// As the menu path defines where item goes, the priorty can start at any value? + /// + + public enum WindowMenuItemPriorty + { + None = 0, + + // NoiseCrimeStudio Specific + Inspectors = 400, // Window/NoiseCrimeStudios/Inspectors + EditorSettings = 411, // Window/NoiseCrimeStudios/Settings 1105 + EditorTools = 422, // Window/NoiseCrimeStudios/Tools 1110 + Windows = 433, // Window/NoiseCrimeStudios/ 1130 + Examples = 444, // Window/NoiseCrimeStudios/Examples + Validations = 499 // Window/NoiseCrimeStudios/Validations + } + + /// Enumeration for Asset Menu Items. + public enum AssetMenuItemPriority + { + Default = 0, + + // Create + CreateScripts = 105, // Assets/Create + + // Asset + Packages = 200, // Assets/ImportAssetPackage + References = 201, // Assets/Reference Checker + + AssetInspectors = 202, + + AssetTools = 210, // Assets/Tools + AssetInfo = 221, // Assets/Tools - Info + + Legacy = 1000 + } + + /// Enumeration for Project Menu Items. Where Project is the specific Unity Project. + public enum ProjectMenuItemPriority + { + Default = 0, + Build = 10, // Project/Build + Tools = 50, // Project/Tools + Validation = 200 // Project/Validation + } + + /* Needs to be in Core! + /// Enumeration for CreateAsset Menu Items. + public enum CreateAssetMenuItemPriority + { + // TODO For ScriptableObjects + } + */ + + /// Enumeration for GameObject Menu Items. + public enum GameObjectMenuPriority + { + Default = -100, + CreateBegin = -10, + CreateEmpty = -1, + Create3D = 0, + Create2D = 1, + CreateEnd = 11, + + ChildrenTop = 49, + ChildrenEnd = 50, + + ParentEnd = 100, + DefaultEnd = 500 + } +} diff --git a/Assets/NoiseCrimeStudios/Editor/NoiseCrimeStudioToolEnum.cs.meta b/Assets/NoiseCrimeStudios/Editor/NoiseCrimeStudioToolEnum.cs.meta new file mode 100644 index 0000000..7c16802 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/NoiseCrimeStudioToolEnum.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e84b06966575856468b06e0088c0a4b1 +timeCreated: 1502730104 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources.meta b/Assets/NoiseCrimeStudios/Editor/Resources.meta new file mode 100644 index 0000000..2f42656 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 504126d0aae528f4298d6d77f13f11b3 +folderAsset: yes +timeCreated: 1499699019 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons.meta new file mode 100644 index 0000000..5083efb --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 61fec4f7862b3394ea4883f1989530b9 +folderAsset: yes +timeCreated: 1507122793 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_black_18dp_1x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_black_18dp_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..72ccdf6feba07ab4ae50495d5179678f4551866d GIT binary patch literal 265 zcmV+k0rvihP)E P00000NkvXXu0mjfjaz16 literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_black_18dp_1x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_black_18dp_1x.png.meta new file mode 100644 index 0000000..07d2dfa --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_black_18dp_1x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: f045141f5dae8e847b6bd0305fe1f351 +timeCreated: 1594042974 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_black_18dp_x2.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_black_18dp_x2.png new file mode 100644 index 0000000000000000000000000000000000000000..dbad8555cfc0967b691a3dd52031e6f3cc58b6df GIT binary patch literal 411 zcmV;M0c8G(P)41Aii%3Snh!oWd@2yg$;tCUAS#gfAdwXayh0!ll@kaAq7pe#@$VHA%O#gD z`FAxNZ}K=ozLe`Fygd6aP0`?hGj88bXtBa8My*7^9R^4rcte4#)wsf(I?Rxz2A08q zcepFi!ZO>!)dn^S$CFyZMl@gs(pBii0X0p2wnG8g8tV7o!i1pDAy8tbzzNAri${qu z+RZUYyiMYu3wI>z-DCWt&Pdid#{?{#qYg;6ca0HOg3usY?HdFCs40?F_|%U!9wSF} z@<2NeWQfP;QR@426FkHrGz9~Wu!Jj0=qSKORzs)XxGWm)|F9D*vli~k%ui~A0>3VZ zgRb;gB5M}g@qXlKD_G#c0WVZojje^^*&VZrcs!y8;KeEbFvoMJe< z_rBSogb+&D!v%WN!44KFfgBESg)zRc+ln}t$`lKYa4(%kD#*<63YitQ@F8m!It^3X z_X|ZD`_@LMvR7d~@Jz9Pq_HUDC?rTsB8rcPWF1*kd2#5i5ne~uR2B|RkkOm)&Ga>U z4%Lvk=}jzF!&xRT^ literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_white_18dp_1x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_white_18dp_1x.png.meta new file mode 100644 index 0000000..2d58592 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_white_18dp_1x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: a95731b6612b27c4dad71bae6e359b67 +timeCreated: 1594043243 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 13 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_white_18dp_2x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_white_18dp_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..5169a788988891d13dae12223213eb8eede7b6d9 GIT binary patch literal 413 zcmV;O0b>4%P)TS2*?t9j(EQ$ zTa!j^q z9TWyQ4|=vuLAy3F7e*~oP%R7F6t*v$rl4`ln6!OlgA~+n8RLSe$NXdE5I${)iBWYJ z=#2c2IujG48oV#VJ@#n`HFLx)JYS=mYtnI)*UuGcREG{O00000NkvXX Hu0mjfJ2ST> literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_white_18dp_2x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_white_18dp_2x.png.meta new file mode 100644 index 0000000..a55cea8 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_cancel_white_18dp_2x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: b2334a6f91e7f2a4798154c50ff406e4 +timeCreated: 1594043243 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 13 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_black_18dp_1x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_black_18dp_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..6472ef1d81d300ba3bd141265296d71926a5b20a GIT binary patch literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rheqn<8~Ar*{C3)mkpB&93#v0t%r zH{fv&6lq&(pdr@P>NI!$*~$QoE5^&8hb*sRD_xiF*ILEZdZ>A~{H*CYyDN7_ZnFRR z<;ffwqZ!%;4;pH2Jea5)*~~hrN!@G3)Cfhlo|os{Iu0_MvsAqGHRwwzxUo^udClKM z7e78jen*G)n@cVU}^<+KdTnjBnjZ$*F}V(@hJb6Mw<&;$T) CW?%gP literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_black_18dp_1x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_black_18dp_1x.png.meta new file mode 100644 index 0000000..1221fad --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_black_18dp_1x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: a9ec28d8cad8ee9429beecd1e3b70dbd +timeCreated: 1594042974 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_black_18dp_2x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_black_18dp_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a1a0cbc45ebc4de4cdf993c5392f959b1e496a00 GIT binary patch literal 402 zcmV;D0d4+?P)_FL=7ac3X3{JVpwvgj*y6+*h5u{0TR#^U(R(~s463j$?)IK8FkX!oiWN7 zqAfb-J>~7N;uv7!jec2q4EW4=x~)0}Xnccuh-1Jvx(H*yZ#=ykv-4csHU{{eGpNJX z^C#9Z;Hh{Tw4(xz0p}@CEkr-cJO&){Jk=2WDB~EQoH~e!ew29(I1YQt@X(JkkLfX4 z1<{Q%i~$Nvw!x?zWf^lv0#yYhvK+IjA(51rU5YCtum+1u1K+7L5|}HDC&>Xv1Z{%~ w4~Wu;5-FmUAxDiCgY%-h;erEFymz1e0Nhk;LAK?PJpcdz07*qoM6N<$f?;~1<^TWy literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_black_18dp_2x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_black_18dp_2x.png.meta new file mode 100644 index 0000000..72f0ad1 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_black_18dp_2x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: e739c5be54ca2754982fe5119915c1ae +timeCreated: 1594042974 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_white_18dp_1x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_white_18dp_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..6a26db0c6da461fe57f16dc1d16ae9b2bdf6f580 GIT binary patch literal 261 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@RheGoCJvAr*{C3oIF~c(F?eFeOT~ zIdd>NH5^^!%yU6eOtGZF_K?g%<&p;1_7@DYK(2t(j9SBM67^|^>TDR+C)OqVv`MX9 zI^iCt$cw@Q_t|=FL{@H4*dqBfbjgvf8)r`}z0feD_QN4g-M!CxdX@y-*r-_QeD?2& z{8PM{5@m~yiU@DaUV4GARVG*?>H5xvd~O|?nvd3&IrB@{Put+|#NpZhI~qssg$wSE z+qGET>`0ztVd-5hqiu_Xl<%E(^RPBt;FFYYzo2=Wl=P4H`!ZcvZ>-YV^$6%M22WQ% Jmvv4FO#s9UXN&*< literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_white_18dp_1x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_white_18dp_1x.png.meta new file mode 100644 index 0000000..176ce2c --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_white_18dp_1x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: bc63023555362ab46857cf36bd1ddeb0 +timeCreated: 1594043243 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 13 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_white_18dp_2x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_white_18dp_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..5db6ba7e84891fa10e87241cc58317d94db36ed5 GIT binary patch literal 398 zcmV;90df9`P)bJ&wE=(y;Ck*d>qPhG{ z>w+elYj`WBuh~xFO`(Ooye;u|ad#abaemD6`F7_5HHiG3Lw3wLyrKd?l?L(oKny@T z1^Rk02F5AS_k%GoPl0x>+v5XO0~lDQKwM)w!Q*u>u#JPL@EZ6?T@36}pnV*b1p})T zXbn+R1`I4xpczC_88A?$Ks|_}GGL&a0zKmxMPN%BB(ntFp7X)aEPGp#BA_X zM8Zh(^@>}wi99{nO`c)=7$@eU}_Dw+yE;{oLm sXjGm@tB@Z9@o8ww(;4iL;SNRt0C4fPXI8Z$Bme*a07*qoM6N<$g6MdtcK`qY literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_white_18dp_2x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_white_18dp_2x.png.meta new file mode 100644 index 0000000..8cd8671 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/baseline_check_circle_white_18dp_2x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 905d6d70d5e6d8e4487714cc420d25a8 +timeCreated: 1594043243 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 13 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_black_18dp_1x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_black_18dp_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..9d514d1dd9d23d516bc45273586618ef4767351d GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mf;?RuLn;`P7Z_bgzHz32L72(4 z^g&j`oc|UN)LIrXTZqaYShs?KgHx-B!O2Thv_X`EL9s(`frH@FJS7>H7UszXTXI}9 mE~VaR(QRt<+OlHyB!-|H^CwL2tVsZx&fw|l=d#Wzp$PzZUMt4{ literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_black_18dp_1x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_black_18dp_1x.png.meta new file mode 100644 index 0000000..bb8a197 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_black_18dp_1x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 404c367d0e23d5a45945d5f455644997 +timeCreated: 1524827732 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_black_18dp_2x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_black_18dp_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..1137eb527f36bcd92497010c3f5ba44fd4f56947 GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K8i>HfYNCo5DsT+9@8}P97&pg9y zamvN0ZobG#j$3Em-SOb?Im9S^ck3a>vX4iOK5<;Qs5?(2XU@+})_;3~T5TUp?vvsQ zwG!ddRJmG}PF7KwVf o;Xq?eGLOOalk3(<@TswXJy*wBaBIgKpnDiRUHx3vIVCg!0FZe|kN^Mx literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_black_18dp_2x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_black_18dp_2x.png.meta new file mode 100644 index 0000000..44ed6a3 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_black_18dp_2x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: ab3b7dad4d275d646b0a001cf215eb50 +timeCreated: 1524827733 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_white_18dp_1x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_white_18dp_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..cda3b535c25751a829a997997a66f1a85e5f0156 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mLOop^Lp07OCoItVvHpAg=l{$R z51#$E;&7e)|1r~SfiAuWAtemE7cnWQtT@5Qp&1&&5T?M;qOhxh$@NOHFsEaKu|c8x qX}1=oyZ>izaQkrVf7BIUFNPf{Nw@Dk@_PlefWgz%&t;ucLK6U~7&Es3 literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_white_18dp_1x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_white_18dp_1x.png.meta new file mode 100644 index 0000000..2e0eff1 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_white_18dp_1x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 9a495e935e9e1644caac509943861254 +timeCreated: 1524827733 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_white_18dp_2x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_white_18dp_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0a1a3d8741cfb94d11f77f0ea719abd9403d70a2 GIT binary patch literal 193 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K8ho_5Uh{y4_R}XR?P~c&`aO0%R zfm@wZ-duLJZkqi!jx~36;D<@?&mLetsNyoKFQM6;!F(PEe{g!fnS5;UR>uq40IENr>mdKI;Vst0NvnBzyJUM literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_white_18dp_2x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_white_18dp_2x.png.meta new file mode 100644 index 0000000..fb69623 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_add_box_white_18dp_2x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 5a19e5a076e040c4bb6b1099fe06b1bf +timeCreated: 1524827732 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_black_18dp_1x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_black_18dp_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..4800461c6344c90d2750e3432850a09e30766640 GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|m{5@S9Ln;`P7YG_8STMA*?GUvz z_|xvheoO07LIJ}erX7oz4CXV(Mly#;F-mWkdCeh!(@D~a(=U}nwPGrxqN)Sq3VC6z h1QumAmM%V^xrd(HCl|kR^#vNu;OXk;vd$@?2>{3zBY^+_ literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_black_18dp_1x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_black_18dp_1x.png.meta new file mode 100644 index 0000000..6c28aef --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_black_18dp_1x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 6c5f652b572ef784894173cfd4c55c66 +timeCreated: 1524827733 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_black_18dp_2x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_black_18dp_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d9aacea4c67e78f5e6d75b133befa380f6d849c2 GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K8w5N+>NCo5DOB;Ea6-1Z=`wwaK zlr7#Ec`0zmrbkLnzs~>VT)6(!jYHeM3V+#XxRBFz+79ba7X-_-E8Go47Mzgi>REWg wMe|>k`#dLBo!|pTtSxP|xh8TPw&^vD-tvEwul@ZBw1t7e)78&qol`;+0AD0DVgLXD literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_black_18dp_2x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_black_18dp_2x.png.meta new file mode 100644 index 0000000..6d27e01 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_black_18dp_2x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: fdde4f6a9d35b6245bcde69e5a96d04e +timeCreated: 1524827734 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_white_18dp_1x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_white_18dp_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..108022c7ee96fb10349a752bee7a36aa604db6c3 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mf;?RuLp07OCoJInk^kX8gNW3F zuqPkn*<>Tl&T>`8V lI3)rY!wr;}+1nZ!80PMu$$3Ro|k0wldT1B8K8mZytjh{y4_Q*ZMgP~c#YJsK$U z)~(q1m-m)lF^^vy&zFBx;@>#sNTW$[{bH;=%sZG7QZ>uQBcw?@Ce|ClF7G156^ z#Rt_}Q9HRs{l8sYa>)1&$3+cMLFMTJXY2PZ*sH$V@BeR?lj;@>g(qYZ*L3k@0BvRP MboFyt=akR{0D4_J0ssI2 literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_white_18dp_2x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_white_18dp_2x.png.meta new file mode 100644 index 0000000..d9a65a4 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_file_download_white_18dp_2x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 711b02b4b918e1d45b7f7474f2f30f10 +timeCreated: 1507122904 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_folder_black_18dp_1x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_folder_black_18dp_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..fb51c4b100c90c3e1bcb801cd16e0226cd598516 GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mv^-rLLn;`PB{&KuJ+zlGdl0}p wNoCC&d%ub%3D^G|k0wldT1B8K;m#2$kNCo5DGY5Ga0(cGw=y&Y9 z(NUN=orC#6tJZY=qx&K(?)(Oo*p8|>krS9nPtDIuh3|QdM_$FZSLG$%u erU`tPj@dGPOY#&^cc#$ x3zt+!U<;3*z~UGGS175tsu!%Xv|?Dv!Z6Fz=%3p3y>dWp44$rjF6*2UngIPX9TNZm literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_folder_white_18dp_1x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_folder_white_18dp_1x.png.meta new file mode 100644 index 0000000..1868ac3 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_folder_white_18dp_1x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 71c0fca928dafaf418362f4bd79c78c7 +timeCreated: 1507134190 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_folder_white_18dp_2x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_folder_white_18dp_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..02ea533a8d662e512843bf218e372653e95d843b GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K;pQnpsh{y4_S5I>?DDbdcG|@-9=YT$JMXzmt#dNS2?*=lWh#>dpH2(p4PmL*eYef zTriX}7R-Q^pppDiQ?N{peq!~}LUr9JIhqKjK&G@wj&@2dfTO$K+nWX+_9|@`g}%Ch zi?d8kSK)4JtQniwc{uy>B6m>Me(+uS-P=?%O3jv@aJa6HGW<0ceyC!`rEoc~?j{U=`ic|b z9N*QPsMv*+MQv@1i8kR%)UIh1`=XoCqqIYBOKErvea{GWZ!y>;D~RpT`=%tUi9cM8 zjMJd-5IZXpx*;AQpQG66NVp4e3Hh{Q=T<@);yl@>u@F125nkF002ovPDHLkV1kFY-~<2w literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_black_18dp_2x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_black_18dp_2x.png.meta new file mode 100644 index 0000000..a04eae9 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_black_18dp_2x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: e2abb8891aacf1e4e8fd2a9a5f1b67e7 +timeCreated: 1524827734 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_white_18dp_1x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_white_18dp_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..384504c6f5af177df155d0c125c59741754c73a7 GIT binary patch literal 271 zcmV+q0r38bP)BfoP7CwN=qbK<;C9lj)=uK)sx$n z?OrS&2@fa;#EP2*GYo3Yj4-{*2#wlGO)To5gF^+Hm(LArp)n>`87i!5p|!%>{jihi zzI;JnZd1BwOC@?0XML$-WrjKunb=5E)7V<>=;L(*wu&DE-u$)+p{a$r$)nxB$2a|A V&B&aJS2zFw002ovPDHLkV1k#bcJ=@O literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_white_18dp_1x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_white_18dp_1x.png.meta new file mode 100644 index 0000000..95113fe --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_white_18dp_1x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: f37ec6f470fb30f48a76536604114f34 +timeCreated: 1507122904 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_white_18dp_2x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_info_outline_white_18dp_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c7b1113cfef22bcec86ead7ae67be12326276cab GIT binary patch literal 485 zcmVW+#V#f>U=9~3v zy5k#|%`o-bRp5gvNWBjKU}@RX_o(#cOX<;tO*2A$>f4JBeW-BBCp2Wv4dAi~>H>ZU-{cI? zse=}k;97{XqEJ|gdQ)z}NLv+h2nN-m6riYd=e>Y~D%A1;c7!A-*ac%VF|-AqWJ2?3 zQF6~X51D>It4ihg|)rzQwa>o;%bj)#rEu3g_bm z0fv<`T4D;hzb7|BT8w#W@?gXl8;#aYk6vpA-H!2$9P*8A}UWEw$p*LXfBIFLtCW2mswzER-LBvrv6+2odMMZ0d^68Rt z(6o7z45B{ocHq4E4&i@twCK_&CFPb5TU65I9RDR}tWeS#FZi51vx<&pR+Ez_{Z-B! zm6uaQEqp;Xk#x<W+f&Qo9Pvj zj#){GSs)~~2Xlm^jW5VHl35<7);utS=wNEmKC&f-6KjSnqGNAj(JrL~403Dk2q>v7 z{x8AFx0+)rX>gCN8PK4j4MyXd5$n{DjEi=t#nHp#>EWnpo=Yy6gZh>~^K%lsnB=z= a{UIOCv{_*!f}CUk0000XRJ?P7KFhQj4qWLU? z6wX*CucCUp>s#wa)$P4ta2TUUlh7lxPE?Bfsu4AI(2|bWW^3c<{7drJ5HJBM0rr6&nz#Lln+g2X(&Ig znRcZjDD%o+eab3^1IA2@*;jEmCXTfX0y_Na5NJ7Ua?c$bS{@ZD`ZqYNoU-7sa>|0k c%4t>n0Dko4;$U0=y#N3J07*qoM6N<$g1Rk)y8r+H literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_pin_drop_white_18dp_2x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_pin_drop_white_18dp_2x.png.meta new file mode 100644 index 0000000..4e98f11 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_pin_drop_white_18dp_2x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 10626e78addedab44911c33edf12dc05 +timeCreated: 1507122904 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_square_white_18dp_1x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_square_white_18dp_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..88f1a39cfe7be99f3629953a6a4e0a937804d674 GIT binary patch literal 81 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mBs^UlLo_BP|M@?^Q6WKTO-jhc e6-uwPm>6O^n3V1Xw;2J|FnGH9xvX|k0wldT1B8K8kf)1dh)3t!Ya4kFC(vFpg-;}y%ssv__?JCDF}wS#&BVFE40|WayE6Q3RZCc)d5gg#P0}dk!~{j> mwr`Cs+tWBCB-lfX|El@>30^#X?O`|2bOujXKbLh*2~7YWcrQKx literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_square_white_18dp_2x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_square_white_18dp_2x.png.meta new file mode 100644 index 0000000..30e35ed --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_square_white_18dp_2x.png.meta @@ -0,0 +1,100 @@ +fileFormatVersion: 2 +guid: c63db4192bb8e52408217529706fda03 +timeCreated: 1593917420 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: WebGL + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_black_18dp_1x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_black_18dp_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..b125aa04146e66d6e1758eb5ef977110ab317be3 GIT binary patch literal 217 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|m7I?ZihEy;nEAW3{QgobfdV;S9 zr}AOmw(J&>orZtdoznkwnKg^9JwD|@+J&SI=^Uvik}}eMaEEx%~aQ|*Pi>J&v=b3wE$LG8MEr0%P=cnz7#~$g4jD2yc9`&S%#vjw5|Y!>q=2|S(dv( zn7HqV)RG4#LbxN#Tj8|}c5=}h;gt-FN;eeh%)6;{NUP;(ZTgn%+JC7%^iR}Ze;xR;nPZ%xaA6W00-c21_z>%WekO*bs{6mMG7g+4Q0tmBumImb46~FWEVM0C}|FsQe!D%;$(@q zc+@nODf51M2gPf~{CRGCAOEy@=J_kmIqNSNr^gp#)vQg#9yJ>5wTM>+tH~-65i8W> zmU!Z+xUL4XL~ON9M6*A3LUb8ngf4N^A8PVR98z&ud^FyGW?Evco%T8Dk`B*xizu6- zVw#Bf?4`S|IBmaO)>&$%pS0>05fKp)am{z_A|fIpBD%Gz(&DX%vdd1`Ylk%!Yx3O$ z%dEHC0cTuQ7V*X$eVD9M#6`pW%1{?XJT^%`8nlbJt4V(vb%pf(X7EK+Tu_afR9v`&w>q1sK+W39sKd=Pt8+b`a$Q&_Wz<*K!cn4z%EqHLs! z(T+Q2l!{TxVw1woi$|!pQAxx*8`PmwoK@IMaYTy_5xsgv+&0@$@k~JzMRe*F(V@j$ zcSL;kNW=t%tQHYbvQfQ?dYhC)M66WEVG(7=jrOB4PAZEysE~)^zWMsHzyonl0S!vF qsMnuCwksKKK#dv=q{$fn{kCrli_lEC3K^aN00005>2 z&nm+K902g|YPAEq?1(&o6%XKFN|O7m+#SeH@&x=&Qj`m>?5uf%opy7u;-;K;v$b0E zFGdi7){EP#~96;mX_5R#hpu6Zex%!GnN(XI`nSVoHvP*q7`}L z@kve<4K)=>bV*dyG*Fd`FEYv+=A(}V4L36JO-iC|GkO%Y9ZAI?XYQj%-DwP?>^wqV zKEj3T7{-fjCptQg?Rbu#Orz<+q9t`rOvE5tUhPXqm$U;-g&1VRWb`p*J^tMX9YC0! T;%W+K00000NkvXXu0mjfBzSWR literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_border_white_18dp_1x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_border_white_18dp_1x.png.meta new file mode 100644 index 0000000..a1d8662 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_border_white_18dp_1x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: b5cc75ace63227b4f94d71aa2f8150b0 +timeCreated: 1507122904 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_border_white_18dp_2x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_border_white_18dp_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..e302ef6fa26e5cf7deff038119b579adfd8c1240 GIT binary patch literal 504 zcmV902g|#tuZ&Fr#qv9+@Z?DWtR;3d>28yoB7eE6Yuiupx4mP|^-wO3h2rEKXw) z7Z0U*S=saP{IV7E%=5R$jn60IUuLPL@i(~Oe3Z`=eZH6+<TSr8+o6(5W@-UpnFkx}Opjzxjv_-JaBV!qY3*ype|S9Ex; zSCTg?3e54{XFcw_=ByU`HCkhS{78dd#oUMi+7;8QA%3Rb8%f?(tq$31vsLP1fN9p+ z>VPB8xh^kxZE^g{OkI-8#>Q_LBK?c#lIdgciJ05m{LvSr_Fax zC@|4!r_@A&8hLDwtXxEAgi1|vlDD?0h|q=ek(C~tP_IMMuU~T4A}7%u*_bZr(l6;y zZ;5-7uR0~uA`6=g%4t#=1uAWqGiXC(;kYF4w2AQpleEc8jz$(9YcJ!r^xFoB`%;d;-* z7b13X7B<{#*I;pRCgW04e_*IotzOTDuPtY1Xg6MZ5g5!=y6e|&_V9oc VLdQxU0-eji;OXk;vd$@?2>=F-RG$C< literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_white_18dp_1x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_white_18dp_1x.png.meta new file mode 100644 index 0000000..00a3be5 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_white_18dp_1x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: d7edea0ee5eca524da7610fde0972e8f +timeCreated: 1507122904 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_white_18dp_2x.png b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_white_18dp_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..86eecdd4a0a40e1fe48095fd5262398828101f17 GIT binary patch literal 370 zcmV-&0ge8NP)MEjoCkkyqJc zlx9X`i)ETwkS+FTW?Qy+z*M1v=~i|a#8f241ZS8cvOyA8iA4hXLVzVoxMpR8b!w_? z(kBBU3RJ0ClMSwb3no;M1&07*qoM6N<$g6P$m>i_@% literal 0 HcmV?d00001 diff --git a/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_white_18dp_2x.png.meta b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_white_18dp_2x.png.meta new file mode 100644 index 0000000..9dab080 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons/ic_star_white_18dp_2x.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 450dcd643ffb4e44d95ae909758d1bfa +timeCreated: 1507122904 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: 4 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 5 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Support.meta b/Assets/NoiseCrimeStudios/Editor/Support.meta new file mode 100644 index 0000000..221c82d --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Support.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2ac547b47415b6347b22e23855781153 +folderAsset: yes +timeCreated: 1491150837 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI.meta b/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI.meta new file mode 100644 index 0000000..e638874 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 37a4dc095799c34418003767e89ec1de +folderAsset: yes +timeCreated: 1592882982 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIClippedScrollView.cs b/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIClippedScrollView.cs new file mode 100644 index 0000000..924c209 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIClippedScrollView.cs @@ -0,0 +1,56 @@ +using UnityEngine; + +namespace NoiseCrimeStudios.Editor.IMGUI +{ + /// Support for a clipped Unity IMGUI ScrollView. + /// + /// When a ScrollView displays rows of items from a list Unity does not clip the rows to the view. + /// This class provides support for clipping the rows to the view thus improving overall performance. + /// + public class EditorGUIClippedScrollView + { + public int itemStartIndex { get; set; } + public int itemLastIndex { get; set; } + public float pixelStartHeight { get; set; } + public float pixelEndHeight { get; set; } + + public Rect lastScrollRectResults { get; set; } + public string information { get; set; } + + /// Support for a clipped Unity IMGUI ScrollView. + /// Number of items in List being displayed in scrollview. + /// Universal line height of each row. + /// ScrollView vertical position of scroll. + public EditorGUIClippedScrollView( int itemCount, float lineHeight, float scrollPosY ) + { + Update( itemCount, lineHeight, scrollPosY ); + } + + public void Update( int itemCount, float lineHeight, float scrollPosY ) + { + float rowHeight = lineHeight + 2f; + int maxRows = Mathf.FloorToInt( lastScrollRectResults.height / rowHeight ) + 2; + itemStartIndex = Mathf.FloorToInt( scrollPosY / rowHeight ); + itemLastIndex = itemStartIndex + maxRows; + + pixelStartHeight = itemStartIndex * rowHeight; + pixelEndHeight = itemCount * rowHeight - itemStartIndex * rowHeight - maxRows * rowHeight; + + if ( itemLastIndex > itemCount ) itemLastIndex = itemCount; + if ( pixelEndHeight < 0f ) pixelEndHeight = 0f; + + information = string.Format + ( + "Information: Count: {0} Rows: {1} Index: [ {2} | {3} | {4} ] scrollPos: {5} Height [ Rows: {6} View: {7} total {8} / {9} ] pixel: {10} / {11}", + itemCount, maxRows, + itemStartIndex, itemLastIndex, itemCount - itemLastIndex, + scrollPosY, + maxRows * rowHeight, + lastScrollRectResults.height, + itemCount * rowHeight, + pixelStartHeight + pixelEndHeight + lastScrollRectResults.height, + pixelStartHeight, pixelEndHeight + ); + } + } +} diff --git a/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIClippedScrollView.cs.meta b/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIClippedScrollView.cs.meta new file mode 100644 index 0000000..d88c80a --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIClippedScrollView.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 34f9300684f050f4d84c1d2bb477af02 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIMethods.cs b/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIMethods.cs new file mode 100644 index 0000000..799dee6 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIMethods.cs @@ -0,0 +1,101 @@ +using UnityEditor; +using UnityEngine; + +namespace NoiseCrimeStudios.Editor.IMGUI +{ + /// Collection of static methods to help with Unity's Immediate Mode GUI layout. + public static class EditorGUIMethods + { + #region Texture Generation + public static Texture2D CreateTexture( int width, int height, Color32 col ) + { + // UnityEngine.Debug.LogFormat("Color: {0} HasProLicense: {1} colorSpace: {2}", col, Application.HasProLicense(), PlayerSettings.colorSpace); + bool linear = false; // ( PlayerSettings.colorSpace == ColorSpace.Linear ); + + Color32[] pix = new Color32[width*height]; + + for ( int i = 0; i < pix.Length; i++ ) + pix[ i ] = col; + + Texture2D result = new Texture2D(width, height, TextureFormat.ARGB32, false, linear ); + result.SetPixels32( pix ); + result.Apply(); + + return result; + } + #endregion + + public static void PresentOpenFolderDialog( ref string folderPath, string title, string defaultName ) + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PrefixLabel( "Location", EditorStyles.popup ); + + if ( GUILayout.Button( string.IsNullOrEmpty( folderPath ) ? "Browse..." : folderPath, EditorStyles.popup, GUILayout.Width( 320f ) ) ) + { + var path = EditorUtility.OpenFolderPanel( title, folderPath, defaultName); + if ( path.Length > 0 ) folderPath = path; + } + EditorGUILayout.EndHorizontal(); + } + + #region CUSTOM SINGLE LINE GUI + public static void SingleLineVector2Field( string title, ref Vector2 input ) + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PrefixLabel( title ); + input = EditorGUILayout.Vector2Field( "", input ); + EditorGUILayout.EndHorizontal(); + } + + public static void SingleLineRectField( string title, ref Rect input ) + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PrefixLabel( title ); + input = EditorGUILayout.RectField( "", input ); + EditorGUILayout.EndHorizontal(); + } + #endregion + + + #region Boxes + public static float BeginBoxOut() + { + Rect r = EditorGUILayout.BeginHorizontal (); + GUI.Box( r, GUIContent.none ); + EditorGUILayout.BeginVertical(); + return r.y; + } + + public static void EndBoxOut() + { + EditorGUILayout.EndVertical(); + EditorGUILayout.EndHorizontal(); + } + + public static float BeginBoxOutBordered( int border ) + { + Rect r = EditorGUILayout.BeginHorizontal (); + GUI.Box( r, GUIContent.none ); + EditorGUILayout.BeginVertical(); + + GUILayout.Space( border ); + EditorGUILayout.BeginHorizontal(); + GUILayout.Space( border ); + EditorGUILayout.BeginVertical(); + + return r.y; + } + + public static void EndBoxOutBordered( int border ) + { + GUILayout.Space( border ); + EditorGUILayout.EndVertical(); + GUILayout.Space( border ); + EditorGUILayout.EndHorizontal(); + + EditorGUILayout.EndVertical(); + EditorGUILayout.EndHorizontal(); + } + #endregion + } +} diff --git a/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIMethods.cs.meta b/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIMethods.cs.meta new file mode 100644 index 0000000..10e2950 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIMethods.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e8c81f23ce2bdb946a149fcc5985fff8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIStyles.cs b/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIStyles.cs new file mode 100644 index 0000000..a1c4522 --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIStyles.cs @@ -0,0 +1,161 @@ +using UnityEditor; +using UnityEngine; + +namespace NoiseCrimeStudios.Editor.IMGUI +{ + /// Collection of custom styles for Unity's Immediate Mode GUI layout. + /// + /// Loading Unity Editor Icons as GUIContent + /// EditorGUIUtility.IconContent("d_Refresh") + /// + public static class EditorGUIStyles + { + #region Unity Styles Reference + // EditorStyles.centeredGreyMiniLabel + // EditorStyles.miniLabel + // EditorStyles.miniButton + // EditorStyles.toolbar + // EditorStyles.toolbarButton + #endregion + + #region Label Styles + public static GUIStyle labelBgLightLeft; + public static GUIStyle labelBgLightRight; + public static GUIStyle labelBgDarkLeft; + public static GUIStyle labelBgDarkRight; + public static GUIStyle labelBgStdLeft; + public static GUIStyle labelBgStdRight; + + public static GUIStyle labelNormLeft; + public static GUIStyle labelNormRight; + public static GUIStyle labelBoldLeft; + public static GUIStyle labelBoldRight; + + public static GUIStyle labelNormIcon; + #endregion + + public static GUIStyle fullButton; + + public static GUIStyle miniButtonDark; + public static GUIStyle miniButtonLight; + + public static GUIStyle textAreaImage; + + public static GUIStyle scopeDark; + public static GUIStyle scopeLight; + public static GUIStyle scopeStd; + + public static Color errorColor = new Color( 0.5f, 0f, 0f ); + public static Color warningColor = Color.yellow; + public static Color normalColor = Color.white; + public static Color disabledColor = Color.gray; + + public static Color colorContentNormal = Color.white; + public static Color colorContentError = new Color( 0.5f, 0f, 0f ); + public static Color colorContentWarning = Color.yellow; + public static Color colorContentGreen = Color.green; + + // How to destroy these? + public static Texture2D backgroundTxDark; + public static Texture2D backgroundTxStd; + public static Texture2D backgroundTxLight; + + // GUISkin skin = EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector); + + + static EditorGUIStyles() + { + bool hasProLicense = Application.HasProLicense(); + + // Textures + backgroundTxDark = EditorGUIMethods.CreateTexture( 8, 8, hasProLicense ? new Color32( 48, 48, 48, 255 ) : new Color32( 154, 154, 154, 255 ) ); + backgroundTxLight = EditorGUIMethods.CreateTexture( 8, 8, hasProLicense ? new Color32( 64, 64, 64, 255 ) : new Color32( 193, 193, 193, 255 ) ); + backgroundTxStd = EditorGUIMethods.CreateTexture( 8, 8, hasProLicense ? new Color32( 56, 56, 56, 255 ) : new Color32( 162, 162, 162, 255 ) ); + // backgroundTextureSelect = IMGUIMethods.CreateTexture(8,8, new Color32(56,56,156,255)); + + RectOffset margin = new RectOffset(0,0,0,0); + RectOffset padding = new RectOffset(2,2,2,2); + + DefineStyle( ref fullButton, GUI.skin.button, FontStyle.Normal, TextAnchor.MiddleCenter, null, null, margin, new RectOffset( 2, 2, 2, 2 ) ); + + DefineStyle( ref scopeLight, EditorStyles.label, FontStyle.Normal, TextAnchor.MiddleCenter, backgroundTxLight, null, margin, padding ); + DefineStyle( ref scopeStd, EditorStyles.label, FontStyle.Normal, TextAnchor.MiddleCenter, backgroundTxStd, null, margin, padding ); + DefineStyle( ref scopeDark, EditorStyles.label, FontStyle.Normal, TextAnchor.MiddleCenter, backgroundTxDark, null, margin, padding ); + + DefineStyle( ref miniButtonLight, EditorStyles.miniButton, EditorStyles.miniButton.fontStyle, EditorStyles.miniButton.alignment, backgroundTxLight ); + DefineStyle( ref miniButtonDark, EditorStyles.miniButton, EditorStyles.miniButton.fontStyle, EditorStyles.miniButton.alignment, backgroundTxDark ); + + DefineStyle( ref labelBgLightLeft, EditorStyles.label, FontStyle.Normal, TextAnchor.MiddleLeft, backgroundTxLight ); + DefineStyle( ref labelBgLightRight, EditorStyles.label, FontStyle.Normal, TextAnchor.MiddleRight, backgroundTxLight ); + DefineStyle( ref labelBgStdLeft, EditorStyles.label, FontStyle.Normal, TextAnchor.MiddleLeft, backgroundTxStd ); + DefineStyle( ref labelBgStdRight, EditorStyles.label, FontStyle.Normal, TextAnchor.MiddleRight, backgroundTxStd ); + DefineStyle( ref labelBgDarkLeft, EditorStyles.label, FontStyle.Normal, TextAnchor.MiddleLeft, backgroundTxDark ); + DefineStyle( ref labelBgDarkRight, EditorStyles.label, FontStyle.Normal, TextAnchor.MiddleRight, backgroundTxDark ); + + DefineStyle( ref labelNormLeft, EditorStyles.label, FontStyle.Normal, TextAnchor.MiddleLeft ); + DefineStyle( ref labelNormRight, EditorStyles.label, FontStyle.Normal, TextAnchor.MiddleRight ); + DefineStyle( ref labelBoldLeft, EditorStyles.label, FontStyle.Bold, TextAnchor.MiddleLeft ); + DefineStyle( ref labelBoldRight, EditorStyles.label, FontStyle.Bold, TextAnchor.MiddleRight ); + DefineStyle( ref labelNormIcon, EditorStyles.label, FontStyle.Normal, TextAnchor.MiddleCenter, null, null, null, new RectOffset( 2, 2, 2, 2 ) ); + + textAreaImage = new GUIStyle( EditorStyles.textArea ) + { + imagePosition = ImagePosition.ImageOnly, + alignment = TextAnchor.MiddleCenter + }; + } + + static void DefineStyle( ref GUIStyle style, GUIStyle from, FontStyle font, TextAnchor anchor, Texture2D normalBG = null, RectOffset border = null, RectOffset margin = null, RectOffset padding = null ) + { + if ( null == border ) border = from.border; + if ( null == margin ) margin = from.margin; + if ( null == padding ) padding = from.padding; + + style = new GUIStyle( from ) + { + fontStyle = font, + alignment = anchor, + border = border, + margin = margin, + padding = padding + }; + + if ( null != normalBG ) style.normal.background = normalBG; + } + + /// Create Google Material Icons & Content Helper Method. + /// '{0}ic_file_download_{1}_18dp_1x.png' + public static void CreateIconContent( ref Texture iconTexture, ref GUIContent iconContent, string materialIconsPath, string iconNameFormat, string contentText ) + { + string iconColor = Application.HasProLicense() ? "white" : "black"; + + if ( null == iconTexture ) + iconTexture = ( Texture )AssetDatabase.LoadAssetAtPath( string.Format( iconNameFormat, materialIconsPath, iconColor ), typeof( Texture ) ); + + if ( null == iconContent ) + iconContent = new GUIContent( iconTexture, contentText ); + } + } +} + + +/* +// Examples - just copy the OnGUI into an editorWindow class to check out the styles. +protected virtual void OnGUI() +{ + EditorGUILayout.LabelField("Test Label Dark Left", IMGUICustomStyles.leftAlignLabelDark, GUILayout.MinWidth(256f), GUILayout.MaxWidth(256f)); + EditorGUILayout.LabelField("Test Label Light Left", IMGUICustomStyles.leftAlignLabelLight, GUILayout.MinWidth(256f), GUILayout.MaxWidth(256f)); + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Test Label Dark Right", IMGUICustomStyles.rightAlignLabelDark, GUILayout.MinWidth(256f), GUILayout.MaxWidth(256f)); + EditorGUILayout.LabelField("Test Label Light Right", IMGUICustomStyles.rightAlignLabelLight, GUILayout.MinWidth(256f), GUILayout.MaxWidth(256f)); + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Test Label Left Bold", IMGUICustomStyles.leftBoldLabel, GUILayout.MinWidth(256f), GUILayout.MaxWidth(256f)); + EditorGUILayout.LabelField("Test Label Light Norm", IMGUICustomStyles.leftNormalLabel, GUILayout.MinWidth(256f), GUILayout.MaxWidth(256f)); + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Test Label Right Bold", IMGUICustomStyles.rightBoldLabel, GUILayout.MinWidth(256f), GUILayout.MaxWidth(256f)); + EditorGUILayout.LabelField("Test Label Right Norm", IMGUICustomStyles.rightNormalLabel, GUILayout.MinWidth(256f), GUILayout.MaxWidth(256f)); +} +*/ diff --git a/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIStyles.cs.meta b/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIStyles.cs.meta new file mode 100644 index 0000000..23b095e --- /dev/null +++ b/Assets/NoiseCrimeStudios/Editor/Support/EditorGUI/EditorGUIStyles.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5274f83eb29e62e43b9c6895fdbf82cf +timeCreated: 1593926591 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudiosToolbox.meta b/Assets/NoiseCrimeStudiosToolbox.meta new file mode 100644 index 0000000..c5b0de9 --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 9e424032b32f6f54caa05f332100fb2e +folderAsset: yes +timeCreated: 1594719228 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor.meta b/Assets/NoiseCrimeStudiosToolbox/Editor.meta new file mode 100644 index 0000000..821b0de --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 06b61359e7396644abf9f55e727826a5 +folderAsset: yes +timeCreated: 1616505232 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer.meta b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer.meta new file mode 100644 index 0000000..5893226 --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 5ccbced43530f8f4e8370e10d1632765 +folderAsset: yes +timeCreated: 1525113739 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/AssetPackage.cs b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/AssetPackage.cs new file mode 100644 index 0000000..077ee9f --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/AssetPackage.cs @@ -0,0 +1,246 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using NoiseCrimeStudios.Core.Formatting; +using NoiseCrimeStudios.Core.IO; +using UnityEditor; +using UnityEngine; + +namespace NoiseCrimeStudios.Toolbox.AssetStoreOrganizer +{ + /// AssetStorePackage Container + /// Editor\Mono\AssetStore\AssetStoreContext.cs + public class AssetPackage + { + [Serializable] + public class StorePackageLink + { + public string id; + public string type; + } + + [Serializable] + public class StorePackageLabelWithID + { + public string id; + public string label; + } + + // Custom Properties + public string fullFilePath; + public long fileSize; + public bool isUnityStandardAsset; + public bool isArchived; + + public DateTime modifiedDate; // DateTime for correct sorting + public DateTime publishDate; // DateTime for correct sorting + + // Precalculate display values for optimal performance + public string displayModifiedDate; // Display date + public string displayFileSize; // Display FileSize + + // Unity Package Properties from Json + public string unity_version; + public string pubdate; + public string version; + public string description; // Not in JSON? + public int upload_id; + public int version_id; + public int id; + public string title; + public string baseCategory; // Cached base category for easy filter generation. + + public StorePackageLink link; + public StorePackageLabelWithID category; + public StorePackageLabelWithID publisher; + + // See Editor\Mono\AssetStore\AssetStoreContext.cs + private static Regex s_StandardPackage52RegExp = new Regex("/Standard Packages/(Character\\ Controller|Glass\\ Refraction\\ \\(Pro\\ Only\\)|Image\\ Effects\\ \\(Pro\\ Only\\)|Light\\ Cookies|Light\\ Flares|Particles|Physic\\ Materials|Projectors|Scripts|Standard\\ Assets\\ \\(Mobile\\)|Skyboxes|Terrain\\ Assets|Toon\\ Shading|Tree\\ Creator|Water\\ \\(Basic\\)|Water\\ \\(Pro\\ Only\\))\\.unitypackage$", RegexOptions.IgnoreCase); + // private static Regex s_StandardPackage54RegExp = new Regex("/Standard Packages/(2D\\ Assets|Toon\\ Shading|Tree\\ Creator|Water\\ \\(Basic\\)|Water\\ \\(Pro\\ Only\\))\\.unitypackage$", RegexOptions.IgnoreCase); + // private static Regex s_GeneratedIDRegExp = new Regex("^\\{(.*)\\}$"); + // private static Regex s_InvalidPathCharsRegExp = new Regex("[^a-zA-Z0-9() _-]"); + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendFormat( "Title: {0} [Size: {1} UnityStandardAsset: {2} IsArchived: {3}]\n", title, fileSize, isUnityStandardAsset, isArchived ); + sb.AppendFormat( "PubDate: {0} unity_version: {1} version: {2} version_id: {3} upload_id: {4} id: {5}\n", pubdate, unity_version, version, version_id, upload_id, id ); + sb.AppendFormat( "Link: id: {0} Type: {1}\n", link.id, link.type ); + sb.AppendFormat( "Category id: {0} label: {1} Base: {2}\n", category.id, category.label, baseCategory ); + sb.AppendFormat( "Publisher id: {0} label: {1}\n", publisher.id, publisher.label ); + sb.AppendFormat( "Package: {0}\n", fullFilePath); + sb.AppendFormat( "Description: {0}\n", description); + return sb.ToString(); + } + + public static long CreatePackageInfoFromLocalStorage( string fullFilePath, List results ) + { + long sizeOnDisk = 0; + + try + { + byte[] jsonBytes = null; + + // Read first 16 bytes header - last 2 bytes are json length + using ( BinaryReader reader = new BinaryReader( new FileStream( fullFilePath, FileMode.Open ) ) ) + { + FileInfo fileInfo = new FileInfo(fullFilePath); + long fileLength = fileInfo.Length; + + int magicNum = reader.ReadInt32(); // 67668767 + + // Debug.LogFormat( "magicNum: {0} Length {1} Name: {2}\nLastWriteTime: {3} | {4} LastAccessTime: {5} CreationTime: {6}", + // magicNum, dataLength, fullFilePath, fileInfo.LastWriteTime, fileInfo.LastWriteTimeUtc, fileInfo.LastAccessTime, fileInfo.CreationTime); + + if ( magicNum == 67668767 ) + { + reader.BaseStream.Seek( 14, 0 ); + ushort dataLength = reader.ReadUInt16(); + + if ( dataLength > 0 && dataLength + 16 < fileLength ) + jsonBytes = reader.ReadBytes( dataLength ); + else + Debug.LogErrorFormat( "CreatePackageInfoFromLocalStorage Error: Invalid Package\n{0}\nBad dataLength: {1}", fullFilePath, dataLength ); + } + else + { + Debug.LogErrorFormat( "CreatePackageInfoFromLocalStorage Error: Invalid Package\n{0}\nBad magicNum: {1}", fullFilePath, magicNum ); + } + } + + if ( null != jsonBytes ) + { + PackageInfo packageInfo = new PackageInfo + { + jsonInfo = Encoding.ASCII.GetString( jsonBytes, 0, jsonBytes.Length ), + packagePath = fullFilePath, + iconURL = null + }; + + sizeOnDisk = PopulateFromPackageInfo( packageInfo, results ); + } + } + catch ( IOException ex ) + { + Debug.LogErrorFormat( "CreatePackageInfoFromLocalStorage Error: Invalid Package\n{0}\nError: {1}", fullFilePath, ex.Message ); + } + + return sizeOnDisk; + } + + /// Central method to populate custom StorePackage from packageInfo + /// Returns on disk size of package. + public static long PopulateFromPackageInfo( PackageInfo packageInfo, List results ) + { + string fullFilePath = PathUtils.GetConsistentFilePath( packageInfo.packagePath ); + + AssetPackage pack; + FileInfo fileInfo = new FileInfo(fullFilePath); + // bool isUnityStandardAsset = IsBuiltinStandardAsset( fullFilePath ); + bool isUnityStandardAsset = fullFilePath.Contains("Editor/Standard Assets") || fullFilePath.Contains( @"Editor\Standard Assets"); + + if ( !string.IsNullOrEmpty( packageInfo.jsonInfo ) ) + pack = JsonUtility.FromJson( packageInfo.jsonInfo ); + else + { + // Catch Unity Standard Assets here + string publisherLabel = !isUnityStandardAsset ? "NA" : "Unity Technologies"; + string publisherID = !isUnityStandardAsset ? "NA" : "1"; + string categoryLabel = !isUnityStandardAsset ? "NA" : "Prefab Packages"; // "Builtin StandardAsset"; + string categoryID = !isUnityStandardAsset ? "NA" : "4"; + string title = !isUnityStandardAsset ? fileInfo.Name : "BuiltinStandardAsset." + Path.GetFileNameWithoutExtension(fileInfo.Name); + string version = !isUnityStandardAsset ? Application.unityVersion : "4.3.4"; // "3.5.0.0"; + + pack = BuildDefaultStorePackage( title, version, version, categoryLabel, categoryID, publisherLabel, publisherID ); + } + + pack.fullFilePath = fullFilePath; + pack.fileSize = fileInfo.Length; + pack.isUnityStandardAsset = isUnityStandardAsset; + pack.modifiedDate = fileInfo.LastWriteTime; + pack.publishDate = pack.pubdate == "NA" ? new DateTime() : DateTime.Parse(pack.pubdate); + + pack.displayModifiedDate = pack.modifiedDate.ToString("dd MMM yyyy"); //.ToString(@"MM\/dd\/yyyy HH:mm"); + pack.displayFileSize = Numerical.ByteCountToSuffixHumbads(pack.fileSize); + + + // Fix potential issues + if ( string.IsNullOrEmpty( pack.unity_version ) ) pack.unity_version = "NA"; // Prior to Unity 5.x this was empty + + // Replace & symbol as for popup menu's it is used for something else - keyboard shortcut maybe? + pack.category.label = pack.category.label.Replace("&", "and"); + + pack.baseCategory = pack.category.label.Split('/')[0]; + + /* + // Extract Icon: No Point every Icon is default Unity Icon! + if ( null != packageInfo.iconURL ) + { + byte[] iconBytes = System.Convert.FromBase64String(packageInfo.iconURL.Substring(22)); + System.IO.File.WriteAllBytes( Application.dataPath + "/testpng.png", iconBytes); + uasp.iconTexture = new Texture2D( 2, 2, TextureFormat.RGB24, false ); + uasp.iconTexture.LoadImage(iconBytes); + } + */ + + results.Add( pack ); + + return pack.fileSize; + } + + private static AssetPackage BuildDefaultStorePackage( string title, string unityVersion, string version, string category, string categoryID, string publisher, string publisherID ) + { + AssetPackage uasp = new AssetPackage(); + uasp.link = new StorePackageLink(); + uasp.category = new StorePackageLabelWithID(); + uasp.publisher = new StorePackageLabelWithID(); + + uasp.unity_version = unityVersion; + uasp.pubdate = "NA"; + uasp.version = version; + uasp.upload_id = -1; + uasp.version_id = -1; + uasp.id = -1; + uasp.title = title; + + uasp.link.id = "NA"; + uasp.link.type = "NA"; + uasp.category.id = categoryID; + uasp.category.label = category; + uasp.publisher.id = publisherID; + uasp.publisher.label = publisher; + + uasp.description ="NA"; + uasp.baseCategory = uasp.category.label.Split('/')[0]; + return uasp; + } + + #region HELPERS + // Note: + // see Editor\Mono\AssetStore\AssetStoreContext.cs + // This no longer works correctly in Unity 5.4 as standard asset package names have changed! + // Seems its stuck with Unity 3.5 version standard assets. + // Unsure if this is broken or by design. + private static bool IsBuiltinStandardAsset(string path) + { + return s_StandardPackage52RegExp.IsMatch(path); + } + + // public static bool IsPackageInProject() { } + + public static bool GetAllAssetBundleNames() + { + string[] assetBundles = AssetDatabase.GetAllAssetBundleNames(); + + Debug.LogFormat("assetBundles Count: {0}\n", assetBundles.Length ); + + foreach ( string s in assetBundles ) + Debug.LogFormat("{0}\n", s); + + return false; + } + #endregion + } +} diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/AssetPackage.cs.meta b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/AssetPackage.cs.meta new file mode 100644 index 0000000..2195bb0 --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/AssetPackage.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4b6f407a6b5cc894898c64de59cab0f9 +timeCreated: 1505924053 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerArchiver.cs b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerArchiver.cs new file mode 100644 index 0000000..37ee439 --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerArchiver.cs @@ -0,0 +1,288 @@ +#define ENABLE_ARCHIVE_LOGS + +using System.Collections.Generic; +using System.IO; +using NoiseCrimeStudios.Core; +using NoiseCrimeStudios.Core.IO; +using UnityEditor; +using UnityEngine; + +namespace NoiseCrimeStudios.Toolbox.AssetStoreOrganizer +{ + /// Collection of Methods for archive, copy and restore packages between locations. + /// + /// Due to file path limits in Windows its suggest to prepend only the version number to an asset. + /// However some packages are updated but the version stays the same, so in some case we must add versionID. + /// + public static class OrganizerArchiver + { + private static StringBuilderDebugLog debugLogOutput = new StringBuilderDebugLog(); + + private static readonly string kOverwriteFile = "{0}\nAlready exists in the AssetStore Directory.\nDo you want to overwrite the original file with\n{1}"; + private static readonly string kRestoreMessageFormat = "Are you sure you want to restore the package\n{0}\n({1})\nto\n{2}"; + + /// + /// Archive packages to supplied PackageLibrary. + /// + /// List of packages to archive to archiveLib. + /// PackageLibrary representing the archive library used to compare against. + /// Source Package location to archive from. + /// If FALSE will not perform file operations allowing non-destructive testing. + public static void ArchiveAssetStorePackages( List packages, PackageLibrary archiveLib, PackagesLocation sourceLocation, bool enableFileOperations = true ) + { + if ( PackagesLocation.Archive == sourceLocation ) + { + Debug.LogWarningFormat( "ArchiveMethods: Cannot archive packages from the archived directory." ); + return; + } + + if ( !DirectoryUtils.IsValidPathToDirectory( OrganizerPaths.StoreDirectoryBackup ) ) + { + Debug.LogWarningFormat( "ArchiveMethods: The operation could not be completed because ArchiveDirectory does not exist.\n{0}", OrganizerPaths.StoreDirectoryBackup ); + return; + } + + if ( OrganizerPaths.GetPackageDirectory( sourceLocation ) == OrganizerPaths.StoreDirectoryBackup ) + { + Debug.LogWarningFormat( "ArchiveMethods: The operation could not be completed because source location in the same as archive location.\n{0}", OrganizerPaths.StoreDirectoryBackup ); + return; + } + + debugLogOutput.Clear(); + debugLogOutput.IndentReset(16); + debugLogOutput.AppendLine( "-- ArchiveThePackagesInLibrary --" ); + + for( int i=0; i < packages.Count; i++) + { + EditorUtility.DisplayProgressBar( "Copy Packages to Archive", packages[i].title, i/(float)packages.Count ); + ArchiveAssetStorePackage( packages[i], archiveLib, sourceLocation, enableFileOperations, i); + debugLogOutput.InsertSoftBreak( 1536 ); + } + + EditorUtility.ClearProgressBar(); + + debugLogOutput.InsertHardBreak(); + debugLogOutput.AppendLine( "-- ArchiveThePackagesInLibrary --" ); + debugLogOutput.LogToConsole(true); + } + + private static void ArchiveAssetStorePackage( AssetPackage package, PackageLibrary archiveLib, PackagesLocation sourceLocation, bool enableFileOperations, int counter ) + { + if ( package.id == -1 ) // Ignore Legacy Builtin Unity StandardAssets. + { + debugLogOutput.AppendFormat( "[{0:D4}][{1:D8}] IGNORED\t\t{2} - Builtin StandardAsset [{3}]", counter, package.id, package.title, package.fullFilePath ); + return; + } + + AssetPackage matchedPackage; + + MatchState matchState = archiveLib.TryGetMatchedPackage( package, out matchedPackage ); + +#if ENABLE_ARCHIVE_LOGS + if ( matchState == MatchState.Exact ) + { + debugLogOutput.AppendFormat( "[{0:D4}][{1:D8}] EXISTS\t\t{2}", counter, package.id, package.title ); + debugLogOutput.IndentIncrement( 4 ); + debugLogOutput.AppendFormat( "{0} [package.fullFilePath]", package.fullFilePath ); + debugLogOutput.AppendFormat( "{0} [archivePack.fullFilePath]", matchedPackage.fullFilePath ); + debugLogOutput.IndentDecrement( 4 ); + debugLogOutput.AppendLine(); + } +#endif + // If partial or no match found then copy the package. + if ( matchState != MatchState.Exact ) + CopyPackage( package, sourceLocation, PackagesLocation.Archive, matchState, enableFileOperations, counter ); + } + + /// Copy File from storePackage location to archive location. + /// If we have a partial match then we need to copy the file but use versionID to distingush between them. + private static void CopyPackage( AssetPackage package, PackagesLocation srcLocation, PackagesLocation dstLocation, MatchState matchState, bool enableFileOperations, int counter ) + { + // Assumption that source and destination does not contain Unity\Asset Store-5.x\ or Unity\Asset Store\ + string srcPackageDirectory = PathUtils.GetConsistentFilePath( OrganizerPaths.GetPackageDirectory( srcLocation ) ); + string dstPackageDirectory = PathUtils.GetConsistentFilePath( OrganizerPaths.GetPackageDirectory( dstLocation ) ); + + // Remove 'Asset Store-5.x' or 'AssetStore' if final part of source directory path. + if ( srcLocation == PackagesLocation.AssetStore || srcLocation == PackagesLocation.AssetStore5x ) + srcPackageDirectory = Path.GetDirectoryName( srcPackageDirectory ); + + // TODO - FIX: If dstPackageDirectory is not root of 'Asset Store-5.x' or 'AssetStore' we have a problem + if ( !dstPackageDirectory.Contains( "Asset Store-5.x" ) && !dstPackageDirectory.Contains( "AssetStore" ) ) + { + Debug.LogWarningFormat( "ArchiveMethods: The operation could not be completed because destination is not 'AssetStore'.\n{0}", dstPackageDirectory ); + return; + } + + // Get the relative store package path + string relativeSrcPackagePath = package.fullFilePath.Replace( srcPackageDirectory + Path.DirectorySeparatorChar, "" ); + // Remove filename from realtive path + relativeSrcPackagePath = Path.GetDirectoryName( relativeSrcPackagePath ); + + // Build archive filename for package + string archiveFilename; + string storePackFileName = Path.GetFileName( package.fullFilePath ); + string storePackVersion = string.Format("[{0}]", package.version ); + string storePackVersionID = string.Format("[{0}]", package.version_id ); + + // Remove any existing tags - in case this comes from a custom previous archive/backup location! + if ( matchState == MatchState.Partial ) + { + storePackFileName = storePackFileName.Replace( storePackVersion, "" ); + storePackFileName = storePackFileName.Replace( storePackVersionID, "" ); + archiveFilename = storePackVersion + storePackVersionID + storePackFileName; + } + else + { + storePackFileName = storePackFileName.Replace( storePackVersion, "" ); + archiveFilename = storePackVersion + storePackFileName; + } + + string archiveDirectoryPath = dstPackageDirectory + Path.DirectorySeparatorChar + relativeSrcPackagePath; + string archiveFilePath = archiveDirectoryPath + Path.DirectorySeparatorChar + archiveFilename; + +#if ENABLE_ARCHIVE_LOGS + string copyText = enableFileOperations ? "COPIED\t" : "COPY DISABLED"; + debugLogOutput.AppendFormat( "[{0:D4}][{1:D8}] {2}\t{3} (PartialMatch = {4})", counter, package.id, copyText, package.title, matchState ); + debugLogOutput.IndentIncrement(4); + debugLogOutput.AppendFormat( "{0} [package.fullFilePath]", package.fullFilePath ); + debugLogOutput.AppendFormat( "{0} [archiveFilePath]", archiveFilePath ); + debugLogOutput.AppendFormat( "{0} [archivePackageDirectory]", dstPackageDirectory ); + debugLogOutput.AppendFormat( "{0} [storePackageDirectory]", srcPackageDirectory ); + debugLogOutput.AppendFormat( "{0} [relativeStorePackagePath]", relativeSrcPackagePath ); + debugLogOutput.AppendFormat( "{0} [archiveFilename]", archiveFilename ); + debugLogOutput.IndentDecrement(4); + debugLogOutput.AppendLine(); +#endif + + if ( enableFileOperations ) + CopyFile( package.fullFilePath, archiveFilePath, archiveDirectoryPath, false ); + } + + + private static void CopyFile( string sourceFilePath, string targetFilePath, string targetDirectoryPath, bool overwrite ) + { + if ( !File.Exists( sourceFilePath ) ) + { + Debug.LogWarningFormat( "ArchiveMethods: The operation could not be completed because the file doesn't exist.\n{0}", sourceFilePath ); + return; + } + + if ( File.Exists( targetFilePath ) ) + { + Debug.LogWarningFormat( "ArchiveMethods: The operation could not be completed because the file already exists.\n{0}\n{1}", sourceFilePath, targetFilePath ); + return; + } + + if ( !Directory.Exists( targetDirectoryPath ) ) + Directory.CreateDirectory( targetDirectoryPath ); + + FileInfo sourceFileInfo = new FileInfo( sourceFilePath ); + + try + { + sourceFileInfo.CopyTo( targetFilePath, false ); + } + catch ( System.Exception ex ) + { + Debug.LogErrorFormat( "Copy Failed: {0}", ex.Message ); + } + } + + public static bool RestoreArchivePackageToAssetStore( AssetPackage package, PackagesLocation sourcelocation, bool enableFileOperations ) + { + if ( sourcelocation != PackagesLocation.Custom && sourcelocation != PackagesLocation.Archive ) + { + Debug.LogWarningFormat("ArchiveMethods: Invalid Source location, can only copy packages from Custom or Archive locations to AssetStore!"); + return false; + } + + // Cache Tags + string storePackVersion = string.Format("[{0}]", package.version ); + string storePackVersionID = string.Format("[{0}]", package.version_id ); + + string locationDirectory = PathUtils.GetConsistentFilePath( OrganizerPaths.GetPackageDirectory( sourcelocation )); + string packageFilePath = package.fullFilePath; + // Get Relative path + string relativeFilePath = packageFilePath.Replace( locationDirectory, "" ); // this will leave initial directory seperator! + string relativeFileName = Path.GetFileNameWithoutExtension( packageFilePath ); + // Strip any tags we added + relativeFilePath = relativeFilePath.Replace( storePackVersion, "" ); + relativeFilePath = relativeFilePath.Replace( storePackVersionID, "" ); + + string assetStoreRoot = PathUtils.GetConsistentFilePath( OrganizerPaths.StoreDirectoryRoot ); + string destinationFilePath = assetStoreRoot + relativeFilePath; + string destinationDirectory = Path.GetDirectoryName( destinationFilePath ); + + // Check for overwrite! + bool overwrite = true; + bool comfirmed = true; + + if ( File.Exists( destinationFilePath ) ) + { + string message = string.Format( kOverwriteFile, package.title, relativeFileName ); + overwrite = ( EditorUtility.DisplayDialog( "Restore Package To Asset Store", message, "OK", "Cancel" ) ); + } + else + { + string message = string.Format( kRestoreMessageFormat, package.title, relativeFileName, OrganizerPaths.StoreDirectoryBackup ); + comfirmed = ( EditorUtility.DisplayDialog( "Restore Package To Asset Store", message, "OK", "Cancel" ) ); + } + + bool restoreFile = ( enableFileOperations && comfirmed && overwrite ); + +#if ENABLE_ARCHIVE_LOGS + StringBuilderDebugLog debugLogOutput = new StringBuilderDebugLog(); + debugLogOutput.AppendFormat( "[locationPath]\t {0}", locationDirectory ); + debugLogOutput.AppendFormat( "[packagePath]\t {0}", packageFilePath ); + debugLogOutput.AppendFormat( "[relativeFilePath]\t {0}", relativeFilePath ); + debugLogOutput.AppendFormat( "[assetStoreRoot]\t {0}", assetStoreRoot ); + debugLogOutput.AppendFormat( "[fullDestinationPath]\t {0}", destinationFilePath ); + debugLogOutput.AppendFormat( "[destinationDirectory]\t {0}", destinationDirectory ); + debugLogOutput.AppendFormat( "[File Restored]\t {0} [Overwrite: {1}, Confirmed: {2} enableFileOperations: {3}]", restoreFile, overwrite, comfirmed, enableFileOperations ); + debugLogOutput.LogToConsole(); +#endif + + if ( restoreFile ) + CopyFile( packageFilePath, destinationFilePath, destinationDirectory, overwrite ); + + return restoreFile; + } + + /// Log to console the archived status of the storePackage. + public static void LogPackageArchiveStatus( AssetPackage package, PackageLibrary library ) + { + StringBuilderDebugLog output = new StringBuilderDebugLog(); + + if ( library.packageIDTable.ContainsKey( package.id ) ) + { + output.AppendFormat( "Store:\t{0}\t{1}\t{2}\t{3}\t{4}\t{5}", + package.unity_version, package.version, package.version_id, package.pubdate, package.title, package.fullFilePath ); + output.AppendLine(); + + foreach ( AssetPackage archivePack in library.packageIDTable[ package.id ] ) + { + bool matchName = package.title == archivePack.title; + bool matchUnityVersion = package.unity_version == archivePack.unity_version; + bool matchVersion = package.version == archivePack.version; + bool matchVersionID = package.version_id == archivePack.version_id; + bool matchPubDate = package.pubdate == archivePack.pubdate; + bool matched = matchName && matchUnityVersion && matchVersion && matchVersionID && matchPubDate; + + output.AppendFormat( "Archive:\t{0}\t{1}\t{2}\t{3}\t{4}\t{5}", + archivePack.unity_version, archivePack.version, archivePack.version_id, archivePack.pubdate, archivePack.title, archivePack.fullFilePath ); + output.AppendFormat( "Archive:\t{0}\t{1}\t{2}\t{3}\t\t{4}", + matchUnityVersion, matchVersion, matchVersionID, matchPubDate, matchName ); + + if (matched) output.AppendLine( "Package Archive Matched!" ); + output.AppendLine(); + } + } + else + { + output.AppendFormat("Package Archive Status: Not Archived {0} [{1}]", package.title, package.id ); + } + + output.LogToConsole( true ); + } + } +} diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerArchiver.cs.meta b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerArchiver.cs.meta new file mode 100644 index 0000000..8023812 --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerArchiver.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ad84a08f43b6d894f897a9d3046f4a20 +timeCreated: 1593598406 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerEditor.cs b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerEditor.cs new file mode 100644 index 0000000..71e3170 --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerEditor.cs @@ -0,0 +1,544 @@ +// #define LOG_UNITY_METHODS + +using System; +using System.Collections.Generic; +using System.IO; +using NoiseCrimeStudios.Core.Formatting; +using NoiseCrimeStudios.Editor; +using NoiseCrimeStudios.Editor.IMGUI; +using UnityEditor; +using UnityEditorInternal; +using UnityEngine; + +namespace NoiseCrimeStudios.Toolbox.AssetStoreOrganizer +{ + // Add option to 'Assets' menu + public class AssetsMenu_OpenStoreOrganizerEditor + { + [MenuItem( "Assets/Open Asset Store Organizer", false, ( int )AssetMenuItemPriority.Packages )] + public static void OpenStoreOrganizerEditor() + { + EditorWindow.GetWindow( "Store Organizer" ); + } + } + + // Main Editor Window for Organizer + public class OrganizerEditor : EditorWindow + { + private PackageLibrary sourceLibrary = new PackageLibrary(); + private PackageLibrary archiveLibrary = new PackageLibrary(); + private PackageFilters packageFilters = new PackageFilters(); + private List sortedLibrary = new List(); + + private PackagesLocation sourceLocation = PackagesLocation.NativePackageList; + + private PackageFilters.Category activeColumn = PackageFilters.Category.Title; + private string packageInfoCount; + private readonly string[] locationNameArray = Enum.GetNames( typeof( PackagesLocation ) ); + + // GUI + private Vector2 scrollPosition; + private Rect optionsButtonRect; + private static float[] columnWidths = new float[]{280f, 72f, 64f, 64f, 88f, 88f, 256f, 224f, 64f}; + private static float lineHeight = 24f; + private readonly string materialIconPath = "Assets/NoiseCrimeStudios/Editor/Resources/GoogleMaterialIcons"; + + private readonly string urlPublisherQuery = @"https://assetstore.unity.com/?publisher="; + private readonly string urlCategoryQuery = @"https://assetstore.unity.com/?category="; + private readonly string urlAssetTitleQuery = @"https://assetstore.unity.com/packages/vfx/{0}/{1}-{2}"; + + // e.g. https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/amplify-color-1894 + + // Old Site URL's - No longer work + // private readonly string urlPublisherQuery = @"https://www.assetstore.unity3d.com/en/#!/search/page=1/sortby=popularity/query=publisher:"; + // private readonly string urlCategoryQuery = @"https://www.assetstore.unity3d.com/en/#!/search/page=1/sortby=popularity/query=category:"; + // private readonly string urlAssetTitleQuery = @"https://www.assetstore.unity3d.com/en/#!/content/"; + + private static Texture iconImport; + private static GUIContent iconImportContent; + private static Texture iconCancel; + private static GUIContent iconCancelContent; + private static Texture iconCheck; + private static GUIContent iconCheckContent; + private static GUIContent reloadContent; + + private static GUIStyle toolbarLabel; + private static GUIStyle iconLabelStyle; + + private bool requiresBrowserUpdate = false; + private bool requiresFilterUpdate = false; + + [SerializeField] + public bool disableFileOperations = false; + + // Shortcut = [Alt + F1] + [MenuItem( "Window/NoiseCrimeStudios/Asset Store Organizer &1", false, ( int )WindowMenuItemPriorty.Windows )] + private static void InitWindow() + { + GetWindow( "Store Organizer" ); + } + + // Constructor + public OrganizerEditor() + { +#if LOG_UNITY_METHODS + Debug.Log( "StorePackageLibraryEditor: Constructor" ); +#endif + } + + void OnEnable() + { +#if LOG_UNITY_METHODS + Debug.Log( "StorePackageLibraryEditor: OnEnable" ); +#endif + activeColumn = PackageFilters.Category.Title; + packageFilters.OrderByAscending = true; + requiresBrowserUpdate = false; + requiresFilterUpdate = false; + + UpdateLibraries(); + } + + void OnDisable() + { +#if LOG_UNITY_METHODS + Debug.Log( "StorePackageLibraryEditor: OnDisable" ); +#endif + } + + private void OnDestroy() + { +#if LOG_UNITY_METHODS + Debug.Log( "StorePackageLibraryEditor: OnDestroy" ); +#endif + } + + private void UpdateLibraries() + { +#if LOG_UNITY_METHODS + Debug.Log( "StorePackageLibraryEditor: InitialiseBrowser" ); +#endif + // Reset Flag + requiresBrowserUpdate = false; + + // Populate Package Library Content + sourceLibrary.PopulateLibraryContent( sourceLocation ); + // Populate Package Archive Content + archiveLibrary.PopulateLibraryContent( PackagesLocation.Archive ); + // Check Against Backups + sourceLibrary.CompareAgainstArchive( archiveLibrary ); + + // TODO + // These filters only apply to sourceLibrary not archiveLibrary!! + // How can we keep filters if reloading libraries? + + // Precompile filters + packageFilters.ConstructFilters( sourceLibrary.packageLibrary ); + // Apply Sorting + UpdateFilterSortResults(); + } + + private void UpdateFilterSortResults() + { +#if LOG_UNITY_METHODS + Debug.Log( "StorePackageLibraryEditor: UpdateFilterSortResults" ); +#endif + // Reset Flag + requiresFilterUpdate = false; + + // Get Sort & Filtered Result + sortedLibrary = packageFilters.SortAndFilterResults( sourceLibrary.packageLibrary, activeColumn ); + + long sortedSizeOnDisk = 0; + foreach( AssetPackage p in sortedLibrary ) + sortedSizeOnDisk += p.fileSize; + + packageInfoCount = string.Format( "Size: {0} of {1} Packages: {2} of {3}", Numerical.ByteCountToSuffixHumbads( sortedSizeOnDisk ), sourceLibrary.SizeOnDisk, sortedLibrary.Count, sourceLibrary.FileCount ); + } + + /// Archives the source location packages based on curent sorting and filtering results + public void StartArchiveSourceLibraryProcess() + { + OrganizerArchiver.ArchiveAssetStorePackages( sortedLibrary, archiveLibrary, sourceLocation, !disableFileOperations ); + requiresBrowserUpdate = true; + } + + #region GUI METHODS + void SetUpStyles() + { + reloadContent = EditorGUIUtility.IconContent("d_Refresh"); // d_Refresh or d_RotateTool + + EditorGUIStyles.CreateIconContent( ref iconImport, ref iconImportContent, materialIconPath, "{0}/ic_file_download_{1}_18dp_1x.png", "Import Package" ); + EditorGUIStyles.CreateIconContent( ref iconCancel, ref iconCancelContent, materialIconPath, "{0}/baseline_cancel_{1}_18dp_1x.png", "Not In Archive" ); + EditorGUIStyles.CreateIconContent( ref iconCheck, ref iconCheckContent, materialIconPath, "{0}/baseline_check_circle_{1}_18dp_1x.png", "In Archive" ); + + if ( null == toolbarLabel ) + { + toolbarLabel = new GUIStyle( EditorStyles.toolbar ); + toolbarLabel.alignment = TextAnchor.MiddleLeft; + } + + if ( null == iconLabelStyle ) + { + iconLabelStyle = new GUIStyle( "Label" ); + iconLabelStyle.padding = new RectOffset( 2, 2, 2, 2); + iconLabelStyle.alignment = TextAnchor.MiddleCenter; + } + } + + protected virtual void OnGUI() + { + SetUpStyles(); + + if ( requiresBrowserUpdate ) UpdateLibraries(); + if ( requiresFilterUpdate ) UpdateFilterSortResults(); + + float prevLabelWidth = EditorGUIUtility.labelWidth; + requiresBrowserUpdate = false; + requiresFilterUpdate = false; + + GuiPackageTopBar(); + GUILayout.Space(8f); + GuiBrowserBlock(); + + EditorGUIUtility.labelWidth = prevLabelWidth; + } + + + void GuiPackageTopBar() + { + EditorGUIUtility.labelWidth = 64f; + + // Top Line + using ( new EditorGUILayout.HorizontalScope( EditorStyles.toolbar ) ) + { + if ( GUILayout.Button( reloadContent, EditorStyles.toolbarButton, GUILayout.Width( 32f )) ) + requiresBrowserUpdate = true; + + // Show Package Location Popup + GUI.changed = false; + sourceLocation = ( PackagesLocation )EditorGUILayout.Popup( ( int )sourceLocation, locationNameArray, EditorStyles.toolbarPopup, GUILayout.MinWidth( 256f - 40f) ); + requiresBrowserUpdate = GUI.changed; + + float locationWidth = 552f - 4f; + + GUILayout.Space(8f); + + switch ( sourceLocation ) + { + case PackagesLocation.NativePackageList: + GUILayout.Label( OrganizerPaths.StoreDirectoryRoot, toolbarLabel, GUILayout.Width( locationWidth ) ); + break; + case PackagesLocation.AssetStore: + GUILayout.Label( OrganizerPaths.StoreDirectoryLegacy, toolbarLabel, GUILayout.Width( locationWidth ) ); + break; + case PackagesLocation.AssetStore5x: + GUILayout.Label( OrganizerPaths.StoreDirectoryModern, toolbarLabel, GUILayout.Width( locationWidth ) ); + break; + case PackagesLocation.Custom: + GuiPackageLocationButton( PackagesLocation.Custom, "Browse for custom asset store folder", locationWidth ); + break; + case PackagesLocation.Archive: + GuiPackageLocationButton( PackagesLocation.Archive, "Browse for archive asset store folder", locationWidth ); + break; + } + + GUILayout.FlexibleSpace(); + + if ( GUILayout.Button( "Archive Options", EditorGUIStyles.labelNormRight, GUILayout.MinWidth( 256f ), GUILayout.MaxWidth( 256f ) ) ) + PopupWindow.Show( optionsButtonRect, new OrganizerOptionsPopup( this ) ); + + if ( Event.current.type == EventType.Repaint ) optionsButtonRect = GUILayoutUtility.GetLastRect(); + } + + // Second Line + using ( new EditorGUILayout.HorizontalScope( EditorStyles.toolbar ) ) + { + GUI.changed = false; + packageFilters.GuiSearchBar(); + requiresFilterUpdate = GUI.changed; + GUILayout.FlexibleSpace(); + EditorGUILayout.LabelField( packageInfoCount, EditorGUIStyles.labelNormRight, GUILayout.MinWidth( 320f ), GUILayout.MaxWidth( 320f ) ); + } + } + + void GuiPackageLocationButton( PackagesLocation location, string title, float width ) + { + string directory = OrganizerPaths.GetPackageDirectory(location); + + if ( !string.IsNullOrEmpty( directory ) && !Directory.Exists( directory ) ) + directory = string.Empty; + + if ( GUILayout.Button( string.IsNullOrEmpty( directory ) ? "Browse..." : directory, EditorStyles.toolbarPopup, GUILayout.Width( width ) ) ) + { + string path = EditorUtility.OpenFolderPanel( title, directory, "Package Folder"); + + if ( path.Length > 0 && Directory.Exists( path ) ) + { + OrganizerPaths.SetPackageDirectory( location, path ); + requiresBrowserUpdate = true; + } + } + } + + void GuiBrowserBlock() + { + // Row - Column Names + using ( new EditorGUILayout.HorizontalScope() ) + { + GUILayout.Space( 48f ); + GuiColumnHeaderButton( "Package Name", PackageFilters.Category.Title, EditorGUIStyles.labelNormLeft, EditorGUIStyles.labelBoldLeft, columnWidths[ 0 ] ); + GuiColumnHeaderButton( "Archived", PackageFilters.Category.Archived, EditorGUIStyles.labelNormLeft, EditorGUIStyles.labelBoldLeft, columnWidths[ 8 ] ); + GuiColumnHeaderButton( "Version", PackageFilters.Category.Version, EditorGUIStyles.labelNormLeft, EditorGUIStyles.labelBoldLeft, columnWidths[ 3 ] ); + GuiColumnHeaderButton( "Unity", PackageFilters.Category.UnityVersion, EditorGUIStyles.labelNormLeft, EditorGUIStyles.labelBoldLeft, columnWidths[ 1 ] ); + GuiColumnHeaderButton( "Size", PackageFilters.Category.Size, EditorGUIStyles.labelNormRight, EditorGUIStyles.labelBoldRight, columnWidths[ 2 ] ); + GuiColumnHeaderButton( "Downloaded", PackageFilters.Category.ModDate, EditorGUIStyles.labelNormRight, EditorGUIStyles.labelBoldRight, columnWidths[ 4 ] ); + GuiColumnHeaderButton( "Published", PackageFilters.Category.PubDate, EditorGUIStyles.labelNormRight, EditorGUIStyles.labelBoldRight, columnWidths[ 5 ] ); + GuiColumnHeaderButton( "Category", PackageFilters.Category.Category, EditorGUIStyles.labelNormLeft, EditorGUIStyles.labelBoldLeft, columnWidths[ 6 ] ); + GuiColumnHeaderButton( "Publisher", PackageFilters.Category.Publisher, EditorGUIStyles.labelNormLeft, EditorGUIStyles.labelBoldLeft, columnWidths[ 7 ] ); + } + + // Results Scroll View + scrollPosition = EditorGUILayout.BeginScrollView( scrollPosition ); + bool lightStyle = true; + + foreach ( AssetPackage uasp in sortedLibrary ) + { + GuiStorePackageItem( uasp, lightStyle ? EditorGUIStyles.scopeLight : EditorGUIStyles.scopeDark ); + lightStyle = !lightStyle; + } + + EditorGUILayout.Space(); + EditorGUILayout.EndScrollView(); + } + + private void GuiStorePackageItem( AssetPackage ap, GUIStyle scope ) + { + GUI.contentColor = ap.isUnityStandardAsset ? EditorGUIStyles.colorContentWarning : EditorGUIStyles.colorContentNormal; + + using ( new EditorGUILayout.HorizontalScope( scope, GUILayout.Height( lineHeight ) ) ) + { + if ( GUILayout.Button( iconImportContent, EditorGUIStyles.fullButton, GUILayout.Height( lineHeight ), GUILayout.Width( 32f ) ) ) + OrganizerMethods.ImportPackage( ap.fullFilePath ); + + GUILayout.Space( 4f ); + + // Column Entries + GuiCustomMenu ( ap, EditorGUIStyles.labelNormLeft, columnWidths[ 0 ] ); + GUI.contentColor = ap.isArchived ? EditorGUIStyles.colorContentGreen : EditorGUIStyles.colorContentNormal; + EditorGUILayout.LabelField( ap.isArchived ? iconCheckContent : iconCancelContent, iconLabelStyle, GUILayout.Height( lineHeight ), GUILayout.Width( columnWidths[ 8 ] ) ); + GUILayout.Space( 12f ); + GUI.contentColor = ap.isUnityStandardAsset ? EditorGUIStyles.colorContentWarning : EditorGUIStyles.colorContentNormal; + GuiCustomLabel( ap.version, EditorGUIStyles.labelNormLeft, columnWidths[ 3 ] ); + GuiCustomLabel( ap.unity_version, EditorGUIStyles.labelNormLeft, columnWidths[ 1 ] ); + GuiCustomLabel( ap.displayFileSize, EditorGUIStyles.labelNormRight, columnWidths[ 2 ] ); + GuiCustomLabel( ap.displayModifiedDate, EditorGUIStyles.labelNormRight, columnWidths[ 4 ] ); + GuiCustomLabel( ap.pubdate, EditorGUIStyles.labelNormRight, columnWidths[ 5 ] ); + GuiCustomLabel( ap.category.label, EditorGUIStyles.labelNormLeft, columnWidths[ 6 ] ); + GuiCustomLabel( ap.publisher.label, EditorGUIStyles.labelNormLeft, columnWidths[ 7 ] ); + // GuiCustomLabel( uasp.category.label, urlCategoryQuery, uasp.category.id, styleLeft, columnWidths[6] ); // Obsolete - doesn't work with new website + // GuiCustomLabel( uasp.publisher.label, urlPublisherQuery, uasp.publisher.label, styleLeft, columnWidths[ 7 ] ); + } + + GUI.contentColor = EditorGUIStyles.colorContentNormal; + } +#endregion + + + private void GuiColumnHeaderButton( string name, PackageFilters.Category column, GUIStyle normalStyle, GUIStyle boldStyle, float width ) + { + GUIStyle style = activeColumn == column ? boldStyle : normalStyle; + bool clicked = GUILayout.Button( name, style, GUILayout.MinWidth( width ), GUILayout.MaxWidth( width ) ); + GUILayout.Space( 12f ); + + if ( clicked ) + { + // Toggle sorting order direction if previous column is clicked again. + if ( activeColumn == column ) packageFilters.OrderByAscending = !packageFilters.OrderByAscending; + + activeColumn = column; + requiresFilterUpdate = true; + } + } + + private void GuiCustomLabel( string labelText, GUIStyle style, float width ) + { + EditorGUILayout.LabelField( labelText, style, GUILayout.Height( lineHeight ), GUILayout.MinWidth( width ), GUILayout.MaxWidth( width ) ); + GUILayout.Space( 12f ); + } + + private void GuiCustomLabel( string labelText, string url, string id, GUIStyle style, float width ) + { + if ( GUILayout.Button( labelText, style, GUILayout.Height( lineHeight ), GUILayout.MinWidth( width ), GUILayout.MaxWidth( width ) ) && id != "NA" ) + { + if ( Event.current.button == 0 ) + Application.OpenURL( url + id ); + else + AssetStore.Open( string.Format( "content/{0}", id ) ); + } + GUILayout.Space( 12f ); + } + + +#region CUSTOM POPUP MENU + private void GuiCustomMenu( AssetPackage ap, GUIStyle style, float width) + { + if ( GUILayout.Button( ap.title, style, GUILayout.Height( lineHeight ), GUILayout.MinWidth( width ), GUILayout.MaxWidth( width ) ) ) + { + bool hasLinkID = (ap.link.id != "NA"); + bool hasPublisherID = (ap.publisher.id != "NA"); + bool hasCategoryID = (ap.category.id != "NA"); + + GenericMenu menu = new GenericMenu(); + menu.AddItem( new GUIContent( "Import Package" ), false, OnMenuImportPackage, ap ); + menu.AddItem( new GUIContent( "Embed Package" ), false, OnMenuEmbedPackage, ap ); + MenuItemDeletePackage( menu, ap ); + MenuItemCopyPackage( menu, ap); + menu.AddSeparator( "" ); + menu.AddItem( new GUIContent( "Show In Explorer" ), false, OnMenuShowInExplorer, ap ); + menu.AddItem( new GUIContent( "Log Package Information" ), false, OnMenuLogPackageInfo, ap ); + menu.AddItem( new GUIContent( "Log Archive Status" ), false, OnMenuLogArchiveStatus, ap ); + menu.AddSeparator( "" ); + + if ( hasLinkID || hasPublisherID || hasCategoryID ) + { + if ( hasLinkID ) menu.AddItem( new GUIContent( "Show Internet Browser/View Asset" ), false, OnMenuAssetPage, ap ); + if ( hasPublisherID ) menu.AddItem( new GUIContent( "Show Internet Browser/View Publisher" ), false, OnMenuPublisherPage, ap ); + if ( hasCategoryID ) menu.AddItem( new GUIContent( "Show Internet Browser/View Category" ), false, OnMenuCategoryPage, ap ); + + if ( hasLinkID ) menu.AddItem( new GUIContent( "Show AssetStore Tab/View Asset" ), false, OnMenuAssetWindow, ap ); + if ( hasPublisherID ) menu.AddItem( new GUIContent( "Show AssetStore Tab/View Publisher" ), false, OnMenuPublisherWindow, ap ); + if ( hasCategoryID ) menu.AddItem( new GUIContent( "Show AssetStore Tab/View Category" ), false, OnMenuCategoryWindow, ap ); + } + + menu.ShowAsContext(); + } + + GUILayout.Space( 12f ); + } + + /// Location dependant MenuItem for coping to/from either AssetStore or Archive based on location being shown. + private void MenuItemCopyPackage( GenericMenu menu, AssetPackage sp ) + { + switch ( sourceLocation ) + { + case PackagesLocation.NativePackageList: + case PackagesLocation.AssetStore: + case PackagesLocation.AssetStore5x: + menu.AddItem( new GUIContent( "Archive Package" ), false, OnMenuArchivePackage, sp); + break; + case PackagesLocation.Custom: + case PackagesLocation.Archive: + menu.AddItem( new GUIContent( "Restore Package To Asset Store" ), false, OnMenuRestorePackage, sp); + break; + default: + menu.AddDisabledItem( new GUIContent("Unknown Package Location") ); + break; + } + } + + /// Location dependant MenuItem for deleting the package from current location. + private void MenuItemDeletePackage( GenericMenu menu, AssetPackage sp ) + { + switch ( sourceLocation ) + { + case PackagesLocation.NativePackageList: + case PackagesLocation.AssetStore: + case PackagesLocation.AssetStore5x: + menu.AddItem( new GUIContent( "Delete from Asset Store Cache" ), false, OnMenuDeletePackage, sp ); + break; + case PackagesLocation.Custom: + menu.AddItem( new GUIContent( "Delete from Custom Cache Location" ), false, OnMenuDeletePackage, sp ); + break; + case PackagesLocation.Archive: + menu.AddItem( new GUIContent( "Delete from Archived Location" ), false, OnMenuDeletePackage, sp ); + break; + default: + menu.AddDisabledItem( new GUIContent("Unknown Package Location") ); + break; + } + } + + + private static readonly string deletionMessageFormat = "Are you sure you want to delete the package\n{0}\nfrom\n{1}"; + private static readonly string kArchiveMessageFormat = "Are you sure you want to archive the package\n{0}\nto\n{1}"; + + + private string GetDeletionMessage( string title ) + { + switch ( sourceLocation ) + { + case PackagesLocation.NativePackageList: + case PackagesLocation.AssetStore: + case PackagesLocation.AssetStore5x: + return string.Format( deletionMessageFormat, title, "Asset Store Cache" ); + case PackagesLocation.Custom: + return string.Format( deletionMessageFormat, title, "Custom Cache Location" ); + case PackagesLocation.Archive: + return string.Format( deletionMessageFormat, title, "Archived Location" ); + } + + return "Unkown"; + } + + + void OnMenuImportPackage( object sp ) + { + AssetPackage pack = ( AssetPackage )sp; + OrganizerMethods.ImportPackage( pack.fullFilePath ); + Debug.LogFormat("StorePackageLibraryEditor: Imported Package - [{0}] {1}", pack.version, pack.fullFilePath); + } + + void OnMenuEmbedPackage( object sp ) + { + AssetPackage pack = ( AssetPackage )sp; + OrganizerMethods.EmbedPackage( pack.fullFilePath ); + Debug.LogFormat("StorePackageLibraryEditor: Embed Package - [{0}] {1}", pack.version, pack.fullFilePath); + } + + void OnMenuDeletePackage( object sp ) + { + AssetPackage package = ( AssetPackage )sp; + + string message = GetDeletionMessage( package.title ); + + if ( EditorUtility.DisplayDialog( "Delete Selected Package", message, "OK", "Cancel" ) ) + { + File.Delete( package.fullFilePath ); + requiresBrowserUpdate = true; + } + } + + void OnMenuArchivePackage( object sp ) + { + AssetPackage package = ( AssetPackage )sp; + + string message = string.Format( kArchiveMessageFormat, package.title, OrganizerPaths.StoreDirectoryBackup ); + + if ( EditorUtility.DisplayDialog( "Archive Selected Package", message, "OK", "Cancel" ) ) + { + OrganizerArchiver.ArchiveAssetStorePackages( new List() { package }, archiveLibrary, sourceLocation, !disableFileOperations ); + requiresBrowserUpdate = true; + } + } + + void OnMenuRestorePackage( object sp ) + { + AssetPackage package = ( AssetPackage )sp; + requiresBrowserUpdate = OrganizerArchiver.RestoreArchivePackageToAssetStore( package, sourceLocation, !disableFileOperations ); + } + + void OnMenuShowInExplorer( object sp ) { OrganizerMethods.OpenPackageInExplorer( ( ( AssetPackage )sp ).fullFilePath ); } + void OnMenuLogPackageInfo( object sp ) { Debug.Log( ( ( AssetPackage )sp ).ToString() ); } + void OnMenuLogArchiveStatus( object sp ) { OrganizerArchiver.LogPackageArchiveStatus( ( AssetPackage )sp, archiveLibrary ); } + + void OnMenuAssetPage( object sp ) { Application.OpenURL( urlAssetTitleQuery + ( ( AssetPackage )sp ).link.id ); } + void OnMenuPublisherPage( object sp ) { Application.OpenURL( urlPublisherQuery + ( ( AssetPackage )sp ).publisher.label ); } //.id); } + void OnMenuCategoryPage( object sp ) { Application.OpenURL( urlCategoryQuery + ( ( AssetPackage )sp ).category.id ); } + + void OnMenuAssetWindow( object sp ) { AssetStore.Open( string.Format( "content/{0}", ( ( AssetPackage )sp ).link.id ) ); } + void OnMenuPublisherWindow( object sp ) { AssetStore.Open( string.Format( "content/{0}", ( ( AssetPackage )sp ).publisher.id ) ); } + void OnMenuCategoryWindow( object sp ) { AssetStore.Open( string.Format( "content/{0}", ( ( AssetPackage )sp ).category.id ) ); } +#endregion + } +} diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerEditor.cs.meta b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerEditor.cs.meta new file mode 100644 index 0000000..356fc02 --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 10baea619e0e221408d355b26dac79db +timeCreated: 1560441875 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerMethods.cs b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerMethods.cs new file mode 100644 index 0000000..c84bff4 --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerMethods.cs @@ -0,0 +1,74 @@ +using System; +using System.Diagnostics; +using System.IO; +using UnityEditor; +using UnityEngine; + +namespace NoiseCrimeStudios.Toolbox.AssetStoreOrganizer +{ + // Alias + using Debug = UnityEngine.Debug; + + public static class OrganizerMethods + { + static string embeddedPackageFolder = Application.dataPath + Path.DirectorySeparatorChar + "EmbeddedPackages"; + + public static void ImportPackage( string package) + { + try + { + AssetDatabase.ImportPackage( package, true ); + } + catch ( Exception ) + { + Debug.LogError( "Failed to import package: " + package ); + throw; + } + } + + public static void EmbedPackage( string package) + { + if ( !Directory.Exists( embeddedPackageFolder ) ) + { + Directory.CreateDirectory( embeddedPackageFolder ); + + if ( !Directory.Exists( embeddedPackageFolder ) ) + { + Debug.LogError( "Unable to create embeddedPackageFolder for: " + package ); + return; + } + } + + try + { + File.Copy(package, embeddedPackageFolder + Path.DirectorySeparatorChar + Path.GetFileName(package) ); + AssetDatabase.Refresh(); + } + catch ( Exception ) + { + Debug.LogError( "Failed to Copy package: " + package ); + throw; + } + } + + public static void OpenPackageInExplorer( string package) + { + Process.Start(new System.Diagnostics.ProcessStartInfo() + { + FileName = Path.GetDirectoryName(package), + UseShellExecute = true, + Verb = "open" + } ); + } + + public static void OpenDirectoryInExplorer( string path) + { + Process.Start(new System.Diagnostics.ProcessStartInfo() + { + FileName = path, + UseShellExecute = true, + Verb = "open" + } ); + } + } +} diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerMethods.cs.meta b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerMethods.cs.meta new file mode 100644 index 0000000..61517cd --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerMethods.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f8d988eabd083334693988caf5d6f3e7 +timeCreated: 1560479448 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerOptionsPopup.cs b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerOptionsPopup.cs new file mode 100644 index 0000000..e935730 --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerOptionsPopup.cs @@ -0,0 +1,47 @@ +using UnityEditor; +using UnityEngine; + +namespace NoiseCrimeStudios.Toolbox.AssetStoreOrganizer +{ + public class OrganizerOptionsPopup : PopupWindowContent + { + private OrganizerEditor packageLibraryEditor; + + private GUIContent archiveContent = new GUIContent("Archive Shown Packages", "Archive the current filtered packages" ); + private GUIContent fileOpsContent = new GUIContent("Disable File Operations", "Prevents file operations ( for debugging )" ); + private GUIContent logPathsContent = new GUIContent("Log Store Paths", "Logs paths to console for debugging" ); + + public OrganizerOptionsPopup( OrganizerEditor editor ) + { + packageLibraryEditor = editor; + } + + public override Vector2 GetWindowSize() + { + return new Vector2( 256f, 160f ); + } + + public override void OnGUI( Rect rect ) + { + GUILayout.Label( "Archive Options", EditorStyles.boldLabel ); + + packageLibraryEditor.disableFileOperations = + EditorGUILayout.Toggle( fileOpsContent, !packageLibraryEditor.disableFileOperations ); + + if ( GUILayout.Button( archiveContent ) ) + packageLibraryEditor.StartArchiveSourceLibraryProcess(); + + GUILayout.Space(8f); + + if ( GUILayout.Button( logPathsContent ) ) + OrganizerPaths.LogToConsole(); + + if( Event.current.type == EventType.ScrollWheel ) editorWindow.Close(); + } + + /* + public override void OnOpen() { Debug.Log( "Popup opened: " + this ); } + public override void OnClose() { Debug.Log( "Popup closed: " + this ); } + */ + } +} diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerOptionsPopup.cs.meta b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerOptionsPopup.cs.meta new file mode 100644 index 0000000..96c0847 --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerOptionsPopup.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c420fdace04251946acb372fcbe52b00 +timeCreated: 1593566809 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerPaths.cs b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerPaths.cs new file mode 100644 index 0000000..a3ca22c --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerPaths.cs @@ -0,0 +1,135 @@ +using System; +using System.IO; +using NoiseCrimeStudios.Core; +using UnityEditor; +using UnityEngine.Assertions; + +namespace NoiseCrimeStudios.Toolbox.AssetStoreOrganizer +{ + // Aliases + using Debug = UnityEngine.Debug; + + public enum PackagesLocation + { + NativePackageList, + AssetStore, + AssetStore5x, + Custom, + Archive + } + + public static class OrganizerPaths + { + // Gets the root directory for Unity application data. + private static string storeDirectoryRoot = Path.Combine( EnvironmentPath, @"Unity"); + // Gets the Unity AssetStore legacy directory - pre Unity 5.x. + private static string storeDirectoryLegacy = Path.Combine( EnvironmentPath, @"Unity\Asset Store"); + // Gets the Unity AssetStore modern directory from Unity 5.x and up. + private static string storeDirectoryModern = Path.Combine( EnvironmentPath, @"Unity\Asset Store-5.x"); + + // Static strings for Editor Preference Keys + private static readonly string customDirectoryEditorKey = @"com.noisecrimestudios.assetStoreManager.customDirectory"; + private static readonly string backupDirectoryEditorKey = @"com.noisecrimestudios.assetStoreManager.backupDirectory"; + + + /// Get/Set the directory used for custom assetstore location. + public static string StoreDirectoryCustom + { + get { return EditorPrefs.GetString( customDirectoryEditorKey, string.Empty); } + set { EditorPrefs.SetString( customDirectoryEditorKey, value); } + } + + /// Get/Set the directory used for assetstore backup location. + public static string StoreDirectoryBackup + { + get { return EditorPrefs.GetString( backupDirectoryEditorKey, string.Empty); } + set { EditorPrefs.SetString( backupDirectoryEditorKey, value); } + } + + /// Gets the parent Directory for the Unity Application from system environment. + public static string EnvironmentPath + { + get { return Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData ); } + } + + /// Gets the root directory for Unity application data. + public static string StoreDirectoryRoot { get { return storeDirectoryRoot; } } + + /// Gets the Unity AssetStore legacy directory - pre Unity 5.x. + public static string StoreDirectoryLegacy { get { return storeDirectoryLegacy; } } + + /// Gets the Unity AssetStore modern directory from Unity 5.x and up. + public static string StoreDirectoryModern { get { return storeDirectoryModern; } } + + /// Resturns the directory path to the desired Packages Location. + public static string GetPackageDirectory( PackagesLocation packagesLocation ) + { + switch ( packagesLocation ) + { + case PackagesLocation.NativePackageList: return StoreDirectoryRoot; + case PackagesLocation.AssetStore: return StoreDirectoryLegacy; + case PackagesLocation.AssetStore5x: return StoreDirectoryModern; + case PackagesLocation.Custom: return StoreDirectoryCustom; + case PackagesLocation.Archive: return StoreDirectoryBackup; + default: + Assert.IsTrue( false, string.Format( "StorePackageLibrary:GetPackageDirectory: Unhandled enum in switch case {0}", packagesLocation ) ); + return ""; + } + } + + /// Sets the directory path for the desired packages location if applicable. + public static void SetPackageDirectory( PackagesLocation packagesLocation, string path ) + { + switch ( packagesLocation ) + { + case PackagesLocation.NativePackageList: + case PackagesLocation.AssetStore: + case PackagesLocation.AssetStore5x: + Debug.LogErrorFormat("StorePackageLibrary:SetPackageDirectory: Setting {0} is not permitted.", packagesLocation ); + break; + case PackagesLocation.Custom: + StoreDirectoryCustom = path; + break; + case PackagesLocation.Archive: + StoreDirectoryBackup = path; + break; + default: + Assert.IsTrue( false, string.Format( "StorePackageLibrary:SetPackageDirectory: Unhandled enum in switch case {0}", packagesLocation ) ); + break; + } + } + + public static void LogToConsole() + { + StringBuilderDebugLog debugLogOutput = new StringBuilderDebugLog(); + debugLogOutput.AppendFormat( "[NativePackageList]\t {0}", StoreDirectoryRoot ); + debugLogOutput.AppendFormat( "[AssetStore Legacy]\t {0}", StoreDirectoryLegacy ); + debugLogOutput.AppendFormat( "[AssetStore Modern]\t {0}", StoreDirectoryModern ); + debugLogOutput.AppendFormat( "[Custom Path]\t {0}", StoreDirectoryCustom ); + debugLogOutput.AppendFormat( "[Archive Path]\t {0}", StoreDirectoryBackup ); + debugLogOutput.LogToConsole(); + } + } +} + + +/// Returns the location of the AssetStore default Root location. +// public string AssetStoreDirectoryRoot { get; private set; } +/// Returns the location of the old legacy AssetStore location. +// public string AssetStoreDirectoryLegacy { get; private set; } +/// Returns the location of the old legacy AssetStore location. +// public string AssetStoreDirectoryModern { get; private set; } + +/* + public StorePackageLibrary() + { + string appdata = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + + AssetStoreDirectoryRoot = Path.Combine( appdata, @"Unity"); + AssetStoreDirectoryLegacy = Path.Combine( appdata, @"Unity\Asset Store"); + AssetStoreDirectoryModern = Path.Combine( appdata, @"Unity\Asset Store-5.x"); + } +*/ + // if ( null == storeDirectoryRoot) storeDirectoryRoot = Path.Combine( EnvironmentPath, @"Unity"); + // if ( null == storeDirectoryLegacy) storeDirectoryLegacy = Path.Combine( EnvironmentPath, @"Unity\Asset Store"); + // if ( null == storeDirectoryModern) storeDirectoryModern = Path.Combine( EnvironmentPath, @"Unity\Asset Store-5.x"); diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerPaths.cs.meta b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerPaths.cs.meta new file mode 100644 index 0000000..7be5c0e --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/OrganizerPaths.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a515d993da81f7c4eb1f3cb6d1df8a7d +timeCreated: 1593941979 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/PackageFilters.cs b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/PackageFilters.cs new file mode 100644 index 0000000..ba9ce91 --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/PackageFilters.cs @@ -0,0 +1,249 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor; +using UnityEngine; +using NoiseCrimeStudios.Core; +using UnityEngine.Assertions; + +namespace NoiseCrimeStudios.Toolbox.AssetStoreOrganizer +{ + + /// Creates string arrays to be used in dropdowns for filtering by category, publisher, Unity version. + public class PackageFilters + { + public enum Category + { + None, + Title, + UnityVersion, + Version, + ModDate, + PubDate, + Size, + Publisher, + Category, + Archived + } + + private readonly string invalidFilter = "!"; + + private string dynamicSearchText; + + // Filters + private int categoryFilterIndex = 0; + private int publisherFilterIndex = 0; + private int versionFilterIndex = 0; + + private string[] categoryFilterNames; + private string[] publisherFilterNames; + private string[] versionFilterNames; + + private GUIStyle toolbarSeachTextField; + private GUIStyle toolbarSeachCancelButton; + + public bool OrderByAscending { get; set; } + public Category PrimaryCategory { get; set; } + + + public PackageFilters() + { + OrderByAscending = true; + PrimaryCategory = Category.Title; + } + + public void GuiSearchBar() + { + if ( null == toolbarSeachTextField ) toolbarSeachTextField = new GUIStyle( "ToolbarSeachTextField" ); + if ( null == toolbarSeachCancelButton ) toolbarSeachCancelButton = new GUIStyle( "ToolbarSeachCancelButton" ); + + // Dynamic search bar + dynamicSearchText = GUILayout.TextField( dynamicSearchText, toolbarSeachTextField, GUILayout.Width( 256f - 20f ) ); // MinWidth + + if ( GUILayout.Button( "", toolbarSeachCancelButton ) ) + { + dynamicSearchText = ""; + GUI.FocusControl( null ); + } + + // Filters 552 px + GUILayout.Space(8f); + categoryFilterIndex = EditorGUILayout.Popup( "Category", categoryFilterIndex, categoryFilterNames, EditorStyles.toolbarPopup, GUILayout.MinWidth( 192f ), GUILayout.MaxWidth( 192f ) ); + GUILayout.Space(16f); + publisherFilterIndex = EditorGUILayout.Popup( "Publisher", publisherFilterIndex, publisherFilterNames, EditorStyles.toolbarPopup, GUILayout.MinWidth( 192f ), GUILayout.MaxWidth( 192f ) ); + GUILayout.Space(16f); + versionFilterIndex = EditorGUILayout.Popup( "Unity", versionFilterIndex, versionFilterNames, EditorStyles.toolbarPopup, GUILayout.MinWidth( 128f ), GUILayout.MaxWidth( 128f ) ); + } + + /// Returns a cleaned up Unity version string to just the major.minor version if applicable for filters. + string GetUnityMajorMinorVersion( string version ) + { + if ( string.IsNullOrEmpty( version ) || version == "NA" ) return "NA"; + int major = version.IndexOf('.'); + int minor = version.IndexOf('.', major + 1); + return version.Substring( 0, minor ); + } + + private string GetPreviousFilter( string[] filterNames, int filterIndex ) + { + if ( null != filterNames && filterIndex >= 0 && filterIndex < filterNames.Length) + return filterNames[filterIndex]; + + return invalidFilter; + } + + /// Pre-compile string arrays of filter items for each type ( category, publisher, Unity version ). + public void ConstructFilters( List packageLibrary ) + { +#if LOG_UNITY_METHODS + Debug.Log( "PackageFilters: ConstructFilters" ); +#endif + // 2021: Cache Current Filters for re-instatement later. + string previousCategoryFilter = GetPreviousFilter( categoryFilterNames, categoryFilterIndex); + string previousPublisherFilter = GetPreviousFilter( publisherFilterNames, publisherFilterIndex); + string previousVersionFilter = GetPreviousFilter( versionFilterNames, versionFilterIndex); + + dynamicSearchText = string.Empty; + + List categoryNames = new List(); + List publisherNames = new List(); + List versionNames = new List(); + + foreach ( AssetPackage sp in packageLibrary ) + { + string unity = GetUnityMajorMinorVersion( sp.unity_version ); + + if ( !categoryNames.Contains( sp.category.label ) ) categoryNames.Add( sp.category.label ); + if ( !publisherNames.Contains( sp.publisher.label ) ) publisherNames.Add( sp.publisher.label ); + if ( !versionNames.Contains( unity ) ) versionNames.Add( unity ); + } + + categoryNames.Sort(); + publisherNames.Sort(); + versionNames.Sort(); + + categoryNames.Insert( 0, "All" ); + publisherNames.Insert( 0, "All" ); + versionNames.Insert( 0, "All" ); + + categoryFilterNames = categoryNames.ToArray(); + publisherFilterNames = publisherNames.ToArray(); + versionFilterNames = versionNames.ToArray(); + + // 2021: Reinstate filters - Could store these so if they aren't found they are still retained? + categoryFilterIndex = Mathf.Max(0, Array.FindIndex( categoryFilterNames, element => element == previousCategoryFilter ) ); + publisherFilterIndex = Mathf.Max(0, Array.FindIndex( publisherFilterNames, element => element == previousPublisherFilter ) ); + versionFilterIndex = Mathf.Max(0, Array.FindIndex( versionFilterNames, element => element == previousVersionFilter ) ); + + // Debug.LogFormat( "Cat:{0} {1} Pub: {2} {3} Version: {4} {5}", + // previousCategoryFilter, categoryFilterIndex, previousPublisherFilter, publisherFilterIndex, previousVersionFilter, versionFilterIndex ); + } + + public List SortAndFilterResults( List packageLibrary ) + { + return SortAndFilterResults( packageLibrary, PrimaryCategory, Category.Title ); + } + + public List SortAndFilterResults( List packageLibrary, Category activeColumn, Category secondColumn = Category.Title ) + { + IEnumerable packages = packageLibrary; + + // Apply Filters + if ( categoryFilterIndex > 0 ) packages = packages.Where( o => o.category.label.Contains( categoryFilterNames[ categoryFilterIndex ] ) ); + if ( publisherFilterIndex > 0 ) packages = packages.Where( o => o.publisher.label == publisherFilterNames[ publisherFilterIndex ] ); + if ( versionFilterIndex > 0 ) packages = packages.Where( o => o.unity_version.Contains( versionFilterNames[ versionFilterIndex ] ) ); + + // Apply Dyanmic search string + if ( !string.IsNullOrEmpty( dynamicSearchText ) ) + packages = packages.Where( o => o.title.IndexOf( dynamicSearchText, 0, StringComparison.CurrentCultureIgnoreCase ) != -1 ); + + return MultiColumnSort( packages, activeColumn, secondColumn ); + } + + + private List MultiColumnSort( IEnumerable packages, Category activeColumn, Category secondColumn ) + { + IOrderedEnumerable orderedPackages = null; + + switch ( activeColumn ) + { + case Category.Title: orderedPackages = packages.OrderBy( o => o.title, OrderByAscending ); break; + case Category.UnityVersion: orderedPackages = packages.OrderBy( o => o.unity_version, OrderByAscending ); break; + case Category.Version: orderedPackages = packages.OrderBy( o => o.version, OrderByAscending ); break; + case Category.ModDate: orderedPackages = packages.OrderBy( o => o.modifiedDate, OrderByAscending ); break; + case Category.PubDate: orderedPackages = packages.OrderBy( o => o.publishDate, OrderByAscending ); break; + case Category.Size: orderedPackages = packages.OrderBy( o => o.fileSize, OrderByAscending ); break; + case Category.Publisher: orderedPackages = packages.OrderBy( o => o.publisher.label, OrderByAscending ); break; + case Category.Category: orderedPackages = packages.OrderBy( o => o.category.label, OrderByAscending ); break; + case Category.Archived: orderedPackages = packages.OrderBy( o => o.isArchived, OrderByAscending ); break; + default: + Assert.IsTrue( false, string.Format( "PackageFilters: Unhandled enum in switch case {0}", activeColumn ) ); + break; + } + + if ( activeColumn != secondColumn ) + { + switch ( secondColumn ) + { + case Category.Title: orderedPackages = orderedPackages.ThenBy( o => o.title, OrderByAscending ); break; + case Category.UnityVersion: orderedPackages = orderedPackages.ThenBy( o => o.unity_version, OrderByAscending ); break; + case Category.Version: orderedPackages = orderedPackages.ThenBy( o => o.version, OrderByAscending ); break; + case Category.ModDate: orderedPackages = orderedPackages.ThenBy( o => o.modifiedDate, OrderByAscending ); break; + case Category.PubDate: orderedPackages = orderedPackages.ThenBy( o => o.publishDate, OrderByAscending ); break; + case Category.Size: orderedPackages = orderedPackages.ThenBy( o => o.fileSize, OrderByAscending ); break; + case Category.Publisher: orderedPackages = orderedPackages.ThenBy( o => o.publisher.label, OrderByAscending ); break; + case Category.Category: orderedPackages = orderedPackages.ThenBy( o => o.category.label, OrderByAscending ); break; + case Category.Archived: orderedPackages = orderedPackages.ThenBy( o => o.isArchived, OrderByAscending ); break; + default: + Assert.IsTrue( false, string.Format( "PackageFilters: Unhandled enum in switch case {0}", secondColumn ) ); + break; + } + } + + return orderedPackages.ToList(); + } + + + private List SingleColumnSort( IEnumerable packages, Category activeColumn ) + { + if ( OrderByAscending ) + { + switch ( activeColumn ) + { + case Category.Title: packages = packages.OrderBy( o => o.title ); break; + case Category.UnityVersion: packages = packages.OrderBy( o => o.unity_version ); break; + case Category.Version: packages = packages.OrderBy( o => o.version ); break; + case Category.ModDate: packages = packages.OrderBy( o => o.modifiedDate ); break; + case Category.PubDate: packages = packages.OrderBy( o => o.publishDate ); break; + case Category.Size: packages = packages.OrderBy( o => o.fileSize ); break; + case Category.Publisher: packages = packages.OrderBy( o => o.publisher.label ); break; + case Category.Category: packages = packages.OrderBy( o => o.category.label ); break; + case Category.Archived: packages = packages.OrderBy( o => o.isArchived ); break; + default: + Assert.IsTrue( false, string.Format( "PackageFilters: Unhandled enum in switch case {0}", activeColumn ) ); + break; + } + } + else + { + switch ( activeColumn ) + { + case Category.Title: packages = packages.OrderByDescending( o => o.title ); break; + case Category.UnityVersion: packages = packages.OrderByDescending( o => o.unity_version ); break; + case Category.Version: packages = packages.OrderByDescending( o => o.version ); break; + case Category.ModDate: packages = packages.OrderByDescending( o => o.modifiedDate ); break; + case Category.PubDate: packages = packages.OrderByDescending( o => o.publishDate ); break; + case Category.Size: packages = packages.OrderByDescending( o => o.fileSize ); break; + case Category.Publisher: packages = packages.OrderByDescending( o => o.publisher.label ); break; + case Category.Category: packages = packages.OrderByDescending( o => o.category.label ); break; + case Category.Archived: packages = packages.OrderByDescending( o => o.isArchived ); break; + default: + Assert.IsTrue( false, string.Format( "PackageFilters: Unhandled enum in switch case {0}", activeColumn ) ); + break; + } + } + + return packages.ToList(); + } + } +} diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/PackageFilters.cs.meta b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/PackageFilters.cs.meta new file mode 100644 index 0000000..7d6cf98 --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/PackageFilters.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3ed5edce28fc4214d9e23dcfd706fee2 +timeCreated: 1560398868 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/PackageLibrary.cs b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/PackageLibrary.cs new file mode 100644 index 0000000..22c28d2 --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/PackageLibrary.cs @@ -0,0 +1,231 @@ +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using NoiseCrimeStudios.Core.Formatting; +using NoiseCrimeStudios.Core.IO; +using UnityEditor; +using UnityEngine.Assertions; + +namespace NoiseCrimeStudios.Toolbox.AssetStoreOrganizer +{ + // Aliases + using Debug = UnityEngine.Debug; + + public enum MatchState { None, Partial, Exact } + + /// Library holds all packages found within the specificed directory location. + public class PackageLibrary + { + private static readonly string[] searchPatterns = new string[]{ "*.unitypackage" }; + + public List packageLibrary = new List(); + public Dictionary> packageIDTable = new Dictionary>(); + + + /// Returns number of files or packages checked. + public int FileCount { get; private set; } + /// Returns number of packages in Library. + public int PackageCount { get { return packageLibrary.Count; } } + /// Returns a display string formatting of the file size of all packages on disk. + public string SizeOnDisk { get; private set; } + + public PackagesLocation Location { get; private set; } + + + public PackageLibrary() { } + + public PackageLibrary( PackagesLocation packagesLocation ) + { + PopulateLibraryContent( packagesLocation ); + } + + public virtual void PopulateLibraryContent( PackagesLocation packagesLocation ) + { + Location = packagesLocation; + + packageLibrary.Clear(); + packageIDTable.Clear(); + + // Build packages list + switch ( packagesLocation ) + { + case PackagesLocation.NativePackageList: PopulateFromPackageList(); break; + case PackagesLocation.AssetStore: PopulateFileSearchBegin( OrganizerPaths.StoreDirectoryLegacy ); break; + case PackagesLocation.AssetStore5x: PopulateFileSearchBegin( OrganizerPaths.StoreDirectoryModern ); break; + case PackagesLocation.Custom: PopulateFileSearchBegin( OrganizerPaths.StoreDirectoryCustom ); break; + case PackagesLocation.Archive: PopulateFileSearchBegin( OrganizerPaths.StoreDirectoryBackup ); break; + default: + Assert.IsTrue( false, string.Format( "StorePackageLibrary: Unhandled enum in switch case {0}", packagesLocation ) ); + break; + } + + // Build lookuptable for existing archive packages by id, with multiple packages added to value list. + foreach ( AssetPackage sp in packageLibrary ) + { + List list; + + if ( packageIDTable.TryGetValue( sp.id, out list ) ) + list.Add( sp ); + else + packageIDTable.Add( sp.id, new List(){ sp } ); + } + } + + /// Populates packages list from Unity provided native PackageInfo Method. + private void PopulateFromPackageList() + { + long libraryDiskSize = 0; + + var flags = BindingFlags.Static | BindingFlags.NonPublic; + var methodInfo = typeof(PackageInfo).GetMethod("GetPackageList", flags); + object result = methodInfo.Invoke(null, null ); + + PackageInfo[] packageList = (PackageInfo[])result; + + foreach ( PackageInfo p in packageList ) + libraryDiskSize += AssetPackage.PopulateFromPackageInfo( p, packageLibrary ); + + SizeOnDisk = Numerical.ByteCountToSuffixHumbads( libraryDiskSize ); + FileCount = packageList.Length; + } + + /// Populates packages list from iterating through the provided directory. + private void PopulateFileSearchBegin( string packagesPath ) + { + if ( !DirectoryUtils.IsValidPathToDirectory( packagesPath ) ) + { + Debug.LogWarningFormat( "PackageLibrary: Directory does not exist\n{0}", packagesPath ); + return; + } + + int fileCounter = 0; + long libraryDiskSize = 0; + + GetFilesRecursiveViaMultiplePatterns( packagesPath, searchPatterns, true, ref fileCounter, ref libraryDiskSize); + + SizeOnDisk = Numerical.ByteCountToSuffixHumbads( libraryDiskSize ); + FileCount = fileCounter; + } + + /// Given a path and search pattern will populate Library from package files found in directory. + private void GetFilesRecursiveViaMultiplePatterns( string packagesPath, string[] searchPatterns, bool subFolders, ref int fileCounter, ref long libraryDiskSize ) + { + if ( !DirectoryUtils.IsValidPathToDirectory( packagesPath ) ) + { + Debug.LogWarningFormat("PackageLibrary: Directory does not exist\n{0}", packagesPath); + return; + } + + string[] directories = Directory.GetDirectories( packagesPath ); + + foreach ( string directory in directories ) + GetFilesRecursiveViaMultiplePatterns( directory, searchPatterns, subFolders, ref fileCounter, ref libraryDiskSize ); + + foreach ( string sp in searchPatterns ) + { + string[] tmpFiles = Directory.GetFiles( packagesPath, sp ); + fileCounter += tmpFiles.Length; + + foreach ( string fullFilePath in tmpFiles ) + libraryDiskSize += AssetPackage.CreatePackageInfoFromLocalStorage( fullFilePath, packageLibrary ); + } + } + + /* + public void CompareAgainstArchive( PackageArchive storePackageArchives ) + { + foreach( AssetPackage storePack in packageLibrary ) + storePack.isArchived = storePackageArchives.IsPackageArchived( storePack ); + }*/ + + public void CompareAgainstArchive( PackageLibrary archiveLibrary ) + { + foreach( AssetPackage pack in packageLibrary ) + pack.isArchived = ( archiveLibrary.ContainsPackage( pack ) == MatchState.Exact ); + } + + /* + public void CompareAgainstLibrary( PackageLibrary otherLibrary ) + { + foreach( AssetPackage pack in packageLibrary ) + } + */ + + /// Checks if package is found within this library - not object compare! + public MatchState ContainsPackage( AssetPackage package ) + { + List packages; + + if ( packageIDTable.TryGetValue( package.id, out packages ) ) + { + bool partialMatch = true; + + foreach ( AssetPackage archivePack in packages ) + { + bool matchName = package.title == archivePack.title; + bool matchUnityVersion = package.unity_version == archivePack.unity_version; + bool matchVersion = package.version == archivePack.version; + bool matchVersionID = package.version_id == archivePack.version_id; + bool matchPubDate = package.pubdate == archivePack.pubdate; + + bool exactMatched = matchName && matchVersion && matchUnityVersion && matchVersionID && matchPubDate; + + // Maintain Partial Match State in case we don't find exact match. + // Have found cases where we get a name and version match but other data is mismatched. + partialMatch = partialMatch | ( matchName && matchVersion && !exactMatched ); + + if ( exactMatched ) + return MatchState.Exact; + } + + if ( partialMatch ) return MatchState.Partial; + } + + return MatchState.None; + } + + + /// + /// Checks if package is found within this library and if Matched puts the AssetPackage into result. + /// Partial Matches are not returned. + /// + /// Matched state and if matched the AssetPackage in result. + public MatchState TryGetMatchedPackage( AssetPackage package, out AssetPackage result ) + { + List packages; + + result = null; + + if ( packageIDTable.TryGetValue( package.id, out packages ) ) + { + bool partialMatch = true; + + foreach ( AssetPackage archivePack in packages ) + { + bool matchName = package.title == archivePack.title; + bool matchUnityVersion = package.unity_version == archivePack.unity_version; + bool matchVersion = package.version == archivePack.version; + bool matchVersionID = package.version_id == archivePack.version_id; + bool matchPubDate = package.pubdate == archivePack.pubdate; + + bool exactMatched = matchName && matchVersion && matchUnityVersion && matchVersionID && matchPubDate; + + // Maintain Partial Match State in case we don't find exact match. + // Have found cases where we get a name and version match but other data is mismatched. + partialMatch = partialMatch | ( matchName && matchVersion && !exactMatched ); + + if ( exactMatched ) + { + result = archivePack; + return MatchState.Exact; + } + } + + if ( partialMatch ) + return MatchState.Partial; + } + + return MatchState.None; + } + } +} diff --git a/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/PackageLibrary.cs.meta b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/PackageLibrary.cs.meta new file mode 100644 index 0000000..be8014d --- /dev/null +++ b/Assets/NoiseCrimeStudiosToolbox/Editor/AssetStoreOrganizer/PackageLibrary.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2e09f709c0f53b549ac6121f1f9ae95c +timeCreated: 1560396876 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ProjectSettings/AudioManager.asset b/ProjectSettings/AudioManager.asset new file mode 100644 index 0000000000000000000000000000000000000000..f512b3a1fea4c92dce75cbcc0adc3da2274d524c GIT binary patch literal 4140 zcmeH~u}<7T5QfKRLI@!c8X6iGhzgx_iU=hK9Ox8*1ZQz=*qAjk?A@Mxb^(>^>(eGm zLq|iKDi09x2D|~Ufb;(b3n?|_{?ce?KF#iWez{qZ#&?mAYa+6U6^qDv^K)|}ZpmX= zmYxUjp0q4iPbL@9`Iq3~=iKnl{Qk@CKM1x^8zKd^lvPoXdvfhdaqCGj1<1aq@Z=YI zKcFUWASm{eFCi!Q389*=ASY)~0`))*VdK^Q5crDI1UqtjqdMVU>d zqhpnuEC@$hT>u~0Q;n^m8lbDEG8Ucia66Awc1ExiWp5M0&^O!wjsa{{!Jj zWr;G_ksg}-EE)2kWURg!U47=uIcV9%=}|VWhJK!jBT@Vzoty*C0q1~oz&YR?a1J;J foCD4Q=YVtIwH+un@vN+(ev4N(pa|-#@G$)cs4Rg9 literal 0 HcmV?d00001 diff --git a/ProjectSettings/ClusterInputManager.asset b/ProjectSettings/ClusterInputManager.asset new file mode 100644 index 0000000000000000000000000000000000000000..a544c36697e9f9f561339a0c254c84d766301555 GIT binary patch literal 4104 zcmeH^yGjE=6o$|2=HmTsCBA?~Acdw4#6k-Nk=RO*QIsUe=28!6ZR;B(g`MvrLJ%7* zeFoS6-&q!xq_#Q(le6>fnSVClhy(+XwK)-4M@13YuN+ir*H!tAaa6@#_SdKLd5g31alt7sB>(pz zy_XGe4tk^Ka^O90dMu6hpx3w2arb`EKWTMaH#U;aWwPw$UVNyj?WfErK(YCsLB0X3io)PNdL18U&^4g3N6zj?#} literal 0 HcmV?d00001 diff --git a/ProjectSettings/DynamicsManager.asset b/ProjectSettings/DynamicsManager.asset new file mode 100644 index 0000000000000000000000000000000000000000..3c94e86e4c0f5c0464a87e916e3c6616b57cab55 GIT binary patch literal 4280 zcmeH~ziSjh6vyA*`Xipk_#+B(1|z9Gh(se8BeBRqPZ@$A7OXR*FI`y82PUDFO z(Y5;Z`g|};KeH@z9DsSISvJ0P`Q^;iWVSi>>_+2?tIva8Mc(B!3}t=1l9@%H$id$m zm-_D<>K_8+R=GR$4SWLY6YvV0Xd1Z+y+V%*SaE&ccgSl6=iF%hRKX7qxI>o^&%wF> z5yN@!3VlKUCf3~JC_JC1LUqiuhV@wC<(xdvLolvC24~}QG2cbZyvh((@~4QIA7=<- z&ig(`%$#RpEBRZ*%*PqRn6IM#lZlB=8am`(3(oqnmGwVNT;Af4Pv9_o9$YZdV$MI~ zyfr|+uQR}$hd$0M_GM>&cEDXTe+}>OoRcG*?-x24ey-qNyO%0IZHY+i$b=qm-c3YT z=^pJ0}|VX$dV8CBj=MT9$$6gt|l^O%=+OWdxqkZ4)fToyeCP?L?;SINU~R zJ(O~96clY5aioQ>*McCGdf0tE4!bg0!LCB9I7YE# z@Fl-Dq#KFa!9f|`iNsbYZ*Pk|t-7)qC%zm|uhBxhDta<$#9^pX41m)nYTu}z-vJ~v z#y?1FRspMkRlq7>6|f3e1*`&A0jq#j;9n^4@%zOOf9bneJ$QYydN8xV-_ZPxh=0yB K9{hdyKkXMhLp7cN literal 0 HcmV?d00001 diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset new file mode 100644 index 0000000000000000000000000000000000000000..eed98f10556fe9e15df84b5861c4dc04d7773d13 GIT binary patch literal 4104 zcmeH@%Syvw5QWd*wDo>PSK>-sh)`Okb|n;{;6f28-6%z36KkYavFSdq;7j-bzJRz9 zTa$gac$YfcbF%3ycgvxv*2HT$J#grl~Om%UQnC^y&5M z{wQrdCnt+2qK51-6dIHNssnSqB@#w&hPe@-wF&*FgD8cW^F(@`DpeeT#~ss1tXL_GKBuEa1^ z@%*2=6XMqMIOe48s-FDiS-g`KSxcKKx{Uj+4rS*0_h~`ei0?8NpAn>uc#XOEtRQW~ z51EV43DRmo6yMzK^`lNu592uMwtKiftGB{#*n zRaFoO_yAf}?|$rkJsNBt-5C^z-?x7aZwdV=5n@}$22m+Ts(Mip1@ieAQu#Tc@{~YG zH4)IR@Ksr(enm2s*jowKWrhHUZZHN9>6@_Iat1mlS|RNTKaha#Y1G#d)b)4U+B1@A zjJ<|$wfro&jAQ;x=FmO|DC3xCG6z2oC<7e*zn3}syZ~5&cl*C6xUc_9;B|ESzx>4gKqq`}7B>ALC5d{~O?Sbo;;A@|{FGV z=PwJIJ>OY6wzRPq zu41(Ev|!t6aMD&si!{~C+J@#!{yPRHzM4 m`?}CCGG3doQ)>@&#znVV-1l$~bxSu|&azROyHT8+)cgV0$Hnyk literal 0 HcmV?d00001 diff --git a/ProjectSettings/GraphicsSettings.asset b/ProjectSettings/GraphicsSettings.asset new file mode 100644 index 0000000000000000000000000000000000000000..880d373e5b9e3c14b6026d0b529f45dc040c6b7a GIT binary patch literal 4390 zcmai%%a0UA9LKAd+4Y5@h@t|Dh={1mLwTqOyX^2-*~MXB;)}Irrgo>Hr+e(~ad#oc z@#0Bu9=vEICZ6T}`o*s<9rDm!=^{d~vs(w}7 zgAi-J7vi>U0v|%$iZ3Dd4(=P=Ket=_v%I|Qc>wp4E-#8D+FfVP{db9cPc|#-T!z-K5Cp&*us4 zYk2-V>~-7|NBcx)6DG}d?Q?NVUb5#Eo|krAeO>E1;J7EI5NDr_!@Z(q=PHZylxBwK z=kv7Vp5D)K#NqxQM4|Edd=)vV+xX9Dx>?7+gq&Qo{)Y5neWPyKU`4ssObxT_Js^!y;o4o%8 z&i$Dohw;2I@BMhOlRvNN3SVbA-`h0$b6q>YxeqUBy21}x{$hcjvHYb1Pb`1Az~8g{ zl>-0F^0Nj0o#nFy{)^?W7WnU$OY$Kzf1dNd!FkTB&;u824aQqYJQM?@AYI#uL+bnMu_;$-f$4ff?4$C8O8rMtR{g$@~hse$ODT8}J zuaUztK5Kbwus9yeR>Q9)lPXR9a6S=7+J1oAWJA_f>}Yegtmaf4tGZ~;jz@JRDwQ-o zXuJ-AnHnm`{6LMCQK`tZp)1+Q2{jj}TIxq(!U45dsc^C-Yl>r|1;Q~kFKbKL0D!V; zrHxZj+>`YiwJ=SZAmBcY=s^g<0mFek3 z&MVPQFwHE*l{l)ZBhezh&zYoOt3N<&L}u5C@&v!iDwTdS)0C~rH1=C9%Hz~V z^ZDjz$i1kcFHf_9CzWbd0_lgjU}R-K9*LS&oCMyIymxsiluf^O%|WK?zsH)}!POOl zPPVIQEODV;=gGqgIEOK)OJ>!!k1n>l8hg+h4yvjiO)ki^)))=vqC^ylz;u- zEapX3NYV7eu{J)iFVK^VxrSM5GMy+RKN_YgOn7+gHn0m9D~hL7v!!C0wsB4QcrqXM zS+q?P)5ukYSYsXd6{{p_$2FDgY==;ot(xc6tXjloC3f^ RSMjrRIGabY$IHxh{0k&PzzYBX literal 0 HcmV?d00001 diff --git a/ProjectSettings/InputManager.asset b/ProjectSettings/InputManager.asset new file mode 100644 index 0000000000000000000000000000000000000000..0ae4cee66467729007cad9f3e6b3688dab9f3644 GIT binary patch literal 5520 zcmeI0%Wl&^6ow}xE%#fY7g`GCepyr$1eK5g7YYJID^SHvLPBmbO-Ed`H+#PQ%>3>j?CmqpLj8iWiQTYKAu0%| zDyJeu3ct0qsC-I^N(LfPK}m`4(23=E6|cr`N{xWQLOqRsq4c!)fz|+G$YG(S@!OAj z4t*ToL9xO)GU7JIe!#rcJL`If#@`G*WpI3_#@|9+l}_;hMDpoxt?L2*5Pb5tp$_KN z`P(_(Xyxyqu8PiQJ_0@955p&a7wS0vZjLuv`Mis9eB5A-e+xeOU8v*u`#9ccbMVRUM;*r>;CQ2ze~`K=I)AXP2mE>X zC+c6~*Uc zi_#0Uu|>-hIq79xtK?hra?&hH&6jzzuG=-|dfE3KTa+BnVqeWQ3;v`&0Lp!ROx`u; zEq@6!m^tA|TLCC|wpkLEJuh8f_)8@zOfGEBS(+>tRi=1tk*%sfj>u11Nd}S(BpFCD zkYpgqK$3wZ14#z{=M3=t$2070$F-In+cyi*)$+Z+AZL8OBD+?8) R4-+38l*O%eMD?_1{{>MFn!*48 literal 0 HcmV?d00001 diff --git a/ProjectSettings/NavMeshAreas.asset b/ProjectSettings/NavMeshAreas.asset new file mode 100644 index 0000000000000000000000000000000000000000..562e53e61fa1f0e6819d8ae0d1842a23a7c96094 GIT binary patch literal 4460 zcmeH~OKTKC5XWn>yNU1jD-TV497He>iRNZrdq_k>GyzW{o!xdbab{=PnH3)(>j&`e zK@br<=s_^xK|FYsoJG8N^d$NXvi|=)J!57+f=q=@SN*!Wr>eRR+aks9BKtkTKaqWy zL@thA8lAW^CYzm3$8i82lXg14KW)^0eHgm+;@$YiN6$Y8XF$(ly@$(?36VCobd1p! zaq#!LAno^#w2Oc|Djtq}1wRU#{${`N?{UU(1_yZo>tc98en1<<9-hNNaik!}F|T2b z{w2aTc~R!zdmbivZ^}!V^ZUS^Df;(j&fi9EMz37Qi9Db7_LLXpCD;YnjAaJ~h50g0 z)WPtbhQ^%v&ckLryHcLbcX!IO`R=j22l*~TXFTJW_on_u^IaD<<{74u7Vma@h!gyG>Z_pY4F+xZZ=TGS5{e+Oj z{||KX0YXT^H=&ac5<(K*hf5?MGL$^-!+vny3wuf0Uk@D=l43k6HhwQhc4@U^w z=DV4GI|&^3TPf3Tr^wAHW%}*3FluGVz988obyukK%I`HksHGYG@78%C;L(c-)H8@lEObw(?`s<)Ikt37YY zeTbM7CFaYnrwxx1MO7-Tri%2Urz+YVDA&O?jV^MR-E09+puRvabyaIUz z@(Sb?$SaUnAX9-6SbX!|RNh^+;%PiyCizBP2%?d#jBh9Ys>d{i0clVE@AL5bz{Zwm j1oNE|8K1#qb2k+L6M6gQ++}0g4V+llxfY%@fm{6x8#o?K literal 0 HcmV?d00001 diff --git a/ProjectSettings/NetworkManager.asset b/ProjectSettings/NetworkManager.asset new file mode 100644 index 0000000000000000000000000000000000000000..f713b6536197c8a47013334766dbfbfe5bfdaba9 GIT binary patch literal 4112 zcmeH_%Syvg5QgU@t=f94YXz6$rdV%Xi4=-b@KR84Aw^H=X|2|_q_J+}69|GUSKYW4 zx4wigpzol#6O8{Phgk9k!Z|RRnU6nnCO;vvHi$AABAP))B3jF?XY=(O{rJ8w1i(F0 z-@i@u-|jwNN>4Y7gKy_cu)2w0372M+@qNuFBA%dC?32cx%qAnA4E8_L`l%tFh4vIZ@5uhK zpL@!^?l>2_vMn3Rq05t^s$MmARA05w9H@59k*-2n==GF)*eN@zE~`|Nt~_3bI7wleKG5`Po literal 0 HcmV?d00001 diff --git a/ProjectSettings/Physics2DSettings.asset b/ProjectSettings/Physics2DSettings.asset new file mode 100644 index 0000000000000000000000000000000000000000..16e8bb0cea515757ffc4b0b4e9c5e07f0ceba39d GIT binary patch literal 4380 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 Wt*{fwVoj>@miC$CA>3ZE(Ec0Wo(Jv# literal 0 HcmV?d00001 diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset new file mode 100644 index 0000000000000000000000000000000000000000..afe40a67241b5d15a3df46c0179c51c45baddd0e GIT binary patch literal 4308 zcmeHKyH4Xk6unNI@Lb-n6%E>k1|d-ZLP977uSh(^E@-z~jabJDgb6rKkzXV~>l}Je=lWwhip$J)dhy9XC^_z}yn^3z<4a;>HVdfSs(vxGTjIo;*GI zbYtwqvnR!~JbQ`5KJ(*~Qi21J3c?BWskEVDbqw^T>gnu!k^Eh$i#f;7qDelS*?r{yV3+Fj#{O%4I zY?-;p6v0v?hsxhoTKQfeq4FD2Q!OuO$l327^&qTjer%nS}5#8 z4+Ete=PK}YxcLh)d(g74>w!1(UA2x?BLo0r&;3({XwgL2#~+pP`bXC8;oH31pM3*v CZ>XRE literal 0 HcmV?d00001 diff --git a/ProjectSettings/TimeManager.asset b/ProjectSettings/TimeManager.asset new file mode 100644 index 0000000000000000000000000000000000000000..e12f249b610edd3f21b38b75a23f76492636ea86 GIT binary patch literal 4116 zcmZQzV62p*h(nLs)uGdI;YF)uMawTQtjvm!M` z0VGmfl3Kvvn^=*VTbirjn3I!Vjx3QI4^k7HoS2geR}_#~RFavTlZwy|ay`TkU;hY-;eUoeGZ05d9e+$N28}+w>t0?Mk%ekTEbBk-tXFEr>uKS!K z@Z25X3AAczKBCWe=Dc25?+9}}pGIN5*hM{`Mq$0Y!F^sU_`e7G-0)oZAF7;aFQAn$ zH|Q0o2<+89j%=QT`-pu*%XG4RJOF5c8}yb_1lD_y`!bzF;M_8uPbw!mtmrz=^pAjB znh(Awqu>d6(YK?F%X~WquA=DM@to^@$=;I_%<1z+{V~R6`X|9v6!lN#+@SBABjC?z z?#ui+1J3PVf6i*0^UR-f;Fcbb-{Vg%8yx33(4Yg~esPZHUI0wMi@sfCT(+)D;3|si zx}0;Zj}HU%$GI=l=MPb-eiK|pQ6KxDxj`eGAW&c7(E7#qoWB#whXvo0YcqlG3rEfi zDLsEFrtZ_nB9`|8SM<~NbK%Q{sM9Zb{GzwCUeB_K8a)%)@$w@P1`&h?^accG>`?Y1 z(RMudXcki$AdR3KJD9`HR(C=fF_>m*&XkNc;L@VJCeOni%h$N z!`i<6tRvjHjx861sEgIj2JvmXD`s8Jr+qgHJhxxZi3o#i-w_*^q5Xw%y5S#1)hY)n z2Py|D2Py|D2Py|D2mUVyZt!xJr3~YnrWx|#a6;fH954`?C`LUzKD()c^nh literal 0 HcmV?d00001 diff --git a/README.md b/README.md new file mode 100644 index 0000000..5557627 --- /dev/null +++ b/README.md @@ -0,0 +1,159 @@ +## Unity - Asset Store Organizer + +![Screenshot](Screenshots/OrganizerEditor000.png) + +A Unity Editor Tool that allows you to quickly import or embed Unity Asset Store Packages into your project with additional support to allow archiving of packages to a different drive or folder and easily move or delete packages between them. + + +### Introduction +After years of frustration using the Unity Asset Store and even the new Package Manager when they added Asset Store support I decided to write my own Unity editor tool to solve several of my biggest complaints. + +1. Choose where to install Asset Store Packages. +2. Poor support for quickly finding a purchased Asset Store Package and installing it. + + +### Important +**This tool does not allow you to change the default download location of Asset Store instead it offers an archiving mechansim as a way to mitigate this issue.** + +**It should be noted that currently there is no good mechnsim for checking if the current version of a package is the latest one. Therefore you should always do that via the Asset Store or the Package Manager if it is important.** + + + +## Key Features +Key features of the tool: + +* Archive packages to a new folder or drive. +* Archiving maintains a copy of all versions of the package. +* Import or Embed directly from Archive location. +* Import any version of a package from your archive directly. +* Search function to quickly find asset by name. +* Filter functions to reduce the displayed list of assets by Category, Publisher or Unity version. +* Stats showing total disk space used and number of packages by location. + + + +### Archiving +Straightforward archiving system that allows you to quickly and simply archive packages and then import them directly from that location into an Unity project. Alternatively you can use the archiving mechanism to move packages back and forth between the official Unity Asset Store download location and your archive location. This is useful for when you want to check if a package has an update available. + +Furthermore archiving will actually keep package versions separate, allowing you to keep and maintain older versions of a package on disk. You can then choose which version to install from the archive. + + +### Performance +Apart from an initial delay the first time you open the editor in Unity, the editor tool provides a fast and easy method to quickly install or embed a package into your project. + + +### Search & Filters +The tool provides a fast dynamic search function and means to filter the results so you can quickly locate the desired Asset. + + + + +## Help + +### Toolbar + +**Refresh Button** +Use the refresh button to refresh the package list of the current package location. + +**Package Source Locations** +You can choose the location of the packages you are browsing from the dropdown list. Regardless of browsing location you can import or embed packages from the browser by clicking on the import icon or clicking on the Package name and choosing from the dropdown menu. + +Locations: + +* NativePackageList - This returns all the packages found by Unity using its own native methods. +* AssetStore - This returns all packages found in the pre Unity 5.x Asset Store Location. +* AssetStore5x - This returns all the packages found in the post Unity 5.x Asset Store Location. +* Custom - This is a secondary custom location you set up by clicking on the 'browse' or path name. +* Archive - This is a custom location you set up by clicking on the 'browse' or path name. + +**Package Source Path Name** +This shows the current path name used as the source location. If it states 'Browse' then clicking it will open a folder dialog from which you can locate or create a new folder to use for custom or archive location. + + +**Archive Options** +This button displays a dropdown with the following options: + +* Disable File Operations +Will disable actual archiving file operations as a tool for debugging. + +* Archive Shown Packages +Click to archive all currently listed packages in the browser that are not currently archived or have a different version number to the ones that are. + +* Log Store Paths +Debugging tool to show all the paths to the locations being used. + + +### Search Bar + +**Search Box** +Type the name of the package/asset you want to search for. Dynamically searches the package location as you type to locate the asset quickly without having to type the exact or whole name of the asset. + +**Filters - Category** +Dropdown list of all the categories used by the packages in the current location. +Selecting a filter will display only those packages in the browser. + +**Filters - Publisher** +Dropdown list of all the publishers used by the packages in the current location. +Selecting a filter will display only those packages in the browser. + +**Filters - Unity Version** +Dropdown list of all the Unity Versions used by the packages in the current location. +Selecting a filter will display only those packages in the browser. + +**Stats** +Displays size of all packages listed vs size of all packages in location. +Displays count of all packages listed vs of all packages in location. + +### Browser Window +The main window is the browser that lists all the currently valid packages from the chosen location, search and filters. + +**Import Button** +Click this button to begin the package Import process. + +**Package Name** +The name of the package. Click this area to access a dropdown menu: + +* Import Package - begins the package Import process. +* Embed Package - copies the package into the project. +* Delete from AssetStore Cache - will delete the asset from this source location! +* Archive Package - Will archive the package. + +* Show In Explorer - Will open an explorer window at the asset package location. +* Log Package Information - Useful debug information about the package. +* Log Archive Status - Will output to console window the status of the package if its been archived and what versions. + +* Show Internet Browser + * View Asset + Will open the Unity Asset Store page for this asset in your default Internet Browser. + + * View Publisher + Will open the Unity Asset Store page for this publisher in your default Internet Browser. + + * View Category + Will open the Unity Asset Store page for this category of asset in your default Internet Browser. + +* Show Asset Store Tab + * View Asset + Will open the Unity Asset Store for this asset in an Editor tab. + + * View Publisher + Will open the Unity Asset Store page for this publisher in an Editor tab. + + * View Category + Will open the Unity Asset Store page for this category of asset in an Editor tab. + + +## Updates + None + + +## Forum Page + TBD + + +## System Requirements +Unity 5.6.7f1+ + +## License + +[MIT](LICENSE.md) diff --git a/Screenshots/OrganizerEditor000.png b/Screenshots/OrganizerEditor000.png new file mode 100644 index 0000000000000000000000000000000000000000..79a37d83d141eb4d6c8f6d5cbd9dd9eb6902af19 GIT binary patch literal 138585 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 ub< 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¥# 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%0DI1##kaRoCb@Ha)8|G2$fsE^>`$=zeVFZXf;3L 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⪙76g(wzscxId(^f>uWP7YhUqd=0!VWfF^+Q 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