├── .gitmodules ├── CHANGELOG.md ├── CHANGELOG.md.meta ├── Demo.meta ├── Demo ├── AnimationTriggers.cs ├── AnimationTriggers.cs.meta ├── Animations.meta ├── Animations │ ├── CameraMovements.anim │ ├── CameraMovements.anim.meta │ ├── CameraMovements2.anim │ ├── CameraMovements2.anim.meta │ ├── Canvas.controller │ ├── Canvas.controller.meta │ ├── Main Camera.controller │ ├── Main Camera.controller.meta │ ├── TransitionIn.anim │ ├── TransitionIn.anim.meta │ ├── TransitionOut.anim │ └── TransitionOut.anim.meta ├── DEMO README.md ├── DEMO README.md.meta ├── InitSceneLoading.cs ├── InitSceneLoading.cs.meta ├── Materials.meta ├── Materials │ ├── Blue.mat │ ├── Blue.mat.meta │ ├── Brown.mat │ ├── Brown.mat.meta │ ├── Green.mat │ └── Green.mat.meta ├── MultiSceneToolsDemo.asmdef ├── MultiSceneToolsDemo.asmdef.meta ├── SceneCollections.meta ├── SceneCollections │ ├── DemoCollection Load.asset │ ├── DemoCollection Load.asset.meta │ ├── DemoCollection Start.asset │ ├── DemoCollection Start.asset.meta │ ├── DemoCollection Transition.asset │ └── DemoCollection Transition.asset.meta ├── SceneTransition.cs ├── SceneTransition.cs.meta ├── SceneTransition_Editor.cs ├── SceneTransition_Editor.cs.meta ├── Scenes.meta ├── Scenes │ ├── BuildingScene.unity │ ├── BuildingScene.unity.meta │ ├── CameraScene.unity │ ├── CameraScene.unity.meta │ ├── DemoAwake.unity │ ├── DemoAwake.unity.meta │ ├── DemoStart.unity │ ├── DemoStart.unity.meta │ ├── InsideScene.unity │ ├── InsideScene.unity.meta │ ├── OutsideScene.unity │ ├── OutsideScene.unity.meta │ ├── TransitionCanvas.unity │ └── TransitionCanvas.unity.meta ├── TriggerSceneLoad.cs └── TriggerSceneLoad.cs.meta ├── Editor.meta ├── Editor ├── ActiveScene_PropertyDrawer.cs ├── ActiveScene_PropertyDrawer.cs.meta ├── CreateCollectionShortcut.cs ├── CreateCollectionShortcut.cs.meta ├── MultiSceneToolsConfig_Editor.cs ├── MultiSceneToolsConfig_Editor.cs.meta ├── MultiSceneToolsEditor.asmdef ├── MultiSceneToolsEditor.asmdef.meta ├── MultiSceneToolsEditorExtension.cs ├── MultiSceneToolsEditorExtension.cs.meta ├── MultiSceneToolsHierarchyStyle_Editor.cs ├── MultiSceneToolsHierarchyStyle_Editor.cs.meta ├── MultiSceneToolsMenuItems.cs ├── MultiSceneToolsMenuItems.cs.meta ├── MultiSceneToolsSetup_Wizard.cs ├── MultiSceneToolsSetup_Wizard.cs.meta ├── MultiSceneToolsStartup.cs ├── MultiSceneToolsStartup.cs.meta ├── SceneCollection_Editor.cs ├── SceneCollection_Editor.cs.meta ├── SceneManager_EditorWindow.cs ├── SceneManager_EditorWindow.cs.meta ├── TextureLoader_Editor.cs └── TextureLoader_Editor.cs.meta ├── INSTALLATION GUIDE.pdf ├── INSTALLATION GUIDE.pdf.meta ├── Images.meta ├── Images ├── MultiSceneTools Icon.png ├── MultiSceneTools Icon.png.meta ├── addativeCollectionIcon.png ├── addativeCollectionIcon.png.meta ├── false-Icon.png ├── false-Icon.png.meta ├── true-Icon.png └── true-Icon.png.meta ├── README.md ├── README.md.meta ├── Runtime.meta ├── Runtime ├── AsyncCollection.cs ├── AsyncCollection.cs.meta ├── Internal.meta ├── Internal │ ├── ActiveScene.cs │ └── ActiveScene.cs.meta ├── MultiSceneAsyncLoading.cs ├── MultiSceneAsyncLoading.cs.meta ├── MultiSceneLoader.cs ├── MultiSceneLoader.cs.meta ├── MultiSceneLoading.cs ├── MultiSceneLoading.cs.meta ├── MultiSceneTools.asmdef ├── MultiSceneTools.asmdef.meta ├── MultiSceneToolsConfig.cs ├── MultiSceneToolsConfig.cs.meta ├── SceneCollection.cs └── SceneCollection.cs.meta ├── Scenes.meta ├── Scenes ├── EmptyScene.unity └── EmptyScene.unity.meta ├── package.json └── package.json.meta /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Packages/UniTask"] 2 | path = Packages/UniTask 3 | url = https://github.com/Cysharp/UniTask.git 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Version 1.0.2 - 08/05/25 2 | - Fixed null argument error when no collection is loaded 3 | - Added missing demo script 4 | 5 | # Version 1.0.1 - 07/05/25 6 | - Fixed unexpected installation location issues with the asset store. 7 | - Added new setup option: installation path. moves the package to the desired path, supports automatic placement in packages folder. (I dont know how this works with detecting updates via the package manager yet) 8 | - Fixed loading scenes through the scene manager window to register correctly in the config. 9 | - Fixed internal variable for the active scene index not saving after being edited. 10 | - Fixed SceneCollections not being set to currently loaded from calling SceneCollection.LoadCollection() 11 | - Fixed several issues with "Save Open Collection" button in the scene manager window. 12 | 13 | Observed issues: 14 | - Invisible extra editor windows opened automatically when attempting to open the setup wizard during updates. 15 | The issue disappeared by its own. If it shows up again then please report it. 16 | 17 | # Version 1.0.0 - 26/04/25 18 | - Fixed Active scene index not updating correctly 19 | - Fixed Active Scene index throwing errors when the collection's scene array changed in certain cases. 20 | - Added demo 21 | - Changed Icons and branding 22 | - Added add all collections to build settings menu item 23 | 24 | # Version 0.4.2-6 - 10/12/2024 25 | - Fixed loadCollectionMode.Replace attempting to unload scenes that was already unloaded by single loading. 26 | - Fixed attempting to unload collections with no scenes in them. 27 | - Fixed loading methods not setting allowSceneActivation correctly 28 | - Fixed removing loaded collection on open single scenes 29 | 30 | # Version 0.4.1 - 06/12/2024 31 | - Fixed issue with Async LoadCollectionMode.Replace not correctly replacing all scenes 32 | 33 | # Version 0.4.0 - 15/10/2024 34 | - Added async loading 35 | - Added AsyncCollection for ease of use to track the loading state of the collection 36 | - options for manually enabling scenes once they are done loading / waiting to unload scenes after loading 37 | - Refactored additive loading 38 | - Added experimental subtractive loading mode (not implemented for async) 39 | 40 | # Version 0.3.5 - 16/10/2023 41 | 42 | - Added hierarchy info from the loaded collection. 43 | - Shows which loaded scenes are in a collection with a tooltip on which it belongs to 44 | - User defined collection color, which is displayed over the scene 45 | - Confirmation the scene has been added to build settings 46 | - shows which scene will be set as the active scene when loaded 47 | - Fixed bug with active scene index being reset to -1 every other time a change is made in the collection. 48 | 49 | # Version 0.3.4 - 12/10/2023 50 | 51 | - Fixed bug: Setting active scene now waits until the scene is loaded. 52 | 53 | # Version 0.3.3 - 11/10/2023 54 | 55 | - Added option for setting an active scene automatically when loading a collection (setting in the collection itself) 56 | - Added visual feedback of which scenes are in the build settings from the scene list in collections 57 | - Clicking the red X adds the scene to the build settings. 58 | - Added a menu item to create shortcuts to load collection for the menu bar. 59 | 60 | # Version 0.3.2 - 06/10/2023 61 | 62 | - Added dialogue popup when attempting to load a collection with unsaved scene changes. 63 | 64 | # Version 0.3.1 - 13/09/2023 65 | 66 | - Fixed trying to find currently open scenes when there is no config in the project, resulting in errors on first time setup. 67 | - Fixed Version number not being saved in the config 68 | - Changed the Scene Manager window name to "Multi Scene Manager" 69 | - Moved the menu items into Tools/MultiSceneTools/... 70 | 71 | # Version 0.3.0 - 28/05/2023 72 | 73 | - Refactored config instance and initialization 74 | - Boot Loader example is now deprecated. 75 | - Refactored Scene Collection creation. 76 | - Known issue: Duplication is not working as intended. 77 | - Added setup window that automatically opens on install and updates to confirm new settings. 78 | - Has option to not show again 79 | - Added menu new menu items 80 | - Changelog 81 | - Reload Project Collections 82 | - Fixed bugs with loading without boot scene 83 | - Fixed issues relating to new way to manage the boot scene. 84 | - Fixed bugs when unloading a collection with a single or no scenes. 85 | - Updated the editor script for the config to add undo's to the toggles. 86 | - Changed the default config asset path 87 | - Made editor assembly only compile on Unity Editor platform. 88 | - Apache 2.0 License 89 | 90 | # Version 0.2.6 - 28/02/2023 91 | 92 | - Made some object fields read only 93 | - Added automatic detection of collections that are open when no collection has been loaded manually. i.e: Automatically detect what collection was open in the previous editor session. 94 | - fixed the scene manager window not loading when opening the project/swapping layouts. 95 | - fixed some smaller bugs and improved some code. 96 | 97 | # Version 0.2.5 - ??/??/20?? 98 | 99 | - Step 1. Look at code 100 | - Step 2. Develop 101 | - Step 3. Forget you did anything 102 | - Step 4. Progress 103 | - Step ?. ??????? 104 | 105 | # Version 0.2.4 - 18/11/2022 106 | 107 | - Fixed issue with config editor script always resetting the paths to default values. 108 | 109 | # Version 0.2.4 - 17/11/2022 110 | 111 | - Fixed issue with config instance not being set when booting 112 | 113 | # Version 0.2.3 - 16/11/2022 114 | 115 | - Made OnSceneLoad public and accessible 116 | - Changed name of OnSceneLoad -> OnSceneCollectionLoaded 117 | - Added another event (OnSceneCollectionLoadDebug), now there is two. one which outputs the scene collection data and one void. 118 | 119 | # Version 0.2.2 - 14/11/2022 120 | 121 | - Fixed scene selection field in the scene manager window 122 | 123 | # Version 0.2.1 - 14/11/2022 124 | 125 | - Re arranged SceneManager window 126 | - Refactored MultiSceneToolsConfig 127 | - Refactored MultiSceneLoader.loadDifference() 128 | - Added optional parameter to keep boot scene when unloading scenes. 129 | - Added MultiSceneLoader.loadAdditive() 130 | - Added MultiSceneLoader.OnSceneLoad 131 | - use OnSceneLoadAddMethod(UnityAction unityAction) to add an action 132 | - Added config setting: allowing cross scene references 133 | - Added config setting: toggle OnSceneLoad logging 134 | - Added config setting: SceneCollection Load path 135 | - Added config setting: Boot scene path 136 | 137 | # Version 0.1.0 138 | 139 | - Initial Upload 140 | -------------------------------------------------------------------------------- /CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 031a1ad57bfbcc646a9508e5e52ed074 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Demo.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2955f51975d37d7479929c2de525e026 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Demo/AnimationTriggers.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace HH.MultiSceneTools.Demo 6 | { 7 | public class AnimationTriggers : MonoBehaviour 8 | { 9 | void Update() 10 | { 11 | if(Input.GetKeyDown(KeyCode.Space)) 12 | { 13 | GetComponent().SetTrigger("PlayAnimation"); 14 | } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Demo/AnimationTriggers.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 866ec607a7d08324f88a995e822aa9b9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Demo/Animations.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d8f6aad31b57a1b458e99ccfd1524a2f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Demo/Animations/CameraMovements.anim.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 984f3e1f9ce7fdf41b23d8503f28cd92 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 7400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Demo/Animations/CameraMovements2.anim.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d5f463b1ab33b8e44aba87a8bcccdbbc 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 7400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Demo/Animations/Canvas.controller: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1107 &-6046870228823002239 4 | AnimatorStateMachine: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 1 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Base Layer 11 | m_ChildStates: 12 | - serializedVersion: 1 13 | m_State: {fileID: 8651843324446373611} 14 | m_Position: {x: 20, y: 240, z: 0} 15 | - serializedVersion: 1 16 | m_State: {fileID: 6701322182254941338} 17 | m_Position: {x: 260, y: 240, z: 0} 18 | - serializedVersion: 1 19 | m_State: {fileID: 426853536227650280} 20 | m_Position: {x: 160, y: 170, z: 0} 21 | m_ChildStateMachines: [] 22 | m_AnyStateTransitions: [] 23 | m_EntryTransitions: [] 24 | m_StateMachineTransitions: {} 25 | m_StateMachineBehaviours: [] 26 | m_AnyStatePosition: {x: 50, y: 20, z: 0} 27 | m_EntryPosition: {x: 50, y: 120, z: 0} 28 | m_ExitPosition: {x: 800, y: 120, z: 0} 29 | m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} 30 | m_DefaultState: {fileID: 426853536227650280} 31 | --- !u!91 &9100000 32 | AnimatorController: 33 | m_ObjectHideFlags: 0 34 | m_CorrespondingSourceObject: {fileID: 0} 35 | m_PrefabInstance: {fileID: 0} 36 | m_PrefabAsset: {fileID: 0} 37 | m_Name: Canvas 38 | serializedVersion: 5 39 | m_AnimatorParameters: [] 40 | m_AnimatorLayers: 41 | - serializedVersion: 5 42 | m_Name: Base Layer 43 | m_StateMachine: {fileID: -6046870228823002239} 44 | m_Mask: {fileID: 0} 45 | m_Motions: [] 46 | m_Behaviours: [] 47 | m_BlendingMode: 0 48 | m_SyncedLayerIndex: -1 49 | m_DefaultWeight: 0 50 | m_IKPass: 0 51 | m_SyncedLayerAffectsTiming: 0 52 | m_Controller: {fileID: 9100000} 53 | --- !u!1102 &426853536227650280 54 | AnimatorState: 55 | serializedVersion: 6 56 | m_ObjectHideFlags: 1 57 | m_CorrespondingSourceObject: {fileID: 0} 58 | m_PrefabInstance: {fileID: 0} 59 | m_PrefabAsset: {fileID: 0} 60 | m_Name: No anim 61 | m_Speed: 1 62 | m_CycleOffset: 0 63 | m_Transitions: [] 64 | m_StateMachineBehaviours: [] 65 | m_Position: {x: 50, y: 50, z: 0} 66 | m_IKOnFeet: 0 67 | m_WriteDefaultValues: 1 68 | m_Mirror: 0 69 | m_SpeedParameterActive: 0 70 | m_MirrorParameterActive: 0 71 | m_CycleOffsetParameterActive: 0 72 | m_TimeParameterActive: 0 73 | m_Motion: {fileID: 0} 74 | m_Tag: 75 | m_SpeedParameter: 76 | m_MirrorParameter: 77 | m_CycleOffsetParameter: 78 | m_TimeParameter: 79 | --- !u!1102 &6701322182254941338 80 | AnimatorState: 81 | serializedVersion: 6 82 | m_ObjectHideFlags: 1 83 | m_CorrespondingSourceObject: {fileID: 0} 84 | m_PrefabInstance: {fileID: 0} 85 | m_PrefabAsset: {fileID: 0} 86 | m_Name: Transition_OUT 87 | m_Speed: 1 88 | m_CycleOffset: 0 89 | m_Transitions: [] 90 | m_StateMachineBehaviours: [] 91 | m_Position: {x: 50, y: 50, z: 0} 92 | m_IKOnFeet: 0 93 | m_WriteDefaultValues: 0 94 | m_Mirror: 0 95 | m_SpeedParameterActive: 0 96 | m_MirrorParameterActive: 0 97 | m_CycleOffsetParameterActive: 0 98 | m_TimeParameterActive: 0 99 | m_Motion: {fileID: 7400000, guid: 542304d90b960b94994ed701450e1a11, type: 2} 100 | m_Tag: 101 | m_SpeedParameter: 102 | m_MirrorParameter: 103 | m_CycleOffsetParameter: 104 | m_TimeParameter: 105 | --- !u!1102 &8651843324446373611 106 | AnimatorState: 107 | serializedVersion: 6 108 | m_ObjectHideFlags: 1 109 | m_CorrespondingSourceObject: {fileID: 0} 110 | m_PrefabInstance: {fileID: 0} 111 | m_PrefabAsset: {fileID: 0} 112 | m_Name: Transition_IN 113 | m_Speed: 1 114 | m_CycleOffset: 0 115 | m_Transitions: [] 116 | m_StateMachineBehaviours: [] 117 | m_Position: {x: 50, y: 50, z: 0} 118 | m_IKOnFeet: 0 119 | m_WriteDefaultValues: 0 120 | m_Mirror: 0 121 | m_SpeedParameterActive: 0 122 | m_MirrorParameterActive: 0 123 | m_CycleOffsetParameterActive: 0 124 | m_TimeParameterActive: 0 125 | m_Motion: {fileID: 7400000, guid: 673c79c490d42f1488c6567d5ca793c9, type: 2} 126 | m_Tag: 127 | m_SpeedParameter: 128 | m_MirrorParameter: 129 | m_CycleOffsetParameter: 130 | m_TimeParameter: 131 | -------------------------------------------------------------------------------- /Demo/Animations/Canvas.controller.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fa4ca91639c625f418ce72ec2c4e07da 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 9100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Demo/Animations/Main Camera.controller: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1102 &-8358839027771003488 4 | AnimatorState: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 1 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Move Inside 11 | m_Speed: 1 12 | m_CycleOffset: 0 13 | m_Transitions: 14 | - {fileID: -2673121638762128036} 15 | m_StateMachineBehaviours: [] 16 | m_Position: {x: 50, y: 50, z: 0} 17 | m_IKOnFeet: 0 18 | m_WriteDefaultValues: 1 19 | m_Mirror: 0 20 | m_SpeedParameterActive: 0 21 | m_MirrorParameterActive: 0 22 | m_CycleOffsetParameterActive: 0 23 | m_TimeParameterActive: 0 24 | m_Motion: {fileID: 7400000, guid: 984f3e1f9ce7fdf41b23d8503f28cd92, type: 2} 25 | m_Tag: 26 | m_SpeedParameter: 27 | m_MirrorParameter: 28 | m_CycleOffsetParameter: 29 | m_TimeParameter: 30 | --- !u!1101 &-2673121638762128036 31 | AnimatorStateTransition: 32 | m_ObjectHideFlags: 1 33 | m_CorrespondingSourceObject: {fileID: 0} 34 | m_PrefabInstance: {fileID: 0} 35 | m_PrefabAsset: {fileID: 0} 36 | m_Name: 37 | m_Conditions: 38 | - m_ConditionMode: 1 39 | m_ConditionEvent: PlayAnimation 40 | m_EventTreshold: 0 41 | m_DstStateMachine: {fileID: 0} 42 | m_DstState: {fileID: 1365130559061277606} 43 | m_Solo: 0 44 | m_Mute: 0 45 | m_IsExit: 0 46 | serializedVersion: 3 47 | m_TransitionDuration: 0.25 48 | m_TransitionOffset: 0 49 | m_ExitTime: 0.9517685 50 | m_HasExitTime: 1 51 | m_HasFixedDuration: 1 52 | m_InterruptionSource: 0 53 | m_OrderedInterruption: 1 54 | m_CanTransitionToSelf: 1 55 | --- !u!1101 &-949075268697560196 56 | AnimatorStateTransition: 57 | m_ObjectHideFlags: 1 58 | m_CorrespondingSourceObject: {fileID: 0} 59 | m_PrefabInstance: {fileID: 0} 60 | m_PrefabAsset: {fileID: 0} 61 | m_Name: 62 | m_Conditions: 63 | - m_ConditionMode: 1 64 | m_ConditionEvent: PlayAnimation 65 | m_EventTreshold: 0 66 | m_DstStateMachine: {fileID: 0} 67 | m_DstState: {fileID: -8358839027771003488} 68 | m_Solo: 0 69 | m_Mute: 0 70 | m_IsExit: 0 71 | serializedVersion: 3 72 | m_TransitionDuration: 0.25 73 | m_TransitionOffset: 0 74 | m_ExitTime: 0.9560117 75 | m_HasExitTime: 1 76 | m_HasFixedDuration: 1 77 | m_InterruptionSource: 0 78 | m_OrderedInterruption: 1 79 | m_CanTransitionToSelf: 1 80 | --- !u!91 &9100000 81 | AnimatorController: 82 | m_ObjectHideFlags: 0 83 | m_CorrespondingSourceObject: {fileID: 0} 84 | m_PrefabInstance: {fileID: 0} 85 | m_PrefabAsset: {fileID: 0} 86 | m_Name: Main Camera 87 | serializedVersion: 5 88 | m_AnimatorParameters: 89 | - m_Name: PlayAnimation 90 | m_Type: 9 91 | m_DefaultFloat: 0 92 | m_DefaultInt: 0 93 | m_DefaultBool: 0 94 | m_Controller: {fileID: 0} 95 | m_AnimatorLayers: 96 | - serializedVersion: 5 97 | m_Name: Base Layer 98 | m_StateMachine: {fileID: 1200915422305564021} 99 | m_Mask: {fileID: 0} 100 | m_Motions: [] 101 | m_Behaviours: [] 102 | m_BlendingMode: 0 103 | m_SyncedLayerIndex: -1 104 | m_DefaultWeight: 0 105 | m_IKPass: 0 106 | m_SyncedLayerAffectsTiming: 0 107 | m_Controller: {fileID: 9100000} 108 | --- !u!1107 &1200915422305564021 109 | AnimatorStateMachine: 110 | serializedVersion: 6 111 | m_ObjectHideFlags: 1 112 | m_CorrespondingSourceObject: {fileID: 0} 113 | m_PrefabInstance: {fileID: 0} 114 | m_PrefabAsset: {fileID: 0} 115 | m_Name: Base Layer 116 | m_ChildStates: 117 | - serializedVersion: 1 118 | m_State: {fileID: -8358839027771003488} 119 | m_Position: {x: 90, y: 220, z: 0} 120 | - serializedVersion: 1 121 | m_State: {fileID: 1365130559061277606} 122 | m_Position: {x: 360, y: 220, z: 0} 123 | - serializedVersion: 1 124 | m_State: {fileID: 3972029123321367267} 125 | m_Position: {x: 140, y: 120, z: 0} 126 | m_ChildStateMachines: [] 127 | m_AnyStateTransitions: [] 128 | m_EntryTransitions: [] 129 | m_StateMachineTransitions: {} 130 | m_StateMachineBehaviours: [] 131 | m_AnyStatePosition: {x: 50, y: 20, z: 0} 132 | m_EntryPosition: {x: -30, y: 110, z: 0} 133 | m_ExitPosition: {x: 800, y: 120, z: 0} 134 | m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} 135 | m_DefaultState: {fileID: 3972029123321367267} 136 | --- !u!1102 &1365130559061277606 137 | AnimatorState: 138 | serializedVersion: 6 139 | m_ObjectHideFlags: 1 140 | m_CorrespondingSourceObject: {fileID: 0} 141 | m_PrefabInstance: {fileID: 0} 142 | m_PrefabAsset: {fileID: 0} 143 | m_Name: Move Outside 144 | m_Speed: 1 145 | m_CycleOffset: 0 146 | m_Transitions: 147 | - {fileID: -949075268697560196} 148 | m_StateMachineBehaviours: [] 149 | m_Position: {x: 50, y: 50, z: 0} 150 | m_IKOnFeet: 0 151 | m_WriteDefaultValues: 1 152 | m_Mirror: 0 153 | m_SpeedParameterActive: 0 154 | m_MirrorParameterActive: 0 155 | m_CycleOffsetParameterActive: 0 156 | m_TimeParameterActive: 0 157 | m_Motion: {fileID: 7400000, guid: d5f463b1ab33b8e44aba87a8bcccdbbc, type: 2} 158 | m_Tag: 159 | m_SpeedParameter: 160 | m_MirrorParameter: 161 | m_CycleOffsetParameter: 162 | m_TimeParameter: 163 | --- !u!1101 &2924315575567538165 164 | AnimatorStateTransition: 165 | m_ObjectHideFlags: 1 166 | m_CorrespondingSourceObject: {fileID: 0} 167 | m_PrefabInstance: {fileID: 0} 168 | m_PrefabAsset: {fileID: 0} 169 | m_Name: 170 | m_Conditions: 171 | - m_ConditionMode: 1 172 | m_ConditionEvent: PlayAnimation 173 | m_EventTreshold: 0 174 | m_DstStateMachine: {fileID: 0} 175 | m_DstState: {fileID: -8358839027771003488} 176 | m_Solo: 0 177 | m_Mute: 0 178 | m_IsExit: 0 179 | serializedVersion: 3 180 | m_TransitionDuration: 0.25 181 | m_TransitionOffset: 0 182 | m_ExitTime: 0.75 183 | m_HasExitTime: 1 184 | m_HasFixedDuration: 1 185 | m_InterruptionSource: 0 186 | m_OrderedInterruption: 1 187 | m_CanTransitionToSelf: 1 188 | --- !u!1102 &3972029123321367267 189 | AnimatorState: 190 | serializedVersion: 6 191 | m_ObjectHideFlags: 1 192 | m_CorrespondingSourceObject: {fileID: 0} 193 | m_PrefabInstance: {fileID: 0} 194 | m_PrefabAsset: {fileID: 0} 195 | m_Name: Waiting 196 | m_Speed: 1 197 | m_CycleOffset: 0 198 | m_Transitions: 199 | - {fileID: 2924315575567538165} 200 | m_StateMachineBehaviours: [] 201 | m_Position: {x: 50, y: 50, z: 0} 202 | m_IKOnFeet: 0 203 | m_WriteDefaultValues: 1 204 | m_Mirror: 0 205 | m_SpeedParameterActive: 0 206 | m_MirrorParameterActive: 0 207 | m_CycleOffsetParameterActive: 0 208 | m_TimeParameterActive: 0 209 | m_Motion: {fileID: 0} 210 | m_Tag: 211 | m_SpeedParameter: 212 | m_MirrorParameter: 213 | m_CycleOffsetParameter: 214 | m_TimeParameter: 215 | -------------------------------------------------------------------------------- /Demo/Animations/Main Camera.controller.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c29446ff1531d0f4f9a387e55338d159 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 9100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Demo/Animations/TransitionIn.anim: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!74 &7400000 4 | AnimationClip: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_Name: TransitionIn 10 | serializedVersion: 6 11 | m_Legacy: 0 12 | m_Compressed: 0 13 | m_UseHighQualityCurve: 1 14 | m_RotationCurves: [] 15 | m_CompressedRotationCurves: [] 16 | m_EulerCurves: [] 17 | m_PositionCurves: [] 18 | m_ScaleCurves: [] 19 | m_FloatCurves: 20 | - curve: 21 | serializedVersion: 2 22 | m_Curve: 23 | - serializedVersion: 3 24 | time: 0 25 | value: 461 26 | inSlope: 0 27 | outSlope: 0 28 | tangentMode: 136 29 | weightedMode: 0 30 | inWeight: 0.33333334 31 | outWeight: 0.33333334 32 | - serializedVersion: 3 33 | time: 0.5 34 | value: 0 35 | inSlope: 0 36 | outSlope: 0 37 | tangentMode: 136 38 | weightedMode: 0 39 | inWeight: 0.33333334 40 | outWeight: 0.33333334 41 | m_PreInfinity: 2 42 | m_PostInfinity: 2 43 | m_RotationOrder: 4 44 | attribute: m_AnchoredPosition.y 45 | path: Transition 46 | classID: 224 47 | script: {fileID: 0} 48 | - curve: 49 | serializedVersion: 2 50 | m_Curve: 51 | - serializedVersion: 3 52 | time: 0 53 | value: 0 54 | inSlope: 59.87868 55 | outSlope: 59.87868 56 | tangentMode: 0 57 | weightedMode: 0 58 | inWeight: 0.33333334 59 | outWeight: 0.14410087 60 | - serializedVersion: 3 61 | time: 0.5 62 | value: 0 63 | inSlope: 0 64 | outSlope: 0 65 | tangentMode: 136 66 | weightedMode: 0 67 | inWeight: 0.33333334 68 | outWeight: 0.33333334 69 | m_PreInfinity: 2 70 | m_PostInfinity: 2 71 | m_RotationOrder: 4 72 | attribute: m_SizeDelta.y 73 | path: Transition 74 | classID: 224 75 | script: {fileID: 0} 76 | m_PPtrCurves: [] 77 | m_SampleRate: 60 78 | m_WrapMode: 0 79 | m_Bounds: 80 | m_Center: {x: 0, y: 0, z: 0} 81 | m_Extent: {x: 0, y: 0, z: 0} 82 | m_ClipBindingConstant: 83 | genericBindings: 84 | - serializedVersion: 2 85 | path: 3091768458 86 | attribute: 538195251 87 | script: {fileID: 0} 88 | typeID: 224 89 | customType: 28 90 | isPPtrCurve: 0 91 | - serializedVersion: 2 92 | path: 3091768458 93 | attribute: 38095219 94 | script: {fileID: 0} 95 | typeID: 224 96 | customType: 28 97 | isPPtrCurve: 0 98 | pptrCurveMapping: [] 99 | m_AnimationClipSettings: 100 | serializedVersion: 2 101 | m_AdditiveReferencePoseClip: {fileID: 0} 102 | m_AdditiveReferencePoseTime: 0 103 | m_StartTime: 0 104 | m_StopTime: 0.5 105 | m_OrientationOffsetY: 0 106 | m_Level: 0 107 | m_CycleOffset: 0 108 | m_HasAdditiveReferencePose: 0 109 | m_LoopTime: 0 110 | m_LoopBlend: 0 111 | m_LoopBlendOrientation: 0 112 | m_LoopBlendPositionY: 0 113 | m_LoopBlendPositionXZ: 0 114 | m_KeepOriginalOrientation: 0 115 | m_KeepOriginalPositionY: 1 116 | m_KeepOriginalPositionXZ: 0 117 | m_HeightFromFeet: 0 118 | m_Mirror: 0 119 | m_EditorCurves: 120 | - curve: 121 | serializedVersion: 2 122 | m_Curve: 123 | - serializedVersion: 3 124 | time: 0 125 | value: 461 126 | inSlope: 0 127 | outSlope: 0 128 | tangentMode: 136 129 | weightedMode: 0 130 | inWeight: 0.33333334 131 | outWeight: 0.33333334 132 | - serializedVersion: 3 133 | time: 0.5 134 | value: 0 135 | inSlope: 0 136 | outSlope: 0 137 | tangentMode: 136 138 | weightedMode: 0 139 | inWeight: 0.33333334 140 | outWeight: 0.33333334 141 | m_PreInfinity: 2 142 | m_PostInfinity: 2 143 | m_RotationOrder: 4 144 | attribute: m_AnchoredPosition.y 145 | path: Transition 146 | classID: 224 147 | script: {fileID: 0} 148 | - curve: 149 | serializedVersion: 2 150 | m_Curve: 151 | - serializedVersion: 3 152 | time: 0 153 | value: 0 154 | inSlope: 59.87868 155 | outSlope: 59.87868 156 | tangentMode: 0 157 | weightedMode: 0 158 | inWeight: 0.33333334 159 | outWeight: 0.14410087 160 | - serializedVersion: 3 161 | time: 0.5 162 | value: 0 163 | inSlope: 0 164 | outSlope: 0 165 | tangentMode: 136 166 | weightedMode: 0 167 | inWeight: 0.33333334 168 | outWeight: 0.33333334 169 | m_PreInfinity: 2 170 | m_PostInfinity: 2 171 | m_RotationOrder: 4 172 | attribute: m_SizeDelta.y 173 | path: Transition 174 | classID: 224 175 | script: {fileID: 0} 176 | m_EulerEditorCurves: [] 177 | m_HasGenericRootTransform: 0 178 | m_HasMotionFloatCurves: 0 179 | m_Events: [] 180 | -------------------------------------------------------------------------------- /Demo/Animations/TransitionIn.anim.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 673c79c490d42f1488c6567d5ca793c9 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 7400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Demo/Animations/TransitionOut.anim: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!74 &7400000 4 | AnimationClip: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_Name: TransitionOut 10 | serializedVersion: 6 11 | m_Legacy: 0 12 | m_Compressed: 0 13 | m_UseHighQualityCurve: 1 14 | m_RotationCurves: [] 15 | m_CompressedRotationCurves: [] 16 | m_EulerCurves: [] 17 | m_PositionCurves: [] 18 | m_ScaleCurves: [] 19 | m_FloatCurves: 20 | - curve: 21 | serializedVersion: 2 22 | m_Curve: 23 | - serializedVersion: 3 24 | time: 0 25 | value: 0 26 | inSlope: 0 27 | outSlope: 0 28 | tangentMode: 136 29 | weightedMode: 0 30 | inWeight: 0.33333334 31 | outWeight: 0.33333334 32 | - serializedVersion: 3 33 | time: 0.5 34 | value: 461 35 | inSlope: 0 36 | outSlope: 0 37 | tangentMode: 136 38 | weightedMode: 0 39 | inWeight: 0.33333334 40 | outWeight: 0.33333334 41 | m_PreInfinity: 2 42 | m_PostInfinity: 2 43 | m_RotationOrder: 4 44 | attribute: m_AnchoredPosition.y 45 | path: Transition 46 | classID: 224 47 | script: {fileID: 0} 48 | - curve: 49 | serializedVersion: 2 50 | m_Curve: 51 | - serializedVersion: 3 52 | time: 0 53 | value: 0 54 | inSlope: 0 55 | outSlope: 0 56 | tangentMode: 136 57 | weightedMode: 0 58 | inWeight: 0.33333334 59 | outWeight: 0.33333334 60 | - serializedVersion: 3 61 | time: 0.5 62 | value: 0 63 | inSlope: 59.87868 64 | outSlope: 59.87868 65 | tangentMode: 0 66 | weightedMode: 0 67 | inWeight: 0.33333334 68 | outWeight: 0.14410087 69 | m_PreInfinity: 2 70 | m_PostInfinity: 2 71 | m_RotationOrder: 4 72 | attribute: m_SizeDelta.y 73 | path: Transition 74 | classID: 224 75 | script: {fileID: 0} 76 | m_PPtrCurves: [] 77 | m_SampleRate: 60 78 | m_WrapMode: 0 79 | m_Bounds: 80 | m_Center: {x: 0, y: 0, z: 0} 81 | m_Extent: {x: 0, y: 0, z: 0} 82 | m_ClipBindingConstant: 83 | genericBindings: 84 | - serializedVersion: 2 85 | path: 3091768458 86 | attribute: 538195251 87 | script: {fileID: 0} 88 | typeID: 224 89 | customType: 28 90 | isPPtrCurve: 0 91 | - serializedVersion: 2 92 | path: 3091768458 93 | attribute: 38095219 94 | script: {fileID: 0} 95 | typeID: 224 96 | customType: 28 97 | isPPtrCurve: 0 98 | pptrCurveMapping: [] 99 | m_AnimationClipSettings: 100 | serializedVersion: 2 101 | m_AdditiveReferencePoseClip: {fileID: 0} 102 | m_AdditiveReferencePoseTime: 0 103 | m_StartTime: 0 104 | m_StopTime: 0.5 105 | m_OrientationOffsetY: 0 106 | m_Level: 0 107 | m_CycleOffset: 0 108 | m_HasAdditiveReferencePose: 0 109 | m_LoopTime: 0 110 | m_LoopBlend: 0 111 | m_LoopBlendOrientation: 0 112 | m_LoopBlendPositionY: 0 113 | m_LoopBlendPositionXZ: 0 114 | m_KeepOriginalOrientation: 0 115 | m_KeepOriginalPositionY: 1 116 | m_KeepOriginalPositionXZ: 0 117 | m_HeightFromFeet: 0 118 | m_Mirror: 0 119 | m_EditorCurves: 120 | - curve: 121 | serializedVersion: 2 122 | m_Curve: 123 | - serializedVersion: 3 124 | time: 0 125 | value: 0 126 | inSlope: 0 127 | outSlope: 0 128 | tangentMode: 136 129 | weightedMode: 0 130 | inWeight: 0.33333334 131 | outWeight: 0.33333334 132 | - serializedVersion: 3 133 | time: 0.5 134 | value: 461 135 | inSlope: 0 136 | outSlope: 0 137 | tangentMode: 136 138 | weightedMode: 0 139 | inWeight: 0.33333334 140 | outWeight: 0.33333334 141 | m_PreInfinity: 2 142 | m_PostInfinity: 2 143 | m_RotationOrder: 4 144 | attribute: m_AnchoredPosition.y 145 | path: Transition 146 | classID: 224 147 | script: {fileID: 0} 148 | - curve: 149 | serializedVersion: 2 150 | m_Curve: 151 | - serializedVersion: 3 152 | time: 0 153 | value: 0 154 | inSlope: 0 155 | outSlope: 0 156 | tangentMode: 136 157 | weightedMode: 0 158 | inWeight: 0.33333334 159 | outWeight: 0.33333334 160 | - serializedVersion: 3 161 | time: 0.5 162 | value: 0 163 | inSlope: 59.87868 164 | outSlope: 59.87868 165 | tangentMode: 0 166 | weightedMode: 0 167 | inWeight: 0.33333334 168 | outWeight: 0.14410087 169 | m_PreInfinity: 2 170 | m_PostInfinity: 2 171 | m_RotationOrder: 4 172 | attribute: m_SizeDelta.y 173 | path: Transition 174 | classID: 224 175 | script: {fileID: 0} 176 | m_EulerEditorCurves: [] 177 | m_HasGenericRootTransform: 0 178 | m_HasMotionFloatCurves: 0 179 | m_Events: [] 180 | -------------------------------------------------------------------------------- /Demo/Animations/TransitionOut.anim.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 542304d90b960b94994ed701450e1a11 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 7400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Demo/DEMO README.md: -------------------------------------------------------------------------------- 1 | # DEMO README 2 | 3 | This demo is using scene collections to load scenes. For this to work the scenes needs to be added to build settings. 4 | Each Scene Collection detects if the scenes contained within has been added to the build settings. Click the red X to add it to the build settings, or do it manually. 5 | 6 | **For project collections one can use the shortcut under Tools/Multi Scene Tools/Add All Scenes In Collections to Build, this will not work on the demo scenes as they are not in the selected asset folder.** 7 | 8 | Now open any of the desired scene collections within the demo folder, or open the DemoAwake scene by itself. -------------------------------------------------------------------------------- /Demo/DEMO README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 88a42ef0cb4c7874ca1e8d52b6244b7d 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Demo/InitSceneLoading.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | using UnityEngine; 10 | 11 | namespace HH.MultiSceneTools.Demo 12 | { 13 | public class InitSceneLoading : MonoBehaviour 14 | { 15 | [SerializeField] SceneCollection InitInto; 16 | 17 | // Start is called before the first frame update 18 | void Start() 19 | { 20 | MultiSceneLoader.loadCollection(InitInto, LoadCollectionMode.Replace); 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /Demo/InitSceneLoading.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8c27ae466d0f3ba4799f3212603828e4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Demo/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e4994b927efa76d41bc3149b9eb3adf0 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Demo/Materials/Blue.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 8 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Blue 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ValidKeywords: [] 13 | m_InvalidKeywords: [] 14 | m_LightmapFlags: 4 15 | m_EnableInstancingVariants: 0 16 | m_DoubleSidedGI: 0 17 | m_CustomRenderQueue: -1 18 | stringTagMap: {} 19 | disabledShaderPasses: [] 20 | m_SavedProperties: 21 | serializedVersion: 3 22 | m_TexEnvs: 23 | - _BumpMap: 24 | m_Texture: {fileID: 0} 25 | m_Scale: {x: 1, y: 1} 26 | m_Offset: {x: 0, y: 0} 27 | - _DetailAlbedoMap: 28 | m_Texture: {fileID: 0} 29 | m_Scale: {x: 1, y: 1} 30 | m_Offset: {x: 0, y: 0} 31 | - _DetailMask: 32 | m_Texture: {fileID: 0} 33 | m_Scale: {x: 1, y: 1} 34 | m_Offset: {x: 0, y: 0} 35 | - _DetailNormalMap: 36 | m_Texture: {fileID: 0} 37 | m_Scale: {x: 1, y: 1} 38 | m_Offset: {x: 0, y: 0} 39 | - _EmissionMap: 40 | m_Texture: {fileID: 0} 41 | m_Scale: {x: 1, y: 1} 42 | m_Offset: {x: 0, y: 0} 43 | - _MainTex: 44 | m_Texture: {fileID: 0} 45 | m_Scale: {x: 1, y: 1} 46 | m_Offset: {x: 0, y: 0} 47 | - _MetallicGlossMap: 48 | m_Texture: {fileID: 0} 49 | m_Scale: {x: 1, y: 1} 50 | m_Offset: {x: 0, y: 0} 51 | - _OcclusionMap: 52 | m_Texture: {fileID: 0} 53 | m_Scale: {x: 1, y: 1} 54 | m_Offset: {x: 0, y: 0} 55 | - _ParallaxMap: 56 | m_Texture: {fileID: 0} 57 | m_Scale: {x: 1, y: 1} 58 | m_Offset: {x: 0, y: 0} 59 | m_Ints: [] 60 | m_Floats: 61 | - _BumpScale: 1 62 | - _Cutoff: 0.5 63 | - _DetailNormalMapScale: 1 64 | - _DstBlend: 0 65 | - _GlossMapScale: 1 66 | - _Glossiness: 0.5 67 | - _GlossyReflections: 1 68 | - _Metallic: 0 69 | - _Mode: 0 70 | - _OcclusionStrength: 1 71 | - _Parallax: 0.02 72 | - _SmoothnessTextureChannel: 0 73 | - _SpecularHighlights: 1 74 | - _SrcBlend: 1 75 | - _UVSec: 0 76 | - _ZWrite: 1 77 | m_Colors: 78 | - _Color: {r: 0.099430345, g: 0.575428, b: 0.9245283, a: 1} 79 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 80 | m_BuildTextureStacks: [] 81 | -------------------------------------------------------------------------------- /Demo/Materials/Blue.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2515274998020ea43909e52644f6e6b0 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Demo/Materials/Brown.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 8 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Brown 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ValidKeywords: [] 13 | m_InvalidKeywords: [] 14 | m_LightmapFlags: 4 15 | m_EnableInstancingVariants: 0 16 | m_DoubleSidedGI: 0 17 | m_CustomRenderQueue: -1 18 | stringTagMap: {} 19 | disabledShaderPasses: [] 20 | m_SavedProperties: 21 | serializedVersion: 3 22 | m_TexEnvs: 23 | - _BumpMap: 24 | m_Texture: {fileID: 0} 25 | m_Scale: {x: 1, y: 1} 26 | m_Offset: {x: 0, y: 0} 27 | - _DetailAlbedoMap: 28 | m_Texture: {fileID: 0} 29 | m_Scale: {x: 1, y: 1} 30 | m_Offset: {x: 0, y: 0} 31 | - _DetailMask: 32 | m_Texture: {fileID: 0} 33 | m_Scale: {x: 1, y: 1} 34 | m_Offset: {x: 0, y: 0} 35 | - _DetailNormalMap: 36 | m_Texture: {fileID: 0} 37 | m_Scale: {x: 1, y: 1} 38 | m_Offset: {x: 0, y: 0} 39 | - _EmissionMap: 40 | m_Texture: {fileID: 0} 41 | m_Scale: {x: 1, y: 1} 42 | m_Offset: {x: 0, y: 0} 43 | - _MainTex: 44 | m_Texture: {fileID: 0} 45 | m_Scale: {x: 1, y: 1} 46 | m_Offset: {x: 0, y: 0} 47 | - _MetallicGlossMap: 48 | m_Texture: {fileID: 0} 49 | m_Scale: {x: 1, y: 1} 50 | m_Offset: {x: 0, y: 0} 51 | - _OcclusionMap: 52 | m_Texture: {fileID: 0} 53 | m_Scale: {x: 1, y: 1} 54 | m_Offset: {x: 0, y: 0} 55 | - _ParallaxMap: 56 | m_Texture: {fileID: 0} 57 | m_Scale: {x: 1, y: 1} 58 | m_Offset: {x: 0, y: 0} 59 | m_Ints: [] 60 | m_Floats: 61 | - _BumpScale: 1 62 | - _Cutoff: 0.5 63 | - _DetailNormalMapScale: 1 64 | - _DstBlend: 0 65 | - _GlossMapScale: 1 66 | - _Glossiness: 0.5 67 | - _GlossyReflections: 1 68 | - _Metallic: 0 69 | - _Mode: 0 70 | - _OcclusionStrength: 1 71 | - _Parallax: 0.02 72 | - _SmoothnessTextureChannel: 0 73 | - _SpecularHighlights: 1 74 | - _SrcBlend: 1 75 | - _UVSec: 0 76 | - _ZWrite: 1 77 | m_Colors: 78 | - _Color: {r: 0.4056604, g: 0.28538474, b: 0.06658952, a: 1} 79 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 80 | m_BuildTextureStacks: [] 81 | -------------------------------------------------------------------------------- /Demo/Materials/Brown.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f79fda75129811f47a295498d93c8166 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Demo/Materials/Green.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 8 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Green 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ValidKeywords: [] 13 | m_InvalidKeywords: [] 14 | m_LightmapFlags: 4 15 | m_EnableInstancingVariants: 0 16 | m_DoubleSidedGI: 0 17 | m_CustomRenderQueue: -1 18 | stringTagMap: {} 19 | disabledShaderPasses: [] 20 | m_SavedProperties: 21 | serializedVersion: 3 22 | m_TexEnvs: 23 | - _BumpMap: 24 | m_Texture: {fileID: 0} 25 | m_Scale: {x: 1, y: 1} 26 | m_Offset: {x: 0, y: 0} 27 | - _DetailAlbedoMap: 28 | m_Texture: {fileID: 0} 29 | m_Scale: {x: 1, y: 1} 30 | m_Offset: {x: 0, y: 0} 31 | - _DetailMask: 32 | m_Texture: {fileID: 0} 33 | m_Scale: {x: 1, y: 1} 34 | m_Offset: {x: 0, y: 0} 35 | - _DetailNormalMap: 36 | m_Texture: {fileID: 0} 37 | m_Scale: {x: 1, y: 1} 38 | m_Offset: {x: 0, y: 0} 39 | - _EmissionMap: 40 | m_Texture: {fileID: 0} 41 | m_Scale: {x: 1, y: 1} 42 | m_Offset: {x: 0, y: 0} 43 | - _MainTex: 44 | m_Texture: {fileID: 0} 45 | m_Scale: {x: 1, y: 1} 46 | m_Offset: {x: 0, y: 0} 47 | - _MetallicGlossMap: 48 | m_Texture: {fileID: 0} 49 | m_Scale: {x: 1, y: 1} 50 | m_Offset: {x: 0, y: 0} 51 | - _OcclusionMap: 52 | m_Texture: {fileID: 0} 53 | m_Scale: {x: 1, y: 1} 54 | m_Offset: {x: 0, y: 0} 55 | - _ParallaxMap: 56 | m_Texture: {fileID: 0} 57 | m_Scale: {x: 1, y: 1} 58 | m_Offset: {x: 0, y: 0} 59 | m_Ints: [] 60 | m_Floats: 61 | - _BumpScale: 1 62 | - _Cutoff: 0.5 63 | - _DetailNormalMapScale: 1 64 | - _DstBlend: 0 65 | - _GlossMapScale: 1 66 | - _Glossiness: 0.5 67 | - _GlossyReflections: 1 68 | - _Metallic: 0 69 | - _Mode: 0 70 | - _OcclusionStrength: 1 71 | - _Parallax: 0.02 72 | - _SmoothnessTextureChannel: 0 73 | - _SpecularHighlights: 1 74 | - _SrcBlend: 1 75 | - _UVSec: 0 76 | - _ZWrite: 1 77 | m_Colors: 78 | - _Color: {r: 0.08189747, g: 0.4056604, b: 0.099389896, a: 1} 79 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 80 | m_BuildTextureStacks: [] 81 | -------------------------------------------------------------------------------- /Demo/Materials/Green.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 814efa1e674849a4eac70e4ead6e6d35 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Demo/MultiSceneToolsDemo.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MultiSceneToolsDemo", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:3d61be0c52ad2ee409d26dae681f6697" 6 | ], 7 | "includePlatforms": [], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": false, 10 | "overrideReferences": false, 11 | "precompiledReferences": [], 12 | "autoReferenced": true, 13 | "defineConstraints": [], 14 | "versionDefines": [], 15 | "noEngineReferences": false 16 | } -------------------------------------------------------------------------------- /Demo/MultiSceneToolsDemo.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ffa0eb49d2436124086d9edcffa404b0 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Demo/SceneCollections.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cf8da93355f3b714eb99d0adfb673bd4 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Demo/SceneCollections/DemoCollection Load.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 11500000, guid: 8554d268507aaa841afb43e28e84c809, type: 3} 13 | m_Name: DemoCollection Load 14 | m_EditorClassIdentifier: 15 | k__BackingField: Inside Demo 16 | <ActiveSceneIndex>k__BackingField: 2 17 | _SceneNames: 18 | - CameraScene 19 | - BuildingScene 20 | - InsideScene 21 | Scenes: 22 | - TargetScene: {fileID: 102900000, guid: bec0538345339414a8d5342bc8827126, type: 3} 23 | IsActive: 0 24 | wasChanged: 0 25 | - TargetScene: {fileID: 102900000, guid: a82d84f7068e71149a9759523a62af49, type: 3} 26 | IsActive: 0 27 | wasChanged: 0 28 | - TargetScene: {fileID: 102900000, guid: 3402a0c920cef60489e100bf801540d1, type: 3} 29 | IsActive: 1 30 | wasChanged: 0 31 | hierarchyColor: {r: 0.20163757, g: 0.3606665, b: 0.6037736, a: 0.6313726} 32 | -------------------------------------------------------------------------------- /Demo/SceneCollections/DemoCollection Load.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b86d80e2e2d60324f9aa5c527e37c91f 3 | labels: 4 | - MultiSceneTools 5 | - SceneCollection 6 | NativeFormatImporter: 7 | externalObjects: {} 8 | mainObjectFileID: 11400000 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Demo/SceneCollections/DemoCollection Start.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 11500000, guid: 8554d268507aaa841afb43e28e84c809, type: 3} 13 | m_Name: DemoCollection Start 14 | m_EditorClassIdentifier: 15 | <Title>k__BackingField: Outside Demo 16 | <ActiveSceneIndex>k__BackingField: 2 17 | _SceneNames: 18 | - CameraScene 19 | - BuildingScene 20 | - OutsideScene 21 | - TransitionCanvas 22 | Scenes: 23 | - TargetScene: {fileID: 102900000, guid: bec0538345339414a8d5342bc8827126, type: 3} 24 | IsActive: 0 25 | wasChanged: 0 26 | - TargetScene: {fileID: 102900000, guid: a82d84f7068e71149a9759523a62af49, type: 3} 27 | IsActive: 0 28 | wasChanged: 0 29 | - TargetScene: {fileID: 102900000, guid: 4b5116764aa4fd548aab013c4edcea27, type: 3} 30 | IsActive: 1 31 | wasChanged: 0 32 | - TargetScene: {fileID: 102900000, guid: f033cda09a7477e48b5751f96700f453, type: 3} 33 | IsActive: 0 34 | wasChanged: 0 35 | hierarchyColor: {r: 0.14786398, g: 0.6698113, b: 0.22396521, a: 0.5176471} 36 | -------------------------------------------------------------------------------- /Demo/SceneCollections/DemoCollection Start.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 37eef9943e6da4944b22e623c5199e91 3 | labels: 4 | - MultiSceneTools 5 | - SceneCollection 6 | NativeFormatImporter: 7 | externalObjects: {} 8 | mainObjectFileID: 11400000 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Demo/SceneCollections/DemoCollection Transition.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 11500000, guid: 8554d268507aaa841afb43e28e84c809, type: 3} 13 | m_Name: DemoCollection Transition 14 | m_EditorClassIdentifier: 15 | <Title>k__BackingField: Init 16 | <ActiveSceneIndex>k__BackingField: 0 17 | _SceneNames: 18 | - DemoStart 19 | - TransitionCanvas 20 | Scenes: 21 | - TargetScene: {fileID: 102900000, guid: c89544e44d8ba2e459ed709046d21305, type: 3} 22 | IsActive: 1 23 | wasChanged: 0 24 | - TargetScene: {fileID: 102900000, guid: f033cda09a7477e48b5751f96700f453, type: 3} 25 | IsActive: 0 26 | wasChanged: 0 27 | hierarchyColor: {r: 1, g: 0, b: 0, a: 0.5254902} 28 | -------------------------------------------------------------------------------- /Demo/SceneCollections/DemoCollection Transition.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3e173616927d0dc4a8b72a91a709aca0 3 | labels: 4 | - MultiSceneTools 5 | - SceneCollection 6 | NativeFormatImporter: 7 | externalObjects: {} 8 | mainObjectFileID: 11400000 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Demo/SceneTransition.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | using System.Collections; 10 | using UnityEngine; 11 | 12 | namespace HH.MultiSceneTools.Demo 13 | { 14 | public class SceneTransition : MonoBehaviour 15 | { 16 | [field:SerializeField] public string TransitionIN {get; private set;} = "Transition_IN"; 17 | [field:SerializeField] public string TransitionOUT {get; private set;} = "Transition_OUT"; 18 | [SerializeField] Animator TransitionAnim; 19 | [SerializeField] bool isAnimatingIn; 20 | [SerializeField] bool isAnimatingOut; 21 | public bool isTransitioning => isAnimatingIn; 22 | float animTime; 23 | 24 | [SerializeField] AsyncCollection loadingOperation; 25 | 26 | public static SceneTransition Instance { get; private set; } 27 | void Start() 28 | { 29 | if(Instance == null) 30 | { 31 | Instance = this; 32 | } 33 | else 34 | { 35 | Destroy(this); 36 | } 37 | } 38 | 39 | /// <summary>Play animation to transition to a new scene</summary> 40 | /// <param name="TransitionToCollection">Title of the scene collection this should transition to</param> 41 | /// <returns></returns> 42 | public void TransitionScene(SceneCollection TransitionToCollection) 43 | { 44 | StartCoroutine(sceneTransition(TransitionToCollection)); 45 | } 46 | 47 | IEnumerator sceneTransition(SceneCollection TransitionToCollection) 48 | { 49 | isAnimatingIn = false; 50 | isAnimatingOut = false; 51 | 52 | if(!isAnimatingIn && !isAnimatingOut) 53 | { 54 | TransitionAnim.Play(TransitionIN); 55 | isAnimatingIn = true; 56 | } 57 | 58 | while(waitForAnim()) 59 | { 60 | yield return null; 61 | } 62 | isAnimatingIn = false; 63 | animTime = 0; 64 | 65 | if(TransitionToCollection != null) 66 | { 67 | loadingOperation = MultiSceneLoader.loadCollectionAsync(TransitionToCollection, LoadCollectionMode.DifferenceReplace); 68 | 69 | while(!loadingOperation.getIsComplete()) 70 | { 71 | yield return null; 72 | } 73 | TransitionAnim.Play(TransitionOUT); 74 | isAnimatingOut = true; 75 | while(waitForAnim()) 76 | { 77 | yield return null; 78 | } 79 | isAnimatingOut = false; 80 | animTime = 0; 81 | } 82 | else 83 | { 84 | Debug.LogError(this + ": is trying to transition to an invalid SceneCollection\"\""); 85 | } 86 | } 87 | 88 | bool waitForAnim() 89 | { 90 | AnimatorStateInfo info = TransitionAnim.GetCurrentAnimatorStateInfo(0); 91 | if(animTime > info.length) 92 | { 93 | return false; 94 | } 95 | animTime += Time.deltaTime; 96 | return true; 97 | } 98 | } 99 | public enum Transition 100 | { 101 | IN, 102 | OUT 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /Demo/SceneTransition.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 50212e70f8b8ee54b88b6375074879a5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Demo/SceneTransition_Editor.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | using UnityEditor; 10 | using HH.MultiSceneTools.Demo; 11 | 12 | namespace HH.MultiSceneToolsEditor 13 | { 14 | [CustomEditor(typeof(SceneTransition))] 15 | public class SceneTransition_Editor : Editor 16 | { 17 | SceneTransition script; 18 | 19 | private void OnEnable() 20 | { 21 | script = target as SceneTransition; 22 | } 23 | 24 | public override void OnInspectorGUI() 25 | { 26 | base.OnInspectorGUI(); 27 | 28 | 29 | EditorGUILayout.TextField("State Name IN: ", script.TransitionIN, EditorStyles.boldLabel); 30 | EditorGUILayout.TextField("State Name OUT: ", script.TransitionOUT, EditorStyles.boldLabel); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Demo/SceneTransition_Editor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9685667de58f62b4391b56c14e3b23d8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Demo/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 59303d224adb2a84bb9081fe45519a9b 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Demo/Scenes/BuildingScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a82d84f7068e71149a9759523a62af49 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Demo/Scenes/CameraScene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0.18028378, g: 0.22571412, b: 0.30692285, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 12 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_LightingSettings: {fileID: 0} 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | maxJobWorkers: 0 122 | preserveTilesOutsideBounds: 0 123 | debug: 124 | m_Flags: 0 125 | m_NavMeshData: {fileID: 0} 126 | --- !u!1 &690603715 127 | GameObject: 128 | m_ObjectHideFlags: 0 129 | m_CorrespondingSourceObject: {fileID: 0} 130 | m_PrefabInstance: {fileID: 0} 131 | m_PrefabAsset: {fileID: 0} 132 | serializedVersion: 6 133 | m_Component: 134 | - component: {fileID: 690603716} 135 | - component: {fileID: 690603718} 136 | - component: {fileID: 690603717} 137 | m_Layer: 5 138 | m_Name: Input key 139 | m_TagString: Untagged 140 | m_Icon: {fileID: 0} 141 | m_NavMeshLayer: 0 142 | m_StaticEditorFlags: 0 143 | m_IsActive: 1 144 | --- !u!224 &690603716 145 | RectTransform: 146 | m_ObjectHideFlags: 0 147 | m_CorrespondingSourceObject: {fileID: 0} 148 | m_PrefabInstance: {fileID: 0} 149 | m_PrefabAsset: {fileID: 0} 150 | m_GameObject: {fileID: 690603715} 151 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 152 | m_LocalPosition: {x: 0, y: 0, z: 0} 153 | m_LocalScale: {x: 1, y: 1, z: 1} 154 | m_ConstrainProportionsScale: 0 155 | m_Children: [] 156 | m_Father: {fileID: 1847778887} 157 | m_RootOrder: 0 158 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 159 | m_AnchorMin: {x: 0, y: 0} 160 | m_AnchorMax: {x: 1, y: 0} 161 | m_AnchoredPosition: {x: 0, y: 15} 162 | m_SizeDelta: {x: 0, y: 30} 163 | m_Pivot: {x: 0.5, y: 0.5} 164 | --- !u!114 &690603717 165 | MonoBehaviour: 166 | m_ObjectHideFlags: 0 167 | m_CorrespondingSourceObject: {fileID: 0} 168 | m_PrefabInstance: {fileID: 0} 169 | m_PrefabAsset: {fileID: 0} 170 | m_GameObject: {fileID: 690603715} 171 | m_Enabled: 1 172 | m_EditorHideFlags: 0 173 | m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} 174 | m_Name: 175 | m_EditorClassIdentifier: 176 | m_Material: {fileID: 0} 177 | m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} 178 | m_RaycastTarget: 1 179 | m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} 180 | m_Maskable: 1 181 | m_OnCullStateChanged: 182 | m_PersistentCalls: 183 | m_Calls: [] 184 | m_FontData: 185 | m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} 186 | m_FontSize: 14 187 | m_FontStyle: 0 188 | m_BestFit: 1 189 | m_MinSize: 10 190 | m_MaxSize: 40 191 | m_Alignment: 0 192 | m_AlignByGeometry: 0 193 | m_RichText: 1 194 | m_HorizontalOverflow: 0 195 | m_VerticalOverflow: 0 196 | m_LineSpacing: 1 197 | m_Text: Press *space* to load scene collection async 198 | --- !u!222 &690603718 199 | CanvasRenderer: 200 | m_ObjectHideFlags: 0 201 | m_CorrespondingSourceObject: {fileID: 0} 202 | m_PrefabInstance: {fileID: 0} 203 | m_PrefabAsset: {fileID: 0} 204 | m_GameObject: {fileID: 690603715} 205 | m_CullTransparentMesh: 1 206 | --- !u!1 &952968390 207 | GameObject: 208 | m_ObjectHideFlags: 0 209 | m_CorrespondingSourceObject: {fileID: 0} 210 | m_PrefabInstance: {fileID: 0} 211 | m_PrefabAsset: {fileID: 0} 212 | serializedVersion: 6 213 | m_Component: 214 | - component: {fileID: 952968392} 215 | - component: {fileID: 952968391} 216 | m_Layer: 0 217 | m_Name: Directional Light 218 | m_TagString: Untagged 219 | m_Icon: {fileID: 0} 220 | m_NavMeshLayer: 0 221 | m_StaticEditorFlags: 0 222 | m_IsActive: 1 223 | --- !u!108 &952968391 224 | Light: 225 | m_ObjectHideFlags: 0 226 | m_CorrespondingSourceObject: {fileID: 0} 227 | m_PrefabInstance: {fileID: 0} 228 | m_PrefabAsset: {fileID: 0} 229 | m_GameObject: {fileID: 952968390} 230 | m_Enabled: 1 231 | serializedVersion: 10 232 | m_Type: 1 233 | m_Shape: 0 234 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 235 | m_Intensity: 1 236 | m_Range: 10 237 | m_SpotAngle: 30 238 | m_InnerSpotAngle: 21.80208 239 | m_CookieSize: 10 240 | m_Shadows: 241 | m_Type: 2 242 | m_Resolution: -1 243 | m_CustomResolution: -1 244 | m_Strength: 1 245 | m_Bias: 0.05 246 | m_NormalBias: 0.4 247 | m_NearPlane: 0.2 248 | m_CullingMatrixOverride: 249 | e00: 1 250 | e01: 0 251 | e02: 0 252 | e03: 0 253 | e10: 0 254 | e11: 1 255 | e12: 0 256 | e13: 0 257 | e20: 0 258 | e21: 0 259 | e22: 1 260 | e23: 0 261 | e30: 0 262 | e31: 0 263 | e32: 0 264 | e33: 1 265 | m_UseCullingMatrixOverride: 0 266 | m_Cookie: {fileID: 0} 267 | m_DrawHalo: 0 268 | m_Flare: {fileID: 0} 269 | m_RenderMode: 0 270 | m_CullingMask: 271 | serializedVersion: 2 272 | m_Bits: 4294967295 273 | m_RenderingLayerMask: 1 274 | m_Lightmapping: 4 275 | m_LightShadowCasterMode: 0 276 | m_AreaSize: {x: 1, y: 1} 277 | m_BounceIntensity: 1 278 | m_ColorTemperature: 6570 279 | m_UseColorTemperature: 0 280 | m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} 281 | m_UseBoundingSphereOverride: 0 282 | m_UseViewFrustumForShadowCasterCull: 1 283 | m_ShadowRadius: 0 284 | m_ShadowAngle: 0 285 | --- !u!4 &952968392 286 | Transform: 287 | m_ObjectHideFlags: 0 288 | m_CorrespondingSourceObject: {fileID: 0} 289 | m_PrefabInstance: {fileID: 0} 290 | m_PrefabAsset: {fileID: 0} 291 | m_GameObject: {fileID: 952968390} 292 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 293 | m_LocalPosition: {x: 0, y: 3, z: 0} 294 | m_LocalScale: {x: 1, y: 1, z: 1} 295 | m_ConstrainProportionsScale: 0 296 | m_Children: [] 297 | m_Father: {fileID: 0} 298 | m_RootOrder: 1 299 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 300 | --- !u!1 &1805865076 301 | GameObject: 302 | m_ObjectHideFlags: 0 303 | m_CorrespondingSourceObject: {fileID: 0} 304 | m_PrefabInstance: {fileID: 0} 305 | m_PrefabAsset: {fileID: 0} 306 | serializedVersion: 6 307 | m_Component: 308 | - component: {fileID: 1805865079} 309 | - component: {fileID: 1805865078} 310 | - component: {fileID: 1805865077} 311 | - component: {fileID: 1805865080} 312 | - component: {fileID: 1805865081} 313 | - component: {fileID: 1805865082} 314 | m_Layer: 0 315 | m_Name: Main Camera 316 | m_TagString: MainCamera 317 | m_Icon: {fileID: 0} 318 | m_NavMeshLayer: 0 319 | m_StaticEditorFlags: 0 320 | m_IsActive: 1 321 | --- !u!81 &1805865077 322 | AudioListener: 323 | m_ObjectHideFlags: 0 324 | m_CorrespondingSourceObject: {fileID: 0} 325 | m_PrefabInstance: {fileID: 0} 326 | m_PrefabAsset: {fileID: 0} 327 | m_GameObject: {fileID: 1805865076} 328 | m_Enabled: 1 329 | --- !u!20 &1805865078 330 | Camera: 331 | m_ObjectHideFlags: 0 332 | m_CorrespondingSourceObject: {fileID: 0} 333 | m_PrefabInstance: {fileID: 0} 334 | m_PrefabAsset: {fileID: 0} 335 | m_GameObject: {fileID: 1805865076} 336 | m_Enabled: 1 337 | serializedVersion: 2 338 | m_ClearFlags: 1 339 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 340 | m_projectionMatrixMode: 1 341 | m_GateFitMode: 2 342 | m_FOVAxisMode: 0 343 | m_SensorSize: {x: 36, y: 24} 344 | m_LensShift: {x: 0, y: 0} 345 | m_FocalLength: 50 346 | m_NormalizedViewPortRect: 347 | serializedVersion: 2 348 | x: 0 349 | y: 0 350 | width: 1 351 | height: 1 352 | near clip plane: 0.3 353 | far clip plane: 1000 354 | field of view: 60 355 | orthographic: 0 356 | orthographic size: 5 357 | m_Depth: -1 358 | m_CullingMask: 359 | serializedVersion: 2 360 | m_Bits: 4294967295 361 | m_RenderingPath: -1 362 | m_TargetTexture: {fileID: 0} 363 | m_TargetDisplay: 0 364 | m_TargetEye: 3 365 | m_HDR: 1 366 | m_AllowMSAA: 1 367 | m_AllowDynamicResolution: 0 368 | m_ForceIntoRT: 0 369 | m_OcclusionCulling: 1 370 | m_StereoConvergence: 10 371 | m_StereoSeparation: 0.022 372 | --- !u!4 &1805865079 373 | Transform: 374 | m_ObjectHideFlags: 0 375 | m_CorrespondingSourceObject: {fileID: 0} 376 | m_PrefabInstance: {fileID: 0} 377 | m_PrefabAsset: {fileID: 0} 378 | m_GameObject: {fileID: 1805865076} 379 | m_LocalRotation: {x: -0.22739896, y: -0, z: -0, w: 0.9738017} 380 | m_LocalPosition: {x: -0.92, y: 12.44, z: -8.84} 381 | m_LocalScale: {x: 1, y: 1, z: 1} 382 | m_ConstrainProportionsScale: 0 383 | m_Children: [] 384 | m_Father: {fileID: 0} 385 | m_RootOrder: 0 386 | m_LocalEulerAnglesHint: {x: -26.288, y: 0, z: 0} 387 | --- !u!95 &1805865080 388 | Animator: 389 | serializedVersion: 5 390 | m_ObjectHideFlags: 0 391 | m_CorrespondingSourceObject: {fileID: 0} 392 | m_PrefabInstance: {fileID: 0} 393 | m_PrefabAsset: {fileID: 0} 394 | m_GameObject: {fileID: 1805865076} 395 | m_Enabled: 1 396 | m_Avatar: {fileID: 0} 397 | m_Controller: {fileID: 9100000, guid: c29446ff1531d0f4f9a387e55338d159, type: 2} 398 | m_CullingMode: 0 399 | m_UpdateMode: 0 400 | m_ApplyRootMotion: 0 401 | m_LinearVelocityBlending: 0 402 | m_StabilizeFeet: 0 403 | m_WarningMessage: 404 | m_HasTransformHierarchy: 1 405 | m_AllowConstantClipSamplingOptimization: 1 406 | m_KeepAnimatorStateOnDisable: 0 407 | --- !u!114 &1805865081 408 | MonoBehaviour: 409 | m_ObjectHideFlags: 0 410 | m_CorrespondingSourceObject: {fileID: 0} 411 | m_PrefabInstance: {fileID: 0} 412 | m_PrefabAsset: {fileID: 0} 413 | m_GameObject: {fileID: 1805865076} 414 | m_Enabled: 1 415 | m_EditorHideFlags: 0 416 | m_Script: {fileID: 11500000, guid: aafdbb487393414429d8bc5d36607173, type: 3} 417 | m_Name: 418 | m_EditorClassIdentifier: 419 | OutsideCollection: {fileID: 11400000, guid: 37eef9943e6da4944b22e623c5199e91, type: 2} 420 | InsideCollection: {fileID: 11400000, guid: b86d80e2e2d60324f9aa5c527e37c91f, type: 2} 421 | --- !u!114 &1805865082 422 | MonoBehaviour: 423 | m_ObjectHideFlags: 0 424 | m_CorrespondingSourceObject: {fileID: 0} 425 | m_PrefabInstance: {fileID: 0} 426 | m_PrefabAsset: {fileID: 0} 427 | m_GameObject: {fileID: 1805865076} 428 | m_Enabled: 1 429 | m_EditorHideFlags: 0 430 | m_Script: {fileID: 11500000, guid: 866ec607a7d08324f88a995e822aa9b9, type: 3} 431 | m_Name: 432 | m_EditorClassIdentifier: 433 | --- !u!1 &1847778883 434 | GameObject: 435 | m_ObjectHideFlags: 0 436 | m_CorrespondingSourceObject: {fileID: 0} 437 | m_PrefabInstance: {fileID: 0} 438 | m_PrefabAsset: {fileID: 0} 439 | serializedVersion: 6 440 | m_Component: 441 | - component: {fileID: 1847778887} 442 | - component: {fileID: 1847778886} 443 | - component: {fileID: 1847778885} 444 | - component: {fileID: 1847778884} 445 | m_Layer: 5 446 | m_Name: Canvas 447 | m_TagString: Untagged 448 | m_Icon: {fileID: 0} 449 | m_NavMeshLayer: 0 450 | m_StaticEditorFlags: 0 451 | m_IsActive: 1 452 | --- !u!114 &1847778884 453 | MonoBehaviour: 454 | m_ObjectHideFlags: 0 455 | m_CorrespondingSourceObject: {fileID: 0} 456 | m_PrefabInstance: {fileID: 0} 457 | m_PrefabAsset: {fileID: 0} 458 | m_GameObject: {fileID: 1847778883} 459 | m_Enabled: 1 460 | m_EditorHideFlags: 0 461 | m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} 462 | m_Name: 463 | m_EditorClassIdentifier: 464 | m_IgnoreReversedGraphics: 1 465 | m_BlockingObjects: 0 466 | m_BlockingMask: 467 | serializedVersion: 2 468 | m_Bits: 4294967295 469 | --- !u!114 &1847778885 470 | MonoBehaviour: 471 | m_ObjectHideFlags: 0 472 | m_CorrespondingSourceObject: {fileID: 0} 473 | m_PrefabInstance: {fileID: 0} 474 | m_PrefabAsset: {fileID: 0} 475 | m_GameObject: {fileID: 1847778883} 476 | m_Enabled: 1 477 | m_EditorHideFlags: 0 478 | m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} 479 | m_Name: 480 | m_EditorClassIdentifier: 481 | m_UiScaleMode: 0 482 | m_ReferencePixelsPerUnit: 100 483 | m_ScaleFactor: 1 484 | m_ReferenceResolution: {x: 800, y: 600} 485 | m_ScreenMatchMode: 0 486 | m_MatchWidthOrHeight: 0 487 | m_PhysicalUnit: 3 488 | m_FallbackScreenDPI: 96 489 | m_DefaultSpriteDPI: 96 490 | m_DynamicPixelsPerUnit: 1 491 | m_PresetInfoIsWorld: 0 492 | --- !u!223 &1847778886 493 | Canvas: 494 | m_ObjectHideFlags: 0 495 | m_CorrespondingSourceObject: {fileID: 0} 496 | m_PrefabInstance: {fileID: 0} 497 | m_PrefabAsset: {fileID: 0} 498 | m_GameObject: {fileID: 1847778883} 499 | m_Enabled: 1 500 | serializedVersion: 3 501 | m_RenderMode: 1 502 | m_Camera: {fileID: 1805865078} 503 | m_PlaneDistance: 1 504 | m_PixelPerfect: 0 505 | m_ReceivesEvents: 1 506 | m_OverrideSorting: 0 507 | m_OverridePixelPerfect: 0 508 | m_SortingBucketNormalizedSize: 0 509 | m_AdditionalShaderChannelsFlag: 0 510 | m_SortingLayerID: 0 511 | m_SortingOrder: 0 512 | m_TargetDisplay: 0 513 | --- !u!224 &1847778887 514 | RectTransform: 515 | m_ObjectHideFlags: 0 516 | m_CorrespondingSourceObject: {fileID: 0} 517 | m_PrefabInstance: {fileID: 0} 518 | m_PrefabAsset: {fileID: 0} 519 | m_GameObject: {fileID: 1847778883} 520 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 521 | m_LocalPosition: {x: 0, y: 0, z: 0} 522 | m_LocalScale: {x: 0, y: 0, z: 0} 523 | m_ConstrainProportionsScale: 0 524 | m_Children: 525 | - {fileID: 690603716} 526 | m_Father: {fileID: 0} 527 | m_RootOrder: 2 528 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 529 | m_AnchorMin: {x: 0, y: 0} 530 | m_AnchorMax: {x: 0, y: 0} 531 | m_AnchoredPosition: {x: 0, y: 0} 532 | m_SizeDelta: {x: 0, y: 0} 533 | m_Pivot: {x: 0, y: 0} 534 | -------------------------------------------------------------------------------- /Demo/Scenes/CameraScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bec0538345339414a8d5342bc8827126 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Demo/Scenes/DemoAwake.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 12 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_LightingSettings: {fileID: 0} 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | maxJobWorkers: 0 122 | preserveTilesOutsideBounds: 0 123 | debug: 124 | m_Flags: 0 125 | m_NavMeshData: {fileID: 0} 126 | --- !u!1 &1648480467 127 | GameObject: 128 | m_ObjectHideFlags: 0 129 | m_CorrespondingSourceObject: {fileID: 0} 130 | m_PrefabInstance: {fileID: 0} 131 | m_PrefabAsset: {fileID: 0} 132 | serializedVersion: 6 133 | m_Component: 134 | - component: {fileID: 1648480468} 135 | - component: {fileID: 1648480469} 136 | m_Layer: 0 137 | m_Name: Boot 138 | m_TagString: Untagged 139 | m_Icon: {fileID: 0} 140 | m_NavMeshLayer: 0 141 | m_StaticEditorFlags: 0 142 | m_IsActive: 1 143 | --- !u!4 &1648480468 144 | Transform: 145 | m_ObjectHideFlags: 0 146 | m_CorrespondingSourceObject: {fileID: 0} 147 | m_PrefabInstance: {fileID: 0} 148 | m_PrefabAsset: {fileID: 0} 149 | m_GameObject: {fileID: 1648480467} 150 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 151 | m_LocalPosition: {x: -8.2392025, y: 7.8794823, z: 134.51147} 152 | m_LocalScale: {x: 1, y: 1, z: 1} 153 | m_ConstrainProportionsScale: 0 154 | m_Children: [] 155 | m_Father: {fileID: 0} 156 | m_RootOrder: 0 157 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 158 | --- !u!114 &1648480469 159 | MonoBehaviour: 160 | m_ObjectHideFlags: 0 161 | m_CorrespondingSourceObject: {fileID: 0} 162 | m_PrefabInstance: {fileID: 0} 163 | m_PrefabAsset: {fileID: 0} 164 | m_GameObject: {fileID: 1648480467} 165 | m_Enabled: 1 166 | m_EditorHideFlags: 0 167 | m_Script: {fileID: 11500000, guid: 8c27ae466d0f3ba4799f3212603828e4, type: 3} 168 | m_Name: 169 | m_EditorClassIdentifier: 170 | InitInto: {fileID: 11400000, guid: 3e173616927d0dc4a8b72a91a709aca0, type: 2} 171 | -------------------------------------------------------------------------------- /Demo/Scenes/DemoAwake.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c34f0e6345dc0d04faea77b7b516c730 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Demo/Scenes/DemoStart.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c89544e44d8ba2e459ed709046d21305 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Demo/Scenes/InsideScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3402a0c920cef60489e100bf801540d1 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Demo/Scenes/OutsideScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4b5116764aa4fd548aab013c4edcea27 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Demo/Scenes/TransitionCanvas.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0.18028378, g: 0.22571412, b: 0.30692285, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 12 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_LightingSettings: {fileID: 0} 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | maxJobWorkers: 0 122 | preserveTilesOutsideBounds: 0 123 | debug: 124 | m_Flags: 0 125 | m_NavMeshData: {fileID: 0} 126 | --- !u!1 &1728068374 127 | GameObject: 128 | m_ObjectHideFlags: 0 129 | m_CorrespondingSourceObject: {fileID: 0} 130 | m_PrefabInstance: {fileID: 0} 131 | m_PrefabAsset: {fileID: 0} 132 | serializedVersion: 6 133 | m_Component: 134 | - component: {fileID: 1728068379} 135 | - component: {fileID: 1728068378} 136 | - component: {fileID: 1728068377} 137 | - component: {fileID: 1728068376} 138 | - component: {fileID: 1728068375} 139 | m_Layer: 5 140 | m_Name: Canvas 141 | m_TagString: Untagged 142 | m_Icon: {fileID: 0} 143 | m_NavMeshLayer: 0 144 | m_StaticEditorFlags: 0 145 | m_IsActive: 1 146 | --- !u!95 &1728068375 147 | Animator: 148 | serializedVersion: 5 149 | m_ObjectHideFlags: 0 150 | m_CorrespondingSourceObject: {fileID: 0} 151 | m_PrefabInstance: {fileID: 0} 152 | m_PrefabAsset: {fileID: 0} 153 | m_GameObject: {fileID: 1728068374} 154 | m_Enabled: 1 155 | m_Avatar: {fileID: 0} 156 | m_Controller: {fileID: 9100000, guid: fa4ca91639c625f418ce72ec2c4e07da, type: 2} 157 | m_CullingMode: 0 158 | m_UpdateMode: 0 159 | m_ApplyRootMotion: 0 160 | m_LinearVelocityBlending: 0 161 | m_StabilizeFeet: 0 162 | m_WarningMessage: 163 | m_HasTransformHierarchy: 1 164 | m_AllowConstantClipSamplingOptimization: 1 165 | m_KeepAnimatorStateOnDisable: 0 166 | --- !u!114 &1728068376 167 | MonoBehaviour: 168 | m_ObjectHideFlags: 0 169 | m_CorrespondingSourceObject: {fileID: 0} 170 | m_PrefabInstance: {fileID: 0} 171 | m_PrefabAsset: {fileID: 0} 172 | m_GameObject: {fileID: 1728068374} 173 | m_Enabled: 1 174 | m_EditorHideFlags: 0 175 | m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} 176 | m_Name: 177 | m_EditorClassIdentifier: 178 | m_IgnoreReversedGraphics: 1 179 | m_BlockingObjects: 0 180 | m_BlockingMask: 181 | serializedVersion: 2 182 | m_Bits: 4294967295 183 | --- !u!114 &1728068377 184 | MonoBehaviour: 185 | m_ObjectHideFlags: 0 186 | m_CorrespondingSourceObject: {fileID: 0} 187 | m_PrefabInstance: {fileID: 0} 188 | m_PrefabAsset: {fileID: 0} 189 | m_GameObject: {fileID: 1728068374} 190 | m_Enabled: 1 191 | m_EditorHideFlags: 0 192 | m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} 193 | m_Name: 194 | m_EditorClassIdentifier: 195 | m_UiScaleMode: 1 196 | m_ReferencePixelsPerUnit: 100 197 | m_ScaleFactor: 1 198 | m_ReferenceResolution: {x: 800, y: 600} 199 | m_ScreenMatchMode: 0 200 | m_MatchWidthOrHeight: 0 201 | m_PhysicalUnit: 3 202 | m_FallbackScreenDPI: 96 203 | m_DefaultSpriteDPI: 96 204 | m_DynamicPixelsPerUnit: 1 205 | m_PresetInfoIsWorld: 0 206 | --- !u!223 &1728068378 207 | Canvas: 208 | m_ObjectHideFlags: 0 209 | m_CorrespondingSourceObject: {fileID: 0} 210 | m_PrefabInstance: {fileID: 0} 211 | m_PrefabAsset: {fileID: 0} 212 | m_GameObject: {fileID: 1728068374} 213 | m_Enabled: 1 214 | serializedVersion: 3 215 | m_RenderMode: 0 216 | m_Camera: {fileID: 0} 217 | m_PlaneDistance: 100 218 | m_PixelPerfect: 0 219 | m_ReceivesEvents: 1 220 | m_OverrideSorting: 0 221 | m_OverridePixelPerfect: 0 222 | m_SortingBucketNormalizedSize: 0 223 | m_AdditionalShaderChannelsFlag: 0 224 | m_SortingLayerID: 0 225 | m_SortingOrder: 0 226 | m_TargetDisplay: 0 227 | --- !u!224 &1728068379 228 | RectTransform: 229 | m_ObjectHideFlags: 0 230 | m_CorrespondingSourceObject: {fileID: 0} 231 | m_PrefabInstance: {fileID: 0} 232 | m_PrefabAsset: {fileID: 0} 233 | m_GameObject: {fileID: 1728068374} 234 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 235 | m_LocalPosition: {x: 0, y: 0, z: 0} 236 | m_LocalScale: {x: 0, y: 0, z: 0} 237 | m_ConstrainProportionsScale: 0 238 | m_Children: 239 | - {fileID: 1947901114} 240 | m_Father: {fileID: 0} 241 | m_RootOrder: 0 242 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 243 | m_AnchorMin: {x: 0, y: 0} 244 | m_AnchorMax: {x: 0, y: 0} 245 | m_AnchoredPosition: {x: 0, y: 0} 246 | m_SizeDelta: {x: 0, y: 0} 247 | m_Pivot: {x: 0, y: 0} 248 | --- !u!1 &1947901113 249 | GameObject: 250 | m_ObjectHideFlags: 0 251 | m_CorrespondingSourceObject: {fileID: 0} 252 | m_PrefabInstance: {fileID: 0} 253 | m_PrefabAsset: {fileID: 0} 254 | serializedVersion: 6 255 | m_Component: 256 | - component: {fileID: 1947901114} 257 | - component: {fileID: 1947901117} 258 | - component: {fileID: 1947901116} 259 | - component: {fileID: 1947901115} 260 | m_Layer: 5 261 | m_Name: Transition 262 | m_TagString: Untagged 263 | m_Icon: {fileID: 0} 264 | m_NavMeshLayer: 0 265 | m_StaticEditorFlags: 0 266 | m_IsActive: 1 267 | --- !u!224 &1947901114 268 | RectTransform: 269 | m_ObjectHideFlags: 0 270 | m_CorrespondingSourceObject: {fileID: 0} 271 | m_PrefabInstance: {fileID: 0} 272 | m_PrefabAsset: {fileID: 0} 273 | m_GameObject: {fileID: 1947901113} 274 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 275 | m_LocalPosition: {x: 0, y: 0, z: 0} 276 | m_LocalScale: {x: 1, y: 1, z: 1} 277 | m_ConstrainProportionsScale: 0 278 | m_Children: [] 279 | m_Father: {fileID: 1728068379} 280 | m_RootOrder: 0 281 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 282 | m_AnchorMin: {x: 0, y: 0} 283 | m_AnchorMax: {x: 1, y: 1} 284 | m_AnchoredPosition: {x: 0, y: 480.00003} 285 | m_SizeDelta: {x: 0, y: -0.000030517578} 286 | m_Pivot: {x: 0.5, y: 0.5} 287 | --- !u!114 &1947901115 288 | MonoBehaviour: 289 | m_ObjectHideFlags: 0 290 | m_CorrespondingSourceObject: {fileID: 0} 291 | m_PrefabInstance: {fileID: 0} 292 | m_PrefabAsset: {fileID: 0} 293 | m_GameObject: {fileID: 1947901113} 294 | m_Enabled: 1 295 | m_EditorHideFlags: 0 296 | m_Script: {fileID: 11500000, guid: 50212e70f8b8ee54b88b6375074879a5, type: 3} 297 | m_Name: 298 | m_EditorClassIdentifier: 299 | TransitionIN: Transition_IN 300 | TransitionOUT: Transition_OUT 301 | OnTransitionInComplete: 302 | m_PersistentCalls: 303 | m_Calls: [] 304 | OnTransitionOutComplete: 305 | m_PersistentCalls: 306 | m_Calls: [] 307 | TransitionAnim: {fileID: 1728068375} 308 | isAnimatingIn: 0 309 | isAnimatingOut: 0 310 | --- !u!114 &1947901116 311 | MonoBehaviour: 312 | m_ObjectHideFlags: 0 313 | m_CorrespondingSourceObject: {fileID: 0} 314 | m_PrefabInstance: {fileID: 0} 315 | m_PrefabAsset: {fileID: 0} 316 | m_GameObject: {fileID: 1947901113} 317 | m_Enabled: 1 318 | m_EditorHideFlags: 0 319 | m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 320 | m_Name: 321 | m_EditorClassIdentifier: 322 | m_Material: {fileID: 0} 323 | m_Color: {r: 0.15686275, g: 0.15686275, b: 0.15686275, a: 1} 324 | m_RaycastTarget: 1 325 | m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} 326 | m_Maskable: 1 327 | m_OnCullStateChanged: 328 | m_PersistentCalls: 329 | m_Calls: [] 330 | m_Sprite: {fileID: 0} 331 | m_Type: 0 332 | m_PreserveAspect: 0 333 | m_FillCenter: 1 334 | m_FillMethod: 4 335 | m_FillAmount: 1 336 | m_FillClockwise: 1 337 | m_FillOrigin: 0 338 | m_UseSpriteMesh: 0 339 | m_PixelsPerUnitMultiplier: 1 340 | --- !u!222 &1947901117 341 | CanvasRenderer: 342 | m_ObjectHideFlags: 0 343 | m_CorrespondingSourceObject: {fileID: 0} 344 | m_PrefabInstance: {fileID: 0} 345 | m_PrefabAsset: {fileID: 0} 346 | m_GameObject: {fileID: 1947901113} 347 | m_CullTransparentMesh: 1 348 | -------------------------------------------------------------------------------- /Demo/Scenes/TransitionCanvas.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f033cda09a7477e48b5751f96700f453 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Demo/TriggerSceneLoad.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | using UnityEngine; 10 | 11 | namespace HH.MultiSceneTools.Demo 12 | { 13 | public class TriggerSceneLoad : MonoBehaviour 14 | { 15 | [SerializeField] SceneCollection OutsideCollection; 16 | [SerializeField] SceneCollection InsideCollection; 17 | AsyncCollection currentAsyncCollection; 18 | 19 | public void TransitionIntoSceneCollection(SceneCollection collection) 20 | { 21 | SceneTransition.Instance.TransitionScene(collection); 22 | } 23 | 24 | public void LoadFirstScene() 25 | { 26 | MultiSceneLoader.loadCollection(OutsideCollection, LoadCollectionMode.Replace); 27 | } 28 | 29 | public void LoadInsideCollection() 30 | { 31 | currentAsyncCollection = MultiSceneLoader.loadCollectionAsync(InsideCollection, LoadCollectionMode.DifferenceReplace, false, true); 32 | } 33 | 34 | public void LoadOutsideCollection() 35 | { 36 | currentAsyncCollection = MultiSceneLoader.loadCollectionAsync(OutsideCollection, LoadCollectionMode.DifferenceReplace, false, true); 37 | } 38 | 39 | public void UnloadDeferredSceneCollection() 40 | { 41 | currentAsyncCollection.OnComplete.AddListener(() => Debug.Log("complete")); 42 | currentAsyncCollection.UnloadDeferredScenes(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Demo/TriggerSceneLoad.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aafdbb487393414429d8bc5d36607173 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d616e8a0f53ea504ca156794d4b214d7 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/ActiveScene_PropertyDrawer.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | using UnityEditor; 10 | using UnityEngine; 11 | using UnityEngine.SceneManagement; 12 | 13 | namespace HH.MultiSceneToolsEditor 14 | { 15 | // View 16 | // ------------------------------------------------------------------ 17 | // | Checkbox Active | Is in build Check | Object field Scene | 18 | // ------------------------------------------------------------------ 19 | 20 | [CustomPropertyDrawer(typeof(ActiveScene))] 21 | public class ActiveScenePropertyDrawer : PropertyDrawer 22 | { 23 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 24 | { 25 | Texture _Y = PackageTextureLoader.FindTexture(PackageTextureLoader.trueIcon); 26 | Texture _N = PackageTextureLoader.FindTexture(PackageTextureLoader.falseIcon); 27 | 28 | SerializedProperty Scene = property.FindPropertyRelative("TargetScene"); 29 | 30 | Rect Left = position; 31 | Left.width = 15; 32 | 33 | SerializedProperty checkbox = property.FindPropertyRelative("IsActive"); 34 | bool wasActive = checkbox.boolValue; 35 | 36 | bool currentActiveState = GUI.Toggle(Left, checkbox.boolValue, new GUIContent("", "Should this scene be set as the active scene when the collection is loaded?")); 37 | if(currentActiveState != wasActive) 38 | { 39 | SerializedProperty _wasChanged = property.FindPropertyRelative("wasChanged"); 40 | _wasChanged.boolValue = true; 41 | } 42 | 43 | checkbox.boolValue = currentActiveState; 44 | 45 | Rect middle = Left; 46 | middle.x += 25; 47 | middle.height = middle.width; 48 | middle.y += 3; 49 | 50 | SceneAsset _curScene = (SceneAsset)Scene.objectReferenceValue; 51 | 52 | bool inBuild = false; 53 | string path = AssetDatabase.GetAssetPath(_curScene); 54 | int index = SceneUtility.GetBuildIndexByScenePath(path); 55 | 56 | if(index >= 0) 57 | { 58 | inBuild = true; 59 | } 60 | 61 | if(inBuild) 62 | { 63 | GUI.DrawTexture(middle, _Y); 64 | GUI.Label(middle, new GUIContent(" ", "This scene is in the build settings.")); 65 | } 66 | else 67 | { 68 | GUIStyle style = new GUIStyle(); 69 | style.contentOffset = Vector2.zero; 70 | 71 | if(GUI.Button(middle, _N, style)) 72 | { 73 | SceneManager_EditorWindow.AddSceneToBuildSettings(path); 74 | } 75 | GUI.Label(middle, new GUIContent(" ", "Click to add this scene to build settings.")); 76 | } 77 | 78 | GUI.enabled = true; 79 | 80 | Rect right = position; 81 | right.x += 50; 82 | right.width -= 50; 83 | 84 | EditorGUI.ObjectField(right, Scene, new GUIContent("")); 85 | } 86 | 87 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 88 | { 89 | return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /Editor/ActiveScene_PropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4434940a2604f36498dafc16e779a5e6 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/CreateCollectionShortcut.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | using System.IO; 10 | using System.Text; 11 | using UnityEngine; 12 | using HH.MultiSceneTools; 13 | using UnityEditor; 14 | 15 | namespace HH.MultiSceneToolsEditor 16 | { 17 | public static class CreateCollectionShortcut 18 | { 19 | public static readonly string shortcutPath = "Editor/MenuItemCollectionShortcuts.cs"; 20 | 21 | const string shortcutCode = 22 | "\n\n [MenuItem(\"Shortcuts/Load {0} Collection\")]\n static void LoadCollectionShortcut_{0}()\n {{\n SceneCollection ShortcutCollection = AssetDatabase.LoadAssetAtPath<SceneCollection>(\"{1}\");\n ShortcutCollection.LoadCollection();\n }}\n}}\n#endif"; 23 | 24 | const string classCode = 25 | "#if UNITY_EDITOR\nusing UnityEditor;\nusing HH.MultiSceneTools;\nusing HH.MultiSceneToolsEditor;\n\npublic static class MenuItemCollectionShortcuts\n{\n [MenuItem(\"Shortcuts/Find Shortcut Script\")]\n static void LocateShortcutScript()\n {\n Selection.activeObject = AssetDatabase.LoadAssetAtPath<MonoScript>(\"Assets/\" + CreateCollectionShortcut.shortcutPath);\n }\n\n}\n#endif"; 26 | const int seekBy = -9; 27 | 28 | public static void GenerateShortcut() 29 | { 30 | Debug.LogWarning("only adds the first collection"); 31 | SceneCollection TargetCollection = MultiSceneToolsConfig.instance.LoadedCollections[0]; 32 | 33 | string path = Application.dataPath + "/" + shortcutPath; 34 | string CollectionAssetPath = AssetDatabase.GetAssetPath(TargetCollection); 35 | string shortcutName = "Load " + TargetCollection.name + " Collection"; 36 | 37 | if(!Directory.Exists(Application.dataPath + "/Editor")) 38 | { 39 | Directory.CreateDirectory(Application.dataPath + "/Editor"); 40 | } 41 | 42 | FileStream fileStream; 43 | if(File.Exists(path)) 44 | { 45 | using (StreamReader sr = new StreamReader(path)) 46 | { 47 | string contents = sr.ReadToEnd(); 48 | if (contents.Contains(shortcutName)) 49 | { 50 | Debug.Log("A shortcut named " + shortcutName + " already exists"); 51 | sr.Close(); 52 | return; 53 | } 54 | else 55 | { 56 | sr.Close(); 57 | fileStream = File.Open(path, FileMode.Open); 58 | } 59 | } 60 | } 61 | else 62 | { 63 | fileStream = File.Create(path); 64 | byte[] baseClassBytes = Encoding.ASCII.GetBytes(classCode); 65 | fileStream.Write(baseClassBytes, 0, baseClassBytes.Length); 66 | } 67 | 68 | string _GeneratedShortcut = string.Format(shortcutCode, TargetCollection.name, CollectionAssetPath); 69 | Debug.Log("Created Shortcut: _GeneratedShortcut"); 70 | byte[] shortcutBytes = Encoding.ASCII.GetBytes(_GeneratedShortcut); 71 | fileStream.Seek(seekBy, SeekOrigin.End); 72 | fileStream.Write(shortcutBytes, 0, shortcutBytes.Length); 73 | fileStream.Close(); 74 | AssetDatabase.Refresh(); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Editor/CreateCollectionShortcut.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 72f02402b8896de47ac807e94ab1d7f2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/MultiSceneToolsConfig_Editor.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | using UnityEngine; 10 | using UnityEditor; 11 | using HH.MultiSceneTools; 12 | using System.Reflection; 13 | using UnityEngine.SceneManagement; 14 | 15 | namespace HH.MultiSceneToolsEditor 16 | { 17 | [CustomEditor(typeof(MultiSceneToolsConfig))] 18 | public class MultiSceneToolsConfig_Editor : Editor 19 | { 20 | MultiSceneToolsConfig script; 21 | 22 | FieldInfo wizardStartUpField, useBootField; 23 | FieldInfo bootSceneField, targetBootAssetField; 24 | FieldInfo bootPathField, collectionPathField; 25 | SerializedProperty loadedCollectionsProperty, packageInfoProperty, installationPathProperty; 26 | private void OnEnable() 27 | { 28 | script = target as MultiSceneToolsConfig; 29 | wizardStartUpField = MultiSceneToolsEditorExtensions._getBackingField(script, "startWizardOnUpdate"); 30 | useBootField = MultiSceneToolsEditorExtensions._getBackingField(script, "UseBootScene"); 31 | bootPathField = MultiSceneToolsEditorExtensions._getBackingField(script, "_BootScenePath"); 32 | bootSceneField = MultiSceneToolsEditorExtensions._getBackingField(script, "BootScene"); 33 | targetBootAssetField = MultiSceneToolsEditorExtensions._getBackingField(script, "_TargetBootScene"); 34 | collectionPathField = MultiSceneToolsEditorExtensions._getBackingField(script, "_SceneCollectionPath"); 35 | loadedCollectionsProperty = serializedObject.FindProperty("currentLoadedCollection"); 36 | packageInfoProperty = serializedObject.FindProperty("registeredPackageVersion"); 37 | installationPathProperty = serializedObject.FindProperty("packagePath"); 38 | } 39 | 40 | void setDefaultPaths() 41 | { 42 | if(bootPathField.GetValue(script) as string == "") 43 | { 44 | bootPathField.SetValue(script, MultiSceneToolsConfig.bootPathDefault); 45 | } 46 | 47 | if(collectionPathField.GetValue(script) as string == "") 48 | { 49 | collectionPathField.SetValue(script, MultiSceneToolsConfig.collectionsPathDefault); 50 | } 51 | } 52 | 53 | public override void OnInspectorGUI() 54 | { 55 | serializedObject.Update(); 56 | 57 | MultiSceneToolsEditorExtensions.GetPackageManifest(); 58 | 59 | GUILayout.Space(8); 60 | GUILayout.Label("Info", EditorStyles.boldLabel); 61 | 62 | GUI.enabled = false; 63 | EditorGUILayout.TextField(new GUIContent("Version"), packageInfoProperty.stringValue); 64 | 65 | EditorGUILayout.ObjectField("Current Instance", MultiSceneToolsConfig.instance, typeof(MultiSceneToolsConfig), false); 66 | 67 | EditorGUILayout.PropertyField(loadedCollectionsProperty, new GUIContent("Loaded Collections", "All collections loaded in the hierarchy")); 68 | GUI.enabled = true; 69 | 70 | GUILayout.Space(8); 71 | GUILayout.Label("Settings", EditorStyles.boldLabel); 72 | 73 | bool? _CurrentStartUpStateValue = wizardStartUpField.GetValue(script) as bool?; 74 | bool _CurrentStartUpState = _CurrentStartUpStateValue ?? true ? _CurrentStartUpStateValue.Value : false; 75 | bool _newStartupState = EditorGUILayout.Toggle(new GUIContent("Start Wizard On Update"), _CurrentStartUpState); 76 | 77 | if(_newStartupState != _CurrentStartUpState) 78 | { 79 | Undo.RegisterCompleteObjectUndo(target, "MultiSeneTools: Start Wizard On Update = " + _newStartupState); 80 | wizardStartUpField.SetValue(script, _newStartupState); 81 | EditorUtility.SetDirty(script); 82 | } 83 | serializedObject.ApplyModifiedProperties(); // ? not sure why i need another one here but it works 84 | 85 | // Log Scene Changes 86 | bool _CurrentLogScenesState = EditorGUILayout.Toggle( 87 | new GUIContent("Log Scene Changes", "Adds a Debug.log to OnSceneLoad. Output: Loaded Collection, Collection Load Mode"), 88 | script.LogOnSceneChange); 89 | 90 | if(_CurrentLogScenesState != script.LogOnSceneChange) 91 | { 92 | Undo.RegisterCompleteObjectUndo(target, "MultiSeneTools: Log Scene Changes = " + _CurrentLogScenesState); 93 | script.setLogOnSceneChange(_CurrentLogScenesState); 94 | } 95 | 96 | serializedObject.UpdateIfRequiredOrScript(); 97 | 98 | bool? _isUsingBootValue = useBootField.GetValue(script) as bool?; 99 | bool _isUsingBoot = _isUsingBootValue ?? false ? _isUsingBootValue.Value : false; 100 | bool _newUsingBoot = EditorGUILayout.Toggle(new GUIContent("Keep boot-scene loaded", "Requires the boot scene to appear in the boot scene collection"), _isUsingBoot); 101 | if(_newUsingBoot != _isUsingBoot) 102 | { 103 | Undo.RegisterCompleteObjectUndo(target, "MultiSeneTools: Keep Boot Scene Loaded = " + _newUsingBoot); 104 | useBootField.SetValue(script, _newUsingBoot); 105 | EditorUtility.SetDirty(script); 106 | } 107 | 108 | GUI.enabled = false; 109 | EditorGUILayout.ObjectField(new GUIContent("Target Boot Scene", "This the scene located at the boot scene path"), script._TargetBootScene, typeof(SceneAsset), false); 110 | GUI.enabled = true; 111 | GUI.enabled = _isUsingBoot; 112 | 113 | string _CurrentBootPath = bootPathField.GetValue(script) as string; 114 | string _newBootPath = EditorGUILayout.TextField( 115 | new GUIContent("Boot scene Path", "Keep this scene when loading differences. This scene will be loaded if all scenes are unloaded"), 116 | _CurrentBootPath); 117 | if(_newBootPath != _CurrentBootPath) 118 | { 119 | Undo.RegisterCompleteObjectUndo(target, "MultiSeneTools: Boot Scene Path = " + _newBootPath); 120 | bootPathField.SetValue(script, _newBootPath); 121 | targetBootAssetField.SetValue(script, (SceneAsset)AssetDatabase.LoadAssetAtPath(_newBootPath, typeof(SceneAsset))); 122 | bootSceneField.SetValue(script, SceneManager.GetSceneByPath(_newBootPath)); 123 | EditorUtility.SetDirty(script); 124 | } 125 | 126 | GUI.enabled = true; 127 | 128 | string _currentCollectionPath = collectionPathField.GetValue(script) as string; 129 | string _newCollectionPath = EditorGUILayout.TextField( 130 | new GUIContent("Scene Collections Path", "Path where new scene collections will be created and loaded from"), 131 | _currentCollectionPath); 132 | if(_newCollectionPath != _currentCollectionPath) 133 | { 134 | Undo.RegisterCompleteObjectUndo(target, "MultiSeneTools: Scene Collection Path = " + _newCollectionPath); 135 | collectionPathField.SetValue(script, _newCollectionPath); 136 | EditorUtility.SetDirty(script); 137 | } 138 | 139 | GUI.enabled = false; 140 | EditorGUILayout.PropertyField(installationPathProperty, new GUIContent("Package Path", "Path to the package, use the setup to relocate the files or update the location."), true); 141 | GUI.enabled = true; 142 | 143 | if(script.LoadedCollections != null) 144 | { 145 | if(script.LoadedCollections.Count == 0) 146 | { 147 | script.findOpenSceneCollections(); 148 | if(script.LoadedCollections.Count == 0) 149 | { 150 | script.SetCurrentCollectionEmpty(); 151 | } 152 | } 153 | } 154 | 155 | setDefaultPaths(); 156 | serializedObject.ApplyModifiedProperties(); 157 | } 158 | } 159 | } -------------------------------------------------------------------------------- /Editor/MultiSceneToolsConfig_Editor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5ae1289a0c29fae479927d0659735d3c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/MultiSceneToolsEditor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MultiSceneToolsEditor", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:3d61be0c52ad2ee409d26dae681f6697" 6 | ], 7 | "includePlatforms": [ 8 | "Editor" 9 | ], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false, 12 | "overrideReferences": false, 13 | "precompiledReferences": [], 14 | "autoReferenced": true, 15 | "defineConstraints": [], 16 | "versionDefines": [], 17 | "noEngineReferences": false 18 | } -------------------------------------------------------------------------------- /Editor/MultiSceneToolsEditor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d68acc4956ce3f9478c2c3bfbc8eb0f4 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor/MultiSceneToolsEditorExtension.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | using System.Reflection; 10 | using UnityEngine; 11 | using HH.MultiSceneTools; 12 | using System.IO; 13 | 14 | namespace HH.MultiSceneToolsEditor 15 | { 16 | public static class MultiSceneToolsEditorExtensions 17 | { 18 | public static readonly string packageName = "com.henrikhustoft.multi-scene-management-tools-lite"; 19 | public static readonly string packagePath = "Assets/Multi Scene Tools Lite"; 20 | public struct PackageInfo 21 | { 22 | public string name; 23 | public string version; 24 | public string displayName; 25 | public string description; 26 | public string unity; 27 | public string[] keywords; 28 | public Author author; 29 | 30 | public struct Author 31 | { 32 | public string name; 33 | public string url; 34 | } 35 | } 36 | 37 | public static PackageInfo GetPackageManifest() 38 | { 39 | PackageInfo package = new PackageInfo(); 40 | 41 | if(MultiSceneToolsConfig.instance == null) 42 | { 43 | JsonUtility.FromJsonOverwrite(File.ReadAllText(packagePath + "/package.json"), package); 44 | return package; 45 | } 46 | 47 | if(!Directory.Exists(MultiSceneToolsConfig.instance.packagePath)) 48 | { 49 | Debug.LogError("Multi Scene Tools package path is invalid. Please run the setup to update the package."); 50 | 51 | MultiSceneToolsConfig.instance.packagePath = packagePath; 52 | 53 | JsonUtility.FromJsonOverwrite(File.ReadAllText(packagePath + "/package.json"), package); 54 | return package; 55 | } 56 | 57 | package = (PackageInfo)JsonUtility.FromJson(File.ReadAllText(MultiSceneToolsConfig.instance.packagePath + "/package.json"), typeof(PackageInfo)); 58 | return package; 59 | } 60 | 61 | 62 | // public static UnityEditor.PackageManager.PackageInfo GetPackageManifest() 63 | // { 64 | // UnityEditor.PackageManager.PackageInfo package = UnityEditor.PackageManager.PackageInfo.GetAllRegisteredPackages().FirstOrDefault(p => p.name == packageName); 65 | // return package; 66 | // } 67 | 68 | private static PackageInfo _packageInfoCache; 69 | public static PackageInfo packageInfo 70 | { 71 | get 72 | { 73 | if(!_packageInfoCache.Equals(default(PackageInfo))) 74 | { 75 | return _packageInfoCache; 76 | } 77 | else 78 | { 79 | PackageInfo package = GetPackageManifest(); 80 | _packageInfoCache = package; 81 | return _packageInfoCache; 82 | } 83 | } 84 | private set 85 | { 86 | _packageInfoCache = value; 87 | } 88 | } 89 | 90 | private static string _getBackingFieldName(string propertyName) 91 | { 92 | return string.Format("<{0}>k__BackingField", propertyName); 93 | } 94 | 95 | public static FieldInfo _getBackingField(object obj, string propertyName) 96 | { 97 | return obj.GetType().GetField(_getBackingFieldName(propertyName), BindingFlags.Instance | BindingFlags.NonPublic); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Editor/MultiSceneToolsEditorExtension.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: afc1a245d1dd17e45a248bf405d73f74 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/MultiSceneToolsHierarchyStyle_Editor.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | using UnityEngine; 10 | using UnityEngine.SceneManagement; 11 | using UnityEditor; 12 | using UnityEditor.SceneManagement; 13 | using HH.MultiSceneTools; 14 | 15 | namespace HH.MultiSceneToolsEditor 16 | { 17 | static public class MultiSceneToolsHierarchyStyle_Editor 18 | { 19 | static Texture checkMark_Y, checkMark_N, collectionIcon; 20 | static SceneCollection[] Collections; 21 | 22 | [InitializeOnLoadMethod] 23 | static void HookUpDrawer() 24 | { 25 | EditorApplication.hierarchyWindowItemOnGUI -= OnHierarchyWindowItemOnGUI; 26 | EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyWindowItemOnGUI; 27 | } 28 | 29 | private static void OnHierarchyWindowItemOnGUI( int instanceID, Rect selectionRect ) 30 | { 31 | // ? then potentially draw the index as well 32 | if(MultiSceneToolsConfig.instance == null) 33 | { 34 | return; 35 | } 36 | 37 | Collections = MultiSceneToolsConfig.instance.LoadedCollections.ToArray(); 38 | 39 | if(checkMark_N == null) 40 | { 41 | checkMark_Y = PackageTextureLoader.FindTexture(PackageTextureLoader.trueIcon); 42 | checkMark_N = PackageTextureLoader.FindTexture(PackageTextureLoader.falseIcon); 43 | collectionIcon = PackageTextureLoader.FindTexture(PackageTextureLoader.additiveCollectionIcon); 44 | } 45 | 46 | DrawSceneInfo(instanceID, selectionRect); 47 | LoadDraggedCollections(); 48 | } 49 | 50 | static private void LoadDraggedCollections() 51 | { 52 | if (Event.current.type == EventType.DragUpdated || 53 | Event.current.type == EventType.DragExited) 54 | { 55 | DragAndDrop.AcceptDrag(); 56 | Object[] draggedObjects = DragAndDrop.objectReferences; 57 | if (draggedObjects != null && 58 | draggedObjects.Length == 1) 59 | { 60 | if (draggedObjects[0] is SceneCollection _loadCollection) 61 | { 62 | if (Event.current.type == EventType.DragUpdated) 63 | { 64 | DragAndDrop.visualMode = DragAndDropVisualMode.Copy; 65 | } 66 | else if (Event.current.type == EventType.DragExited) 67 | { 68 | _loadCollection.LoadAdditive(); 69 | } 70 | Event.current.Use(); 71 | } 72 | } 73 | } 74 | } 75 | 76 | static private void DrawSceneInfo(int instanceID, Rect selectionRect) 77 | { 78 | if(Collections == null) 79 | { 80 | return; 81 | } 82 | 83 | if(Collections.Length == 0) 84 | { 85 | return; 86 | } 87 | 88 | for (int i = 0; i < Collections.Length; i++) // ! this loop is probably redundant 89 | { 90 | Scene scene = GetSceneFromHandleID(instanceID); 91 | if (!scene.IsValid()) 92 | { 93 | return; 94 | } 95 | 96 | if(Collections[0] == null) 97 | { 98 | return; 99 | } 100 | 101 | if(!Collections[i].SceneNames.Exists(SC => SC == scene.name)) 102 | { 103 | continue; 104 | } 105 | 106 | Rect rect_color = new Rect(selectionRect); 107 | rect_color.x -= 47; 108 | rect_color.width += 63; 109 | 110 | EditorGUI.DrawRect(rect_color, Collections[i].hierarchyColor); 111 | // ? if multiple collection can be loaded in the future. draw a line above this scene to differentiate the start and end of each collection. 112 | 113 | Rect rect_Collection = new Rect(selectionRect); 114 | rect_Collection.width = 15; 115 | rect_Collection.height = 15; 116 | 117 | if(Collections[i] != null) 118 | { 119 | GUI.Label(rect_Collection, new GUIContent("", "Loaded by the \"" + Collections[i].name + "\" Collection")); 120 | } 121 | GUI.DrawTexture(rect_Collection, collectionIcon); 122 | 123 | Rect rect_checkMark = new Rect(selectionRect); 124 | rect_checkMark.x = selectionRect.width + 32; 125 | rect_checkMark.y += 1; 126 | rect_checkMark.width = 12; 127 | rect_checkMark.height = 12; 128 | 129 | for (int j = 0; j < Collections[i].SceneNames.Count; j++) 130 | { 131 | if(!scene.name.Equals(Collections[i].SceneNames[j])) 132 | { 133 | continue; 134 | } 135 | 136 | bool inBuild = false; 137 | string path = AssetDatabase.GetAssetPath(Collections[i].Scenes[j].TargetScene); 138 | int index = SceneUtility.GetBuildIndexByScenePath(path); 139 | 140 | if(index >= 0) 141 | { 142 | inBuild = true; 143 | } 144 | 145 | if(inBuild) 146 | { 147 | GUI.Label(rect_checkMark, new GUIContent("", "The scene is already in the build settings")); 148 | GUI.DrawTexture(rect_checkMark, checkMark_Y); 149 | } 150 | else 151 | { 152 | GUI.Label(rect_checkMark, new GUIContent("", "The scene is missing in the build settings")); 153 | GUI.DrawTexture(rect_checkMark, checkMark_N); 154 | } 155 | break; 156 | } 157 | 158 | Rect rect_activeScene = new Rect(rect_checkMark); 159 | rect_activeScene.x -= 19; 160 | rect_activeScene.y -= 1; 161 | rect_activeScene.width = 15; 162 | 163 | GUIStyle RightHeaderStyle = new GUIStyle(GUI.skin.customStyles[22]); 164 | RightHeaderStyle.alignment = TextAnchor.UpperRight; 165 | 166 | string SceneName = EditorSceneManager.GetActiveScene().name; 167 | if(scene.name.Equals(SceneName)) 168 | { 169 | GUI.Label(rect_activeScene, new GUIContent("✔", "This scene is the target active scene for the \"" + Collections[i].name + "\" scene collection"), RightHeaderStyle); 170 | } 171 | } 172 | } 173 | 174 | private static Scene GetSceneFromHandleID( int handleID ) 175 | { 176 | int numScenes = EditorSceneManager.sceneCount; 177 | for (int i = 0 ; i < numScenes; ++i) 178 | { 179 | var scene = EditorSceneManager.GetSceneAt(i); 180 | 181 | if (scene.GetHashCode() == handleID) 182 | { 183 | return scene; 184 | } 185 | } 186 | return new Scene(); 187 | } 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /Editor/MultiSceneToolsHierarchyStyle_Editor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 366e4675fca38d341a3749010c9497a7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/MultiSceneToolsMenuItems.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | using UnityEditor; 10 | using UnityEngine; 11 | using HH.MultiSceneTools; 12 | 13 | namespace HH.MultiSceneToolsEditor 14 | { 15 | public static class MultiSceneToolsMenuItems 16 | { 17 | [MenuItem("Tools/Multi Scene Tools Lite/Reload project Collections", false, 3)] 18 | static void UpdateCollections() 19 | { 20 | MultiSceneToolsConfig.instance.UpdateCollections(); 21 | } 22 | 23 | [MenuItem("Tools/Multi Scene Tools Lite/Add All Scenes In Collections to Build", false, 3)] 24 | public static void AddCollectionsToBuildSettings() 25 | { 26 | MultiSceneToolsConfig.instance.AddCollectionsToBuildSettings(); 27 | } 28 | 29 | [MenuItem("Tools/Multi Scene Tools Lite/Add A Collection Menu Shortcut", false, 3)] 30 | public static void AddMenuShortcut() 31 | { 32 | CreateCollectionShortcut.GenerateShortcut(); 33 | } 34 | 35 | [MenuItem("Tools/Multi Scene Tools Lite/Changelog", false, 6)] 36 | public static void OpenChangelog() 37 | { 38 | Application.OpenURL("https://github.com/HenrysHouses/MultiSceneTools/blob/main/CHANGELOG.md"); 39 | } 40 | 41 | [MenuItem("Tools/Multi Scene Tools Lite/Donate!", false, 6)] 42 | public static void DonateToHenry() 43 | { 44 | Application.OpenURL("https://ko-fi.com/henryshouse"); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Editor/MultiSceneToolsMenuItems.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 05d03a2257efb5c46beabfcd84037cba 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/MultiSceneToolsSetup_Wizard.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | using UnityEngine; 10 | using UnityEditor; 11 | using HH.MultiSceneTools; 12 | using System.IO; 13 | using System.Linq; 14 | 15 | namespace HH.MultiSceneToolsEditor 16 | { 17 | public class MultiSceneToolsSetup_Wizard: EditorWindow 18 | { 19 | Texture MultiSceneToolsIcon; 20 | static GUIStyle TitleStyle; 21 | static GUIStyle WarningStyle; 22 | 23 | // variables 24 | MultiSceneToolsConfig currentConfig; 25 | string _installationPath = MultiSceneToolsEditorExtensions.packagePath; 26 | string _bootScenePath = MultiSceneToolsConfig.bootPathDefault; 27 | string _sceneCollectionsPath = MultiSceneToolsConfig.collectionsPathDefault; 28 | bool useBootScene = false; 29 | bool preventPopupAgain; 30 | 31 | [MenuItem("Tools/Multi Scene Tools Lite/Setup", false, 1)] 32 | public static void MenuEntryCall() 33 | { 34 | var _Wizard = Resources.FindObjectsOfTypeAll<MultiSceneToolsSetup_Wizard >().FirstOrDefault(); 35 | if (_Wizard == null) 36 | { 37 | _Wizard = CreateInstance<MultiSceneToolsSetup_Wizard >(); 38 | } 39 | 40 | // Set properties on 'wizard'... 41 | _Wizard.titleContent = new GUIContent("Multi Scene Tools Setup", "Creates or updates the config"); 42 | _Wizard.position = new Rect(Screen.currentResolution.width/3, Screen.currentResolution.height/4, _Wizard.position.width, _Wizard.position.height); 43 | _Wizard.minSize = new Vector2(684, 520); 44 | 45 | _Wizard.Show(); 46 | } 47 | 48 | private void Awake() 49 | { 50 | MultiSceneToolsIcon = PackageTextureLoader.FindTexture(PackageTextureLoader.packageIcon); 51 | 52 | currentConfig = MultiSceneToolsConfig.instance; 53 | 54 | if(currentConfig) 55 | { 56 | _installationPath = MultiSceneToolsConfig.instance.packagePath; 57 | _bootScenePath = MultiSceneToolsConfig.instance._BootScenePath; 58 | _sceneCollectionsPath = MultiSceneToolsConfig.instance._SceneCollectionPath; 59 | preventPopupAgain = !MultiSceneToolsConfig.instance.startWizardOnUpdate; 60 | useBootScene = MultiSceneToolsConfig.instance.UseBootScene; 61 | } 62 | 63 | MultiSceneToolsStartup.CheckUpdates(false); 64 | } 65 | 66 | void OnGUI() 67 | { 68 | setCustomStyles(); 69 | 70 | Rect _Rect = new Rect(0,10, position.width, position.height); 71 | 72 | Rect version_Rect = new Rect(10, 10, position.width, position.height); 73 | 74 | if(MultiSceneToolsConfig.instance) 75 | { 76 | drawText(ref version_Rect, "V." + MultiSceneToolsConfig.instance.packageVersion, EditorStyles.miniLabel); 77 | } 78 | else 79 | { 80 | drawText(ref version_Rect, "", EditorStyles.miniLabel); 81 | } 82 | 83 | drawIcon(ref _Rect, 150); 84 | 85 | if(MultiSceneToolsStartup.detectedUpdate) 86 | { 87 | drawText(ref _Rect, "Multi Scene Tools Updated: " + MultiSceneToolsEditorExtensions.packageInfo.version + "!", TitleStyle); 88 | } 89 | else 90 | { 91 | drawText(ref _Rect, "Thank you for using Multi Scene Tools!", TitleStyle); 92 | } 93 | 94 | _Rect.y += 5; 95 | drawText(ref _Rect, "Created by Henrik Hustoft", EditorStyles.centeredGreyMiniLabel); 96 | 97 | _Rect.x += 10; 98 | _Rect.y += 20; 99 | 100 | drawText(ref _Rect, "Please confirm the following settings", EditorStyles.whiteLargeLabel); 101 | 102 | _Rect.y += 10; 103 | 104 | drawTextfield( 105 | ref _Rect, 106 | new GUIContent("Installation Path", "Location of the Multi Scene Tools package"), 107 | ref _installationPath); 108 | 109 | drawCheckbox( 110 | ref _Rect, 111 | new GUIContent("Use Boot Scene"), 112 | ref useBootScene 113 | ); 114 | 115 | drawTextfield( 116 | ref _Rect, 117 | new GUIContent("Boot Scene Path", "The boot scene is ignored by default when unloading/loading scene collections to always keep it loaded"), 118 | ref _bootScenePath); 119 | 120 | drawTextfield( 121 | ref _Rect, 122 | new GUIContent("Scene Collections Path", "Only scene collections within this folder will be detected as available for use"), 123 | ref _sceneCollectionsPath); 124 | 125 | _Rect.y += 10; 126 | 127 | #if UNITY_2021_1_OR_NEWER 128 | if(MultiSceneToolsStartup.detectedUpdate) 129 | { 130 | if(drawLinkButton(ref _Rect, "Keep up to date with the changes!",0)) 131 | { 132 | MultiSceneToolsMenuItems.OpenChangelog(); 133 | } 134 | } 135 | #endif 136 | 137 | _Rect.y += 10; 138 | 139 | #if UNITY_2021_1_OR_NEWER 140 | if(drawLinkButton(ref _Rect, "If you enjoy this package consider supporting me and help fund its continued development!",0)) 141 | { 142 | MultiSceneToolsMenuItems.DonateToHenry(); 143 | } 144 | #endif 145 | 146 | _Rect.y += 40; 147 | 148 | drawCheckbox( 149 | ref _Rect, 150 | new GUIContent("Don't show this again?", "Prevent the setup to run on updates to confirm settings added in the future"), 151 | ref preventPopupAgain); 152 | 153 | if(preventPopupAgain) 154 | { 155 | _Rect.width -= 20; 156 | drawText(ref _Rect, "The setup will not popup automatically when this plugin is updated, informing about important changes", EditorStyles.helpBox); 157 | } 158 | 159 | if(currentConfig == null) 160 | { 161 | _Rect.y += 10; 162 | drawText(ref _Rect, "There is currently no config asset in this project, please confirm to create one.", WarningStyle); 163 | } 164 | 165 | _Rect.width = 150; 166 | _Rect.x = position.width - _Rect.width - 20; 167 | _Rect.y = position.height - 30; 168 | 169 | if(drawButton(ref _Rect, "Confirm")) 170 | { 171 | confirm(); 172 | } 173 | } 174 | 175 | static void setCustomStyles() 176 | { 177 | if(TitleStyle == null) 178 | { 179 | TitleStyle = new GUIStyle(EditorStyles.centeredGreyMiniLabel); 180 | TitleStyle.fontSize = 30; 181 | TitleStyle.fontStyle = FontStyle.Bold; 182 | TitleStyle.normal.textColor = Color.white; 183 | 184 | WarningStyle = new GUIStyle(EditorStyles.boldLabel); 185 | WarningStyle.normal.textColor = Color.yellow; 186 | } 187 | } 188 | 189 | void confirm() 190 | { 191 | MultiSceneToolsConfig config = Resources.Load<MultiSceneToolsConfig>( MultiSceneToolsConfig.configResourcesPath + MultiSceneToolsConfig.configName ); 192 | 193 | if(config == null) 194 | { 195 | if(!Directory.Exists(MultiSceneToolsConfig.configPath)) 196 | { 197 | if(Directory.CreateDirectory(MultiSceneToolsConfig.configPath) != null) 198 | { 199 | Debug.Log("created directory: " + MultiSceneToolsConfig.configPath); 200 | } 201 | } 202 | 203 | config = (MultiSceneToolsConfig) ScriptableObject.CreateInstance(typeof(MultiSceneToolsConfig)); 204 | 205 | AssetDatabase.CreateAsset(config, MultiSceneToolsConfig.configPath + MultiSceneToolsConfig.configName + ".asset"); 206 | 207 | string[] labels = {"MultiSceneTools", "Config"}; 208 | AssetDatabase.SetLabels(config, labels); 209 | 210 | AssetDatabase.SaveAssets(); 211 | 212 | Debug.Log("Created Multi Scene Tools config at: " + MultiSceneToolsConfig.configPath + MultiSceneToolsConfig.configName, config); 213 | 214 | Selection.activeObject = config; 215 | } 216 | 217 | if(config.packagePath != _installationPath) 218 | { 219 | if(Directory.Exists(config.packagePath)) 220 | { 221 | movePackageToPath(); 222 | } 223 | 224 | config.packagePath = _installationPath; 225 | } 226 | 227 | config.setBootScenePath(_bootScenePath); 228 | config.setSceneCollectionFolder(_sceneCollectionsPath); 229 | config.setUseBootScene(useBootScene); 230 | if(config.startWizardOnUpdate && preventPopupAgain) 231 | { 232 | config.toggleWizardPopup(); 233 | } 234 | 235 | if(MultiSceneToolsEditorExtensions.packageInfo.version != "") 236 | { 237 | EditorUtility.SetDirty(config); 238 | AssetDatabase.SaveAssets(); 239 | AssetDatabase.Refresh(); 240 | } 241 | 242 | config.findOpenSceneCollections(); 243 | EditorApplication.playModeStateChanged += MultiSceneToolsConfig.instance.resumeCurrentLoadedCollection; 244 | Debug.Log("Confirmed settings", config); 245 | 246 | Close(); 247 | } 248 | 249 | void movePackageToPath() 250 | { 251 | _installationPath = _installationPath.Replace("\\", "/"); 252 | 253 | string sourcePath; 254 | if(MultiSceneToolsConfig.instance) 255 | { 256 | sourcePath = MultiSceneToolsConfig.instance.packagePath + "/"; 257 | } 258 | else 259 | { 260 | sourcePath = MultiSceneToolsEditorExtensions.packagePath + "/"; 261 | } 262 | 263 | string targetPath = _installationPath + "/"; 264 | 265 | if(_installationPath.Length >= "Packages".Length) 266 | { 267 | if(_installationPath.StartsWith("Packages") || _installationPath.StartsWith("packages")) 268 | { 269 | targetPath = Path.Combine("Packages", MultiSceneToolsEditorExtensions.packageName); 270 | } 271 | } 272 | 273 | // Ensure the target directory exists 274 | if (!Directory.Exists(targetPath)) 275 | { 276 | Directory.CreateDirectory(targetPath); 277 | } 278 | 279 | // Get all files in the source directory, including subdirectories 280 | foreach (string file in Directory.GetFiles(sourcePath, "*.*", SearchOption.AllDirectories)) 281 | { 282 | // Determine the relative path of the file 283 | string relativePath = file.Substring(sourcePath.Length); 284 | 285 | // Determine the destination path 286 | string destinationFile = Path.Combine(targetPath, relativePath); 287 | 288 | // Ensure the destination directory exists 289 | string destinationDir = Path.GetDirectoryName(destinationFile); 290 | if (!Directory.Exists(destinationDir)) 291 | { 292 | Directory.CreateDirectory(destinationDir); 293 | } 294 | 295 | // Move the file 296 | File.Move(file, destinationFile); 297 | } 298 | 299 | AssetDatabase.Refresh(); 300 | } 301 | 302 | void drawIcon(ref Rect currentPosition, int size) 303 | { 304 | Rect Icon_Rect = new Rect(position.width/2-150/2, currentPosition.y, size, size); 305 | GUI.DrawTexture(Icon_Rect, MultiSceneToolsIcon); 306 | currentPosition.y += 150; 307 | } 308 | 309 | void drawText(ref Rect currentPosition, string label, GUIStyle style) 310 | { 311 | Rect Title_Rect = new Rect(currentPosition.x , currentPosition.y, currentPosition.width, style.fontSize+10); 312 | EditorGUI.LabelField(Title_Rect, label, style); 313 | currentPosition.y += style.fontSize+EditorGUIUtility.standardVerticalSpacing; 314 | } 315 | 316 | void drawTextfield(ref Rect currentPosition, GUIContent label, ref string target) 317 | { 318 | Rect textfield_Rect = new Rect(currentPosition.x + 10 , currentPosition.y, position.width-30, EditorGUIUtility.singleLineHeight); 319 | target = EditorGUI.TextField(textfield_Rect, label, target); 320 | currentPosition.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; 321 | } 322 | 323 | void drawCheckbox(ref Rect currentPosition, GUIContent label, ref bool target) 324 | { 325 | Rect toggle_Rect = new Rect(currentPosition.x + 10 , currentPosition.y, position.width-30, EditorGUIUtility.singleLineHeight); 326 | target = EditorGUI.Toggle(toggle_Rect, label, target); 327 | currentPosition.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; 328 | } 329 | 330 | bool drawButton(ref Rect currentPosition, string label) 331 | { 332 | Rect button_Rect = new Rect(currentPosition.x + 10 , currentPosition.y, currentPosition.width, EditorGUIUtility.singleLineHeight); 333 | bool result = GUI.Button(button_Rect, label); 334 | currentPosition.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; 335 | return result; 336 | } 337 | 338 | #if UNITY_2021_1_OR_NEWER 339 | bool drawLinkButton(ref Rect currentPosition, string label, int width) 340 | { 341 | GUIContent content = new GUIContent(label); 342 | var size = EditorStyles.linkLabel.CalcSize(content); 343 | Rect link_Rect = new Rect(currentPosition.x , currentPosition.y, size.x, EditorGUIUtility.singleLineHeight); 344 | bool result = EditorGUI.LinkButton(link_Rect, content); 345 | currentPosition.y += EditorGUIUtility.singleLineHeight+EditorGUIUtility.standardVerticalSpacing; 346 | return result; 347 | } 348 | #endif 349 | 350 | private void OnDestroy() 351 | { 352 | MultiSceneToolsStartup.HasShownUpdate(); 353 | } 354 | } 355 | } -------------------------------------------------------------------------------- /Editor/MultiSceneToolsSetup_Wizard.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eee21ffb62d95a548b9ce1eab6407d1a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/MultiSceneToolsStartup.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | using UnityEditor; 10 | using HH.MultiSceneTools; 11 | 12 | namespace HH.MultiSceneToolsEditor 13 | { 14 | public static class MultiSceneToolsStartup 15 | { 16 | public static bool detectedUpdate {get; private set;} 17 | 18 | [InitializeOnLoadMethod] 19 | static void Startup() 20 | { 21 | EditorApplication.delayCall += () => CheckUpdates(true); 22 | 23 | if(!MultiSceneToolsConfig.instance) 24 | { 25 | return; 26 | } 27 | 28 | MultiSceneToolsConfig.instance.findOpenSceneCollections(); 29 | EditorApplication.playModeStateChanged += MultiSceneToolsConfig.instance.resumeCurrentLoadedCollection; 30 | } 31 | 32 | public static void CheckUpdates(bool tryOpenWizard) 33 | { 34 | if(MultiSceneToolsConfig.instance == null && tryOpenWizard) 35 | { 36 | OpenWizard(); 37 | return; 38 | } 39 | 40 | MultiSceneToolsEditorExtensions.PackageInfo newInfo = MultiSceneToolsEditorExtensions.GetPackageManifest(); 41 | 42 | if(MultiSceneToolsConfig.instance.packageVersion != newInfo.version) 43 | { 44 | detectedUpdate = true; 45 | } 46 | 47 | if(MultiSceneToolsConfig.instance.startWizardOnUpdate && detectedUpdate && tryOpenWizard) 48 | { 49 | OpenWizard(); 50 | } 51 | } 52 | 53 | // static void CheckUpdates(PackageRegistrationEventArgs package) 54 | // { 55 | // bool shouldOpenWizard = false; 56 | 57 | // for (int i = 0; i < package.added.Count; i++) 58 | // { 59 | // if(package.added[i].name == MultiSceneToolsEditorExtensions.packageName) 60 | // { 61 | // // MultiSceneToolsEditorExtensions.packageVersion = package.added[i].version; 62 | 63 | // if(MultiSceneToolsConfig.instance) 64 | // { 65 | // if(MultiSceneToolsConfig.instance.startWizardOnUpdate) 66 | // { 67 | // shouldOpenWizard = true; 68 | // } 69 | // } 70 | // else 71 | // { 72 | // shouldOpenWizard = true; 73 | // } 74 | // break; 75 | // } 76 | // } 77 | 78 | // for (int i = 0; i < package.changedTo.Count; i++) 79 | // { 80 | // if(package.changedTo[i].name == MultiSceneToolsEditorExtensions.packageName) 81 | // { 82 | // // MultiSceneToolsEditorExtensions.packageVersion = package.changedTo[i].version; 83 | 84 | // if(MultiSceneToolsConfig.instance) 85 | // { 86 | // if(MultiSceneToolsConfig.instance.startWizardOnUpdate) 87 | // { 88 | // shouldOpenWizard = true; 89 | // } 90 | // } 91 | // else 92 | // { 93 | // shouldOpenWizard = true; 94 | // } 95 | // detectedUpdate = true; 96 | // break; 97 | // } 98 | // } 99 | 100 | // if(shouldOpenWizard) 101 | // { 102 | // OpenWizard(); 103 | // } 104 | // } 105 | 106 | public static void HasShownUpdate() 107 | { 108 | if(MultiSceneToolsConfig.instance) 109 | { 110 | MultiSceneToolsConfig.instance.setPackageVersion(MultiSceneToolsEditorExtensions.packageInfo.version); 111 | } 112 | detectedUpdate = false; 113 | } 114 | 115 | static void OpenWizard() 116 | { 117 | MultiSceneToolsSetup_Wizard.MenuEntryCall(); 118 | } 119 | } 120 | } -------------------------------------------------------------------------------- /Editor/MultiSceneToolsStartup.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d38f5f8d08095eb4584f10cd2d0db06c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/SceneCollection_Editor.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | using UnityEngine; 10 | using UnityEditor; 11 | using HH.MultiSceneTools; 12 | using UnityEditor.Callbacks; 13 | using System.Reflection; 14 | using System.Collections.Generic; 15 | 16 | namespace HH.MultiSceneToolsEditor 17 | { 18 | [CustomEditor(typeof(SceneCollection))] 19 | public class SceneCollection_Editor : Editor 20 | { 21 | SceneCollection script; 22 | FieldInfo TitleField; 23 | FieldInfo ActiveIndexField; 24 | SerializedProperty _Scenes; 25 | SerializedProperty _Color; 26 | 27 | 28 | private void OnEnable() 29 | { 30 | script = target as SceneCollection; 31 | 32 | TitleField = MultiSceneToolsEditorExtensions._getBackingField(script, "Title"); 33 | ActiveIndexField = MultiSceneToolsEditorExtensions._getBackingField(script, "ActiveSceneIndex"); 34 | _Scenes = serializedObject.FindProperty("Scenes"); 35 | _Color = serializedObject.FindProperty("hierarchyColor"); 36 | 37 | } 38 | 39 | public override void OnInspectorGUI() 40 | { 41 | serializedObject.Update(); 42 | 43 | Undo.RecordObject(script, "Scene Collection"); 44 | 45 | string previousTitle = TitleField.GetValue(script) as string; 46 | string newTitle = EditorGUILayout.TextField("Title", previousTitle); 47 | if (previousTitle != newTitle) 48 | { 49 | Undo.RegisterCompleteObjectUndo(target, "MultiSeneTools: Scene Collection Title = " + newTitle); 50 | TitleField.SetValue(script, newTitle); 51 | EditorUtility.SetDirty(script); 52 | } 53 | 54 | EditorGUILayout.PropertyField(_Color); 55 | 56 | if(_Scenes.isExpanded) 57 | { 58 | EditorGUILayout.PropertyField(_Scenes, new GUIContent("Active Scene | In Build | Target Scene")); 59 | } 60 | else 61 | { 62 | EditorGUILayout.PropertyField(_Scenes); 63 | } 64 | 65 | if(_Scenes.serializedObject.hasModifiedProperties) 66 | { 67 | Undo.RegisterCompleteObjectUndo(target, "MultiSeneTools: Scene Collection Active Scene Index = " + ActiveIndexField.GetValue(script)); 68 | updateActiveSceneIndex(); 69 | } 70 | serializedObject.ApplyModifiedProperties(); 71 | 72 | if(GUILayout.Button("Load Collection")) 73 | { 74 | script.LoadCollection(); 75 | } 76 | } 77 | 78 | [OnOpenAsset] 79 | //Handles opening the editor window when double-clicking project files 80 | public static bool OnOpenAsset(int instanceID, int line) 81 | { 82 | SceneCollection collection = EditorUtility.InstanceIDToObject(instanceID) as SceneCollection; 83 | if (collection != null) 84 | { 85 | collection.LoadCollection(); 86 | MultiSceneToolsConfig.instance.setLoadedCollection(collection, LoadCollectionMode.Replace); 87 | return true; 88 | } 89 | return false; 90 | } 91 | 92 | void updateActiveSceneIndex() 93 | { 94 | SerializedProperty _cachedScenes = _Scenes.Copy(); 95 | serializedObject.ApplyModifiedProperties(); 96 | bool isUpdated = false; 97 | bool hasShiftedIndex = false; 98 | bool[] desiredStates = new bool[_Scenes.arraySize]; 99 | List<int> ActiveScenes = new List<int>(); 100 | // find desired states of all scenes 101 | for (int i = 0; i < _Scenes.arraySize; i++) 102 | { 103 | int _cachedIndex = (int)ActiveIndexField.GetValue(script); 104 | bool _changed = _Scenes.GetArrayElementAtIndex(i).FindPropertyRelative("wasChanged").boolValue; 105 | bool _active = _Scenes.GetArrayElementAtIndex(i).FindPropertyRelative("IsActive").boolValue; 106 | 107 | if(_Scenes.arraySize <= _cachedIndex) 108 | { 109 | 110 | hasShiftedIndex = true; 111 | _cachedIndex = _Scenes.arraySize-1; 112 | desiredStates[_cachedIndex] = _Scenes.GetArrayElementAtIndex(_cachedIndex).FindPropertyRelative("IsActive").boolValue; 113 | isUpdated = true; 114 | ActiveIndexField.SetValue(script, _cachedIndex); 115 | break; 116 | } 117 | 118 | if(_changed) 119 | { 120 | desiredStates[i] = _Scenes.GetArrayElementAtIndex(i).FindPropertyRelative("IsActive").boolValue; 121 | isUpdated = true; 122 | ActiveIndexField.SetValue(script, i); 123 | break; 124 | } 125 | 126 | if(_active) 127 | { 128 | ActiveScenes.Add(i); 129 | } 130 | } 131 | 132 | serializedObject.Update(); 133 | _Scenes = _cachedScenes.Copy(); 134 | 135 | // update desired states of all scenes 136 | for (int i = 0; i < _Scenes.arraySize; i++) 137 | { 138 | if(isUpdated) 139 | { 140 | if(hasShiftedIndex && i == _Scenes.arraySize-1) 141 | { 142 | break; 143 | } 144 | 145 | _Scenes.GetArrayElementAtIndex(i).FindPropertyRelative("IsActive").boolValue = desiredStates[i]; 146 | _Scenes.GetArrayElementAtIndex(i).FindPropertyRelative("wasChanged").boolValue = false; 147 | } 148 | } 149 | 150 | // if the array size grew, fix duplicated active scenes 151 | if(!isUpdated) 152 | { 153 | for (int i = 1; i < ActiveScenes.Count; i++) 154 | { 155 | _Scenes.GetArrayElementAtIndex(ActiveScenes[i]).FindPropertyRelative("IsActive").boolValue = false; 156 | } 157 | } 158 | 159 | // if no valid index was set, set index to -1 160 | if(!isUpdated) 161 | { 162 | ActiveIndexField.SetValue(script, -1); 163 | } 164 | 165 | EditorUtility.SetDirty(script); 166 | } 167 | } 168 | } -------------------------------------------------------------------------------- /Editor/SceneCollection_Editor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3f69cca64f0a6534cab92ac8b736cde9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/SceneManager_EditorWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ace163361446b7d47b6711eb8ec6d550 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/TextureLoader_Editor.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | using HH.MultiSceneTools; 10 | using UnityEditor; 11 | using UnityEngine; 12 | 13 | namespace HH.MultiSceneToolsEditor 14 | { 15 | public static class PackageTextureLoader 16 | { 17 | public static readonly string falseIcon = "/Images/false-Icon.png"; 18 | public static readonly string trueIcon = "/Images/true-Icon.png"; 19 | public static readonly string packageIcon = "/Images/MultiSceneTools Icon.png"; 20 | public static readonly string additiveCollectionIcon = "/Images/addativeCollectionIcon.png"; 21 | 22 | public static Texture FindTexture(string packageTexturePath) 23 | { 24 | // load texture from installed package 25 | if(MultiSceneToolsConfig.instance == null) 26 | { 27 | return (Texture)AssetDatabase.LoadAssetAtPath(MultiSceneToolsEditorExtensions.packagePath + packageTexturePath, typeof(Texture2D)); 28 | } 29 | 30 | return (Texture)AssetDatabase.LoadAssetAtPath(MultiSceneToolsConfig.instance.packagePath + packageTexturePath, typeof(Texture2D)); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Editor/TextureLoader_Editor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8d6ce2635ac88e3428dd08294fd7dcc5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /INSTALLATION GUIDE.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustoft-Digital/MultiSceneTools/cbc4db650a8b297496ef2060a9bf3309f504b4f9/INSTALLATION GUIDE.pdf -------------------------------------------------------------------------------- /INSTALLATION GUIDE.pdf.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c4206b54a9bb4a24989967115cbc0f34 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Images.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d8b9bcc5c54614d49a768ad4d4bf1774 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Images/MultiSceneTools Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustoft-Digital/MultiSceneTools/cbc4db650a8b297496ef2060a9bf3309f504b4f9/Images/MultiSceneTools Icon.png -------------------------------------------------------------------------------- /Images/MultiSceneTools Icon.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: db5e86ac06b3e064e9c607f4b46acdcd 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 1 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 0 40 | wrapV: 0 41 | wrapW: 0 42 | nPOTScale: 0 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 1 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 0 55 | spriteTessellationDetail: -1 56 | textureType: 8 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | cookieLightType: 0 67 | platformSettings: 68 | - serializedVersion: 3 69 | buildTarget: DefaultTexturePlatform 70 | maxTextureSize: 2048 71 | resizeAlgorithm: 0 72 | textureFormat: -1 73 | textureCompression: 1 74 | compressionQuality: 50 75 | crunchedCompression: 0 76 | allowsAlphaSplitting: 0 77 | overridden: 0 78 | androidETC2FallbackOverride: 0 79 | forceMaximumCompressionQuality_BC6H_BC7: 0 80 | - serializedVersion: 3 81 | buildTarget: Standalone 82 | maxTextureSize: 2048 83 | resizeAlgorithm: 0 84 | textureFormat: -1 85 | textureCompression: 1 86 | compressionQuality: 50 87 | crunchedCompression: 0 88 | allowsAlphaSplitting: 0 89 | overridden: 0 90 | androidETC2FallbackOverride: 0 91 | forceMaximumCompressionQuality_BC6H_BC7: 0 92 | - serializedVersion: 3 93 | buildTarget: Server 94 | maxTextureSize: 2048 95 | resizeAlgorithm: 0 96 | textureFormat: -1 97 | textureCompression: 1 98 | compressionQuality: 50 99 | crunchedCompression: 0 100 | allowsAlphaSplitting: 0 101 | overridden: 0 102 | androidETC2FallbackOverride: 0 103 | forceMaximumCompressionQuality_BC6H_BC7: 0 104 | spriteSheet: 105 | serializedVersion: 2 106 | sprites: [] 107 | outline: [] 108 | physicsShape: [] 109 | bones: [] 110 | spriteID: 5e97eb03825dee720800000000000000 111 | internalID: 0 112 | vertices: [] 113 | indices: 114 | edges: [] 115 | weights: [] 116 | secondaryTextures: [] 117 | nameFileIdTable: {} 118 | spritePackingTag: 119 | pSDRemoveMatte: 0 120 | pSDShowRemoveMatteOption: 0 121 | userData: 122 | assetBundleName: 123 | assetBundleVariant: 124 | -------------------------------------------------------------------------------- /Images/addativeCollectionIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustoft-Digital/MultiSceneTools/cbc4db650a8b297496ef2060a9bf3309f504b4f9/Images/addativeCollectionIcon.png -------------------------------------------------------------------------------- /Images/addativeCollectionIcon.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 915aba6188627cd4ebc35f83e12d1a18 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 1 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 0 40 | wrapV: 0 41 | wrapW: 0 42 | nPOTScale: 1 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 0 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 0 55 | spriteTessellationDetail: -1 56 | textureType: 0 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | cookieLightType: 0 67 | platformSettings: 68 | - serializedVersion: 3 69 | buildTarget: DefaultTexturePlatform 70 | maxTextureSize: 2048 71 | resizeAlgorithm: 0 72 | textureFormat: -1 73 | textureCompression: 1 74 | compressionQuality: 50 75 | crunchedCompression: 0 76 | allowsAlphaSplitting: 0 77 | overridden: 0 78 | androidETC2FallbackOverride: 0 79 | forceMaximumCompressionQuality_BC6H_BC7: 0 80 | - serializedVersion: 3 81 | buildTarget: Standalone 82 | maxTextureSize: 2048 83 | resizeAlgorithm: 0 84 | textureFormat: -1 85 | textureCompression: 1 86 | compressionQuality: 50 87 | crunchedCompression: 0 88 | allowsAlphaSplitting: 0 89 | overridden: 0 90 | androidETC2FallbackOverride: 0 91 | forceMaximumCompressionQuality_BC6H_BC7: 0 92 | - serializedVersion: 3 93 | buildTarget: Server 94 | maxTextureSize: 2048 95 | resizeAlgorithm: 0 96 | textureFormat: -1 97 | textureCompression: 1 98 | compressionQuality: 50 99 | crunchedCompression: 0 100 | allowsAlphaSplitting: 0 101 | overridden: 0 102 | androidETC2FallbackOverride: 0 103 | forceMaximumCompressionQuality_BC6H_BC7: 0 104 | spriteSheet: 105 | serializedVersion: 2 106 | sprites: [] 107 | outline: [] 108 | physicsShape: [] 109 | bones: [] 110 | spriteID: 111 | internalID: 0 112 | vertices: [] 113 | indices: 114 | edges: [] 115 | weights: [] 116 | secondaryTextures: [] 117 | nameFileIdTable: {} 118 | spritePackingTag: 119 | pSDRemoveMatte: 0 120 | pSDShowRemoveMatteOption: 0 121 | userData: 122 | assetBundleName: 123 | assetBundleVariant: 124 | -------------------------------------------------------------------------------- /Images/false-Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustoft-Digital/MultiSceneTools/cbc4db650a8b297496ef2060a9bf3309f504b4f9/Images/false-Icon.png -------------------------------------------------------------------------------- /Images/false-Icon.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba30354e1d705be43babffb49fe689e6 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 1 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 0 40 | wrapV: 0 41 | wrapW: 0 42 | nPOTScale: 1 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 0 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 0 55 | spriteTessellationDetail: -1 56 | textureType: 0 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | cookieLightType: 0 67 | platformSettings: 68 | - serializedVersion: 3 69 | buildTarget: DefaultTexturePlatform 70 | maxTextureSize: 2048 71 | resizeAlgorithm: 0 72 | textureFormat: -1 73 | textureCompression: 1 74 | compressionQuality: 50 75 | crunchedCompression: 0 76 | allowsAlphaSplitting: 0 77 | overridden: 0 78 | androidETC2FallbackOverride: 0 79 | forceMaximumCompressionQuality_BC6H_BC7: 0 80 | - serializedVersion: 3 81 | buildTarget: Standalone 82 | maxTextureSize: 2048 83 | resizeAlgorithm: 0 84 | textureFormat: -1 85 | textureCompression: 1 86 | compressionQuality: 50 87 | crunchedCompression: 0 88 | allowsAlphaSplitting: 0 89 | overridden: 0 90 | androidETC2FallbackOverride: 0 91 | forceMaximumCompressionQuality_BC6H_BC7: 0 92 | - serializedVersion: 3 93 | buildTarget: Server 94 | maxTextureSize: 2048 95 | resizeAlgorithm: 0 96 | textureFormat: -1 97 | textureCompression: 1 98 | compressionQuality: 50 99 | crunchedCompression: 0 100 | allowsAlphaSplitting: 0 101 | overridden: 0 102 | androidETC2FallbackOverride: 0 103 | forceMaximumCompressionQuality_BC6H_BC7: 0 104 | spriteSheet: 105 | serializedVersion: 2 106 | sprites: [] 107 | outline: [] 108 | physicsShape: [] 109 | bones: [] 110 | spriteID: 111 | internalID: 0 112 | vertices: [] 113 | indices: 114 | edges: [] 115 | weights: [] 116 | secondaryTextures: [] 117 | nameFileIdTable: {} 118 | spritePackingTag: 119 | pSDRemoveMatte: 0 120 | pSDShowRemoveMatteOption: 0 121 | userData: 122 | assetBundleName: 123 | assetBundleVariant: 124 | -------------------------------------------------------------------------------- /Images/true-Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustoft-Digital/MultiSceneTools/cbc4db650a8b297496ef2060a9bf3309f504b4f9/Images/true-Icon.png -------------------------------------------------------------------------------- /Images/true-Icon.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9bd3ca9d3dbdc064b820980de5b50968 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 1 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 0 40 | wrapV: 0 41 | wrapW: 0 42 | nPOTScale: 1 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 0 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 0 55 | spriteTessellationDetail: -1 56 | textureType: 0 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | cookieLightType: 0 67 | platformSettings: 68 | - serializedVersion: 3 69 | buildTarget: DefaultTexturePlatform 70 | maxTextureSize: 2048 71 | resizeAlgorithm: 0 72 | textureFormat: -1 73 | textureCompression: 1 74 | compressionQuality: 50 75 | crunchedCompression: 0 76 | allowsAlphaSplitting: 0 77 | overridden: 0 78 | androidETC2FallbackOverride: 0 79 | forceMaximumCompressionQuality_BC6H_BC7: 0 80 | - serializedVersion: 3 81 | buildTarget: Standalone 82 | maxTextureSize: 2048 83 | resizeAlgorithm: 0 84 | textureFormat: -1 85 | textureCompression: 1 86 | compressionQuality: 50 87 | crunchedCompression: 0 88 | allowsAlphaSplitting: 0 89 | overridden: 0 90 | androidETC2FallbackOverride: 0 91 | forceMaximumCompressionQuality_BC6H_BC7: 0 92 | - serializedVersion: 3 93 | buildTarget: Server 94 | maxTextureSize: 2048 95 | resizeAlgorithm: 0 96 | textureFormat: -1 97 | textureCompression: 1 98 | compressionQuality: 50 99 | crunchedCompression: 0 100 | allowsAlphaSplitting: 0 101 | overridden: 0 102 | androidETC2FallbackOverride: 0 103 | forceMaximumCompressionQuality_BC6H_BC7: 0 104 | spriteSheet: 105 | serializedVersion: 2 106 | sprites: [] 107 | outline: [] 108 | physicsShape: [] 109 | bones: [] 110 | spriteID: 111 | internalID: 0 112 | vertices: [] 113 | indices: 114 | edges: [] 115 | weights: [] 116 | secondaryTextures: [] 117 | nameFileIdTable: {} 118 | spritePackingTag: 119 | pSDRemoveMatte: 0 120 | pSDShowRemoveMatteOption: 0 121 | userData: 122 | assetBundleName: 123 | assetBundleVariant: 124 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Codacy Badge](https://app.codacy.com/project/badge/Grade/ab255c26e8694143944b4ce292fee11b)](https://app.codacy.com/gh/Hustoft-Digital/MultiSceneTools/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) 2 | 3 | # Multi Scene Tools 4 | 5 | <img src="Images/MultiSceneTools%20Icon.png" alt="MultiSceneToolsIcon" width="200"/> 6 | 7 | ## Features 8 | 9 | - Scene Collection ScriptableObjects 10 | - Tracks which scenes are used together in runtime. 11 | - Double Click to load collection. 12 | - Set which scene is the active scene in the collection. (gets set automatically) 13 | - Track and add collection scenes to build settings. 14 | - (Coming) Tracks cross scene references. 15 | 16 | - Hierarchy Style 17 | - Icon and tooltip on scenes that belong to a scene collection 18 | - User defined scene collection color. 19 | - Checkmark on the target active scene for the collection 20 | - Icons for displaying which collection scenes are in the build settings 21 | 22 | - Multi Scene Management Window 23 | - Display currently loaded scene collection 24 | - Load scene collections 25 | - Load scenes additively 26 | - Unload scenes 27 | - Save and override loaded scene collection 28 | - Create scene collections from loaded scenes 29 | - Create new scenes and load it additively 30 | - Add all open scenes to build settings 31 | - See the current settings set in the config scriptable object 32 | 33 | - Multi Scene Loader 34 | - Load scene collections with this static class 35 | - OnSceneCollectionLoaded & OnSceneCollectionLoadDebug<SceneCollection, collectionLoadMode> events triggered on successful loading 36 | - Loading modes 37 | - Additive 38 | - Loads all scenes in a collection additively 39 | - Replace 40 | - Unloads all scenes other than the boot scene, then loads all scenes additively. 41 | - DifferenceReplace 42 | - Unloads all scenes the collections do not share, then load the missing scenes. 43 | - DifferenceAdditive 44 | - Load all scenes in the collection that is not already loaded 45 | - Subtractive [experimental] (not implemented for async) 46 | - unload all matching scenes 47 | - Async loading methods 48 | - preload scenes and activate when ready 49 | - defer unloading scenes and trigger unloading when ready 50 | - returns an AsyncCollection 51 | - track progression of the async operations 52 | - trigger activation of scenes 53 | - trigger unloading of scenes 54 | - (coming) Scene Node view, Connect scenes together with nodes to visualize adjacent scenes and automate when scenes should be loaded. 55 | 56 | - Multi Scene Tools Config 57 | - See and set current singleton instance 58 | - See and set current loaded scene collection 59 | - Toggle for allowing cross scene referencing (Cross scene referencing is not implemented) 60 | - Toggle for logging scene collection loading 61 | - Target path for boot scene or manager scene 62 | - Target path for loading scene collections 63 | 64 | ## Demo 65 | 66 | Contains several scenes to simulate the outside and inside environment of a building, and a player moving in and out of the building. The demo demonstrates how one could structure two scene collections to contain all the relevant scenes for the interior and exterior, and how to load between them using async. 67 | 68 | To start the demo, open the "DemoAwake" unity scene. This scene demonstrates how to start using scene collections from not having any loaded, and loading into the main demo. 69 | 70 | ## Setup 71 | 72 | - Refer to the installation guide 73 | 74 | ## Author 75 | 76 | - [Henrik Hustoft](https://linktr.ee/henryhouse) 77 | 78 | ## License 79 | 80 | Extension Asset 81 | One license required for each individual user. 82 | For more information, check the EULA and FAQ. 83 | 84 | https://unity.com/legal/as-terms 85 | https://assetstore.unity.com/browse/eula-faq 86 | https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 793c65505423e494ea6bf0ef424d1fda 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a659ec701ca31e14aa94c821c96b8b6c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/AsyncCollection.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | using System.Collections.Generic; 10 | using UnityEngine; 11 | using System.Threading.Tasks; 12 | using System.Threading; 13 | using UnityEngine.Events; 14 | using UnityEngine.SceneManagement; 15 | using System.Linq; 16 | 17 | namespace HH.MultiSceneTools 18 | { 19 | public class AsyncCollection 20 | { 21 | public SceneCollection LoadingCollection {get; private set;} 22 | public LoadCollectionMode loadMode {get; private set;} 23 | private readonly Dictionary<AsyncOperation, LoadSceneMode> _loadingOperations = new Dictionary<AsyncOperation, LoadSceneMode>(); 24 | public Dictionary<AsyncOperation, LoadSceneMode> loadingOperations => _loadingOperations.ToDictionary(entry => entry.Key, entry => entry.Value); 25 | 26 | private readonly List<AsyncOperation> _unloadingOperations = new List<AsyncOperation>(); 27 | public AsyncOperation[] unloadingOperations => _unloadingOperations.ToArray(); 28 | private readonly List<string> _UnloadScenes = new List<string>(); 29 | public string[] UnloadScenes => _UnloadScenes.ToArray(); 30 | public bool deferSceneUnload {get; private set;} 31 | public bool isBeingEnabled {get; private set;} 32 | public CancellationTokenSource cancellationTokenSource {get; private set;} 33 | public UnityEvent OnComplete {get; private set;} = new UnityEvent(); 34 | private bool isLoadingComplete = false; 35 | 36 | public AsyncCollection(SceneCollection TargetCollection, LoadCollectionMode mode, CancellationTokenSource tokenSource, bool deferSceneUnload) 37 | { 38 | LoadingCollection = TargetCollection; 39 | loadMode = mode; 40 | cancellationTokenSource = tokenSource; 41 | this.deferSceneUnload = deferSceneUnload; 42 | 43 | if(deferSceneUnload && (mode.Equals(LoadCollectionMode.Additive) || mode.Equals(LoadCollectionMode.DifferenceAdditive))) 44 | { 45 | Debug.LogWarning("Additive loading can not be affected by deferSceneUnload"); 46 | this.deferSceneUnload = false; 47 | } 48 | OnComplete.AddListener(() => isLoadingComplete = true); 49 | } 50 | 51 | public void addUnloadScene(string SceneName) => _UnloadScenes.Add(SceneName); 52 | public void addLoadingOperation(AsyncOperation operation, LoadSceneMode mode) => _loadingOperations.Add(operation, mode); 53 | public void addUnLoadingOperation(AsyncOperation operation) => _unloadingOperations.Add(operation); 54 | 55 | public bool getIsComplete() 56 | { 57 | for (int i = 0; i < _loadingOperations.Count; i++) 58 | { 59 | if(!_loadingOperations.Keys.ElementAt(i).isDone) 60 | { 61 | return false; 62 | } 63 | } 64 | return true; 65 | } 66 | 67 | public float getProgress() 68 | { 69 | float progress = 0; 70 | for (int i = 0; i < _loadingOperations.Count; i++) 71 | { 72 | progress += _loadingOperations.Keys.ElementAt(i).progress; 73 | } 74 | 75 | if(_loadingOperations.Count == 0) 76 | { 77 | Debug.LogWarning($"No scenes where loaded in the async operation: {LoadingCollection.Title}, {loadMode}"); 78 | return 0.9f; 79 | } 80 | 81 | return progress / _loadingOperations.Count; 82 | } 83 | 84 | public void enableLoadedScenes() 85 | { 86 | if(isLoadingComplete) 87 | { 88 | Debug.LogWarning($"{LoadingCollection.Title}'s loading operation has already been completed"); 89 | return; 90 | } 91 | 92 | isBeingEnabled = true; 93 | 94 | for (int i = 0; i < _loadingOperations.Count; i++) 95 | { 96 | _loadingOperations.Keys.ElementAt(i).allowSceneActivation = true; 97 | } 98 | } 99 | 100 | public void UnloadDeferredScenes() 101 | { 102 | if(isLoadingComplete) 103 | { 104 | Debug.LogWarning($"{LoadingCollection.Title}'s loading operation has already been completed"); 105 | return; 106 | } 107 | 108 | if(!deferSceneUnload) 109 | { 110 | Debug.Log($"{LoadingCollection.Title}'s loading operation will already unload scenes automatically"); 111 | return; 112 | } 113 | 114 | deferSceneUnload = false; 115 | } 116 | 117 | public async Task waitUntilIsCompleteAsync() 118 | { 119 | while(!getIsComplete()) 120 | { 121 | if(cancellationTokenSource.IsCancellationRequested) 122 | { 123 | return; 124 | } 125 | await Task.Delay(1); 126 | } 127 | } 128 | 129 | bool isReady() 130 | { 131 | if(getProgress() >= 0.9f) 132 | { 133 | return true; 134 | } 135 | return false; 136 | } 137 | 138 | public async Task isReadyToEnableScenes() 139 | { 140 | while(!isReady()) 141 | { 142 | Debug.Log($"MultiSceneTools: {LoadingCollection.Title} is waiting to be enabled"); 143 | if(cancellationTokenSource.IsCancellationRequested) 144 | { 145 | return; 146 | } 147 | await Task.Delay(1); 148 | } 149 | } 150 | 151 | public async Task isReadyToUnloadScenes() 152 | { 153 | while(deferSceneUnload) 154 | { 155 | Debug.Log($"MultiSceneTools: {LoadingCollection.Title} is waiting to unload discarded scenes"); 156 | if(cancellationTokenSource.IsCancellationRequested) 157 | { 158 | return; 159 | } 160 | await Task.Delay(1); 161 | } 162 | } 163 | } 164 | } -------------------------------------------------------------------------------- /Runtime/AsyncCollection.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1ad904e2e52526849a7b8e2786042541 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Internal.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba95358c52716374e933e0a88c93d266 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Internal/ActiveScene.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | 10 | #if UNITY_EDITOR 11 | using UnityEditor; 12 | 13 | namespace HH.MultiSceneToolsEditor 14 | { 15 | [System.Serializable] 16 | public struct ActiveScene 17 | { 18 | public SceneAsset TargetScene; 19 | public bool IsActive; 20 | public bool wasChanged; 21 | } 22 | } 23 | #endif -------------------------------------------------------------------------------- /Runtime/Internal/ActiveScene.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ae9c62968e2962b438769b67d0502a82 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/MultiSceneAsyncLoading.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0dde95968985456478d278b4436b3b1c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/MultiSceneLoader.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | #define MULTI_SCENES_ASYNC 10 | using UnityEngine; 11 | using UnityEngine.SceneManagement; 12 | using UnityEngine.Events; 13 | using System.Collections.Generic; 14 | using System.Threading.Tasks; 15 | 16 | using System.Threading; 17 | using System; 18 | 19 | namespace HH.MultiSceneTools 20 | { 21 | /// <summary>Specifies the mode for loading a scene collection</summary> 22 | public enum LoadCollectionMode 23 | { 24 | /// <summary> 25 | /// Load the collection exclusively, unloading any scenes not defined in the collection. 26 | /// </summary> 27 | DifferenceReplace, 28 | /// <summary> 29 | /// Load the collection additively, loading only missing scenes defined in the collection. 30 | /// </summary> 31 | DifferenceAdditive, 32 | /// <summary> 33 | /// Load all scenes in the collection, then unload all previously loaded scenes. 34 | /// </summary> 35 | Replace, 36 | /// <summary> 37 | /// Load all scenes in the collection (allows loading duplicate scenes). 38 | /// </summary> 39 | Additive, 40 | /// <summary> 41 | /// Unload all matching scenes 42 | /// </summary> 43 | Subtractive 44 | } 45 | 46 | public static partial class MultiSceneLoader 47 | { 48 | public static UnityEvent<SceneCollection, LoadCollectionMode> OnSceneCollectionLoaded {get; private set;} = new UnityEvent<SceneCollection, LoadCollectionMode>(); 49 | public static UnityEvent<SceneCollection, LoadCollectionMode> OnSceneCollectionLoadDebug {get; private set;} = new UnityEvent<SceneCollection, LoadCollectionMode>(); 50 | private static bool IsLoggingOnSceneLoad; 51 | private static Scene loadedBootScene; 52 | public static SceneCollection KeepLoaded {private set; get;} 53 | public static List<SceneCollection> collectionsCurrentlyLoaded {private set; get;} = new List<SceneCollection>(); 54 | static List<AsyncCollection> asyncLoadingTask = new List<AsyncCollection>(); 55 | static public List<AsyncCollection> currentAsyncTask => asyncLoadingTask; 56 | static bool initialized; 57 | public static void InitCollectionChecker() 58 | { 59 | if(initialized) 60 | { 61 | return; 62 | } 63 | 64 | initialized = true; 65 | Debug.Log("Collection state checker initialized"); 66 | SceneManager.sceneLoaded -= CheckCollectionState; 67 | SceneManager.sceneLoaded += CheckCollectionState; 68 | 69 | #if UNITY_EDITOR 70 | collectionsCurrentlyLoaded.Clear(); 71 | foreach (var loaded in MultiSceneToolsConfig.instance.LoadedCollections) 72 | { 73 | collectionsCurrentlyLoaded.Add(loaded); 74 | } 75 | #endif 76 | } 77 | static void CheckCollectionState(Scene scene, LoadSceneMode mode) 78 | { 79 | if(asyncLoadingTask.Count == 0) 80 | { 81 | collectionsCurrentlyLoaded.Clear(); 82 | #if UNITY_EDITOR 83 | MultiSceneToolsConfig.instance.SetCurrentCollectionEmpty(); 84 | #endif 85 | } 86 | } 87 | 88 | 89 | #if UNITY_EDITOR 90 | public static void cancelAsyncTasks() 91 | { 92 | foreach (var operation in asyncLoadingTask) 93 | { 94 | operation.cancellationTokenSource.Cancel(); 95 | } 96 | } 97 | public static SceneCollection[] setCurrentlyLoaded(List<SceneCollection> collections, LoadCollectionMode state) 98 | { 99 | collectionsCurrentlyLoaded.Clear(); 100 | for (int i = 0; i < collections.Count; i++) 101 | { 102 | collectionsCurrentlyLoaded.Add(collections[i]); 103 | } 104 | 105 | return collectionsCurrentlyLoaded.ToArray(); 106 | } 107 | 108 | #endif 109 | static SceneCollection[] setCurrentlyLoaded(SceneCollection collection, LoadCollectionMode state) 110 | { 111 | switch(state) 112 | { 113 | case LoadCollectionMode.DifferenceAdditive: 114 | case LoadCollectionMode.Additive: 115 | collectionsCurrentlyLoaded.Add(collection); 116 | break; 117 | case LoadCollectionMode.Subtractive: 118 | collectionsCurrentlyLoaded.Remove(collection); 119 | break; 120 | case LoadCollectionMode.DifferenceReplace: 121 | case LoadCollectionMode.Replace: 122 | collectionsCurrentlyLoaded.Clear(); 123 | collectionsCurrentlyLoaded.Add(collection); 124 | break; 125 | default: 126 | throw new NotImplementedException(); 127 | } 128 | return collectionsCurrentlyLoaded.ToArray(); 129 | } 130 | 131 | static public async Task enableLoadedCollectionAsync(AsyncCollection targetCollection) 132 | { 133 | if(targetCollection == null) 134 | { 135 | Debug.LogWarning("Attempted to enable an asynchronously loaded SceneCollection, but none was loaded"); 136 | return; 137 | } 138 | 139 | float progress = targetCollection.getProgress(); 140 | 141 | if(progress >= 1) 142 | { 143 | Debug.LogWarning(targetCollection.LoadingCollection.Title + " is already being enabled", targetCollection.LoadingCollection); 144 | return; 145 | } 146 | 147 | await targetCollection.waitUntilIsCompleteAsync(); 148 | setCurrentUnloadingScenes(ref targetCollection); 149 | 150 | await targetCollection.isReadyToUnloadScenes(); 151 | Task[] unloads = new Task[targetCollection.UnloadScenes.Length]; 152 | for (int i = 0; i < targetCollection.UnloadScenes.Length; i++) 153 | { 154 | if(targetCollection.cancellationTokenSource.IsCancellationRequested) 155 | { 156 | return; 157 | } 158 | 159 | unloads[i] = unloadAsync(targetCollection.UnloadScenes[i], targetCollection.cancellationTokenSource.Token, targetCollection); 160 | } 161 | await Task.WhenAll(unloads); 162 | 163 | setCurrentlyLoaded(targetCollection.LoadingCollection, targetCollection.loadMode); 164 | } 165 | 166 | static void setCurrentUnloadingScenes(ref AsyncCollection asyncCollection) 167 | { 168 | string bootScene = getBootSceneName(); 169 | bool shouldKeepBoot = false; 170 | 171 | if(loadedBootScene.name != null) 172 | { 173 | shouldKeepBoot = true; 174 | } 175 | 176 | // is boot scene loaded? 177 | if(SceneIsLoaded(bootScene, out loadedBootScene) && MultiSceneToolsConfig.instance.UseBootScene) 178 | { 179 | shouldKeepBoot = true; 180 | } 181 | 182 | if(collectionsCurrentlyLoaded[0] == null) 183 | { 184 | return; 185 | } 186 | 187 | switch(asyncCollection.loadMode) 188 | { 189 | case LoadCollectionMode.DifferenceReplace: 190 | int unloadedScenes = 0; 191 | 192 | for (int i = 0; i < collectionsCurrentlyLoaded.Count; i++) 193 | { 194 | for (int j = 0; j < collectionsCurrentlyLoaded[i].SceneNames.Count; j++) 195 | { 196 | bool difference = true; 197 | foreach (string targetScene in asyncCollection.LoadingCollection.SceneNames) 198 | { 199 | if(collectionsCurrentlyLoaded[i].SceneNames[j].Equals(targetScene)) 200 | { 201 | difference = false; 202 | } 203 | } 204 | if(!difference) 205 | { 206 | continue; 207 | } 208 | 209 | if(collectionsCurrentlyLoaded[i].SceneNames[j] == bootScene && shouldKeepBoot) 210 | { 211 | continue; 212 | } 213 | 214 | if(unloadedScenes != collectionsCurrentlyLoaded[i].SceneNames.Count || loadedBootScene.name != null) 215 | { 216 | unloadedScenes++; 217 | asyncCollection.addUnloadScene(collectionsCurrentlyLoaded[i].SceneNames[j]); 218 | } 219 | } 220 | } 221 | break; 222 | 223 | case LoadCollectionMode.Replace: 224 | for (int i = 0; i < collectionsCurrentlyLoaded.Count; i++) 225 | { 226 | for (int j = 0; j < collectionsCurrentlyLoaded[i].SceneNames.Count; j++) 227 | { 228 | if(shouldKeepBoot) 229 | { 230 | if(collectionsCurrentlyLoaded[i].SceneNames[j].Equals(bootScene)) 231 | { 232 | continue; 233 | } 234 | } 235 | 236 | asyncCollection.addUnloadScene(collectionsCurrentlyLoaded[i].SceneNames[j]); 237 | } 238 | } 239 | break; 240 | 241 | case LoadCollectionMode.Additive: 242 | case LoadCollectionMode.DifferenceAdditive: 243 | break; 244 | default: 245 | Debug.LogError("Not Implemented"); 246 | throw new NotImplementedException("Not implemented"); 247 | } 248 | } 249 | 250 | static async Task setActiveScene(SceneCollection collection, CancellationToken token) 251 | { 252 | if(collection.ActiveSceneIndex < 0) 253 | { 254 | return; 255 | } 256 | 257 | Scene targetActive = new Scene(); 258 | 259 | while(!targetActive.isLoaded) 260 | { 261 | targetActive = SceneManager.GetSceneByName(collection.GetNameOfTargetActiveScene()); 262 | if(token.IsCancellationRequested) 263 | { 264 | return; 265 | } 266 | await Task.Yield(); 267 | } 268 | SceneManager.SetActiveScene(targetActive); 269 | } 270 | 271 | static string getBootSceneName() 272 | { 273 | return MultiSceneToolsConfig.instance.BootScene.name; 274 | } 275 | 276 | // * --- Utility --- 277 | private static bool SceneIsLoaded(string Name, out Scene foundScene) 278 | { 279 | foundScene = default; 280 | 281 | for (int i = 0; i < collectionsCurrentlyLoaded.Count; i++) 282 | { 283 | if(collectionsCurrentlyLoaded[i] == null) 284 | { 285 | return false; 286 | } 287 | 288 | if(collectionsCurrentlyLoaded[i].SceneNames.Contains(Name)) 289 | { 290 | foundScene = SceneManager.GetSceneByName(Name); 291 | return true; 292 | } 293 | } 294 | return false; 295 | } 296 | 297 | static SceneCollection FindCollection(string CollectionTitle) 298 | { 299 | foreach (SceneCollection target in MultiSceneToolsConfig.instance.GetSceneCollections()) 300 | { 301 | if(target.Title == CollectionTitle) 302 | { 303 | return target; 304 | } 305 | } 306 | Debug.LogWarning("Could not find collection"); 307 | return null; 308 | } 309 | 310 | // * --- Debugging --- 311 | private static void CheckException_NoScenesInCollection(SceneCollection target) 312 | { 313 | if(target.SceneNames.Count != 0) 314 | { 315 | return; 316 | } 317 | Debug.LogError("Attempted to load a scene collection that contains no scenes"); 318 | throw new ArgumentException("Attempted to load a scene collection that contains no scenes"); 319 | } 320 | 321 | private static void logSceneChange(SceneCollection collection, LoadCollectionMode mode) 322 | { 323 | Debug.Log("Loaded: \"" + collection.Title + "\" in mode: " + mode.ToString()); 324 | } 325 | 326 | private static void AddLogOnLoad() 327 | { 328 | if(IsLoggingOnSceneLoad) 329 | { 330 | return; 331 | } 332 | 333 | OnSceneCollectionLoadDebug.AddListener(logSceneChange); 334 | IsLoggingOnSceneLoad = true; 335 | } 336 | } 337 | } -------------------------------------------------------------------------------- /Runtime/MultiSceneLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: afa8492f8d4551e4f86c50510d332185 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/MultiSceneLoading.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2ff7bc902d32a5b4bbdb4cba4eeef0e5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/MultiSceneTools.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MultiSceneTools" 3 | } 4 | -------------------------------------------------------------------------------- /Runtime/MultiSceneTools.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3d61be0c52ad2ee409d26dae681f6697 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/MultiSceneToolsConfig.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 34b357e401516b74c916c7f8bdf349d6 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SceneCollection.cs: -------------------------------------------------------------------------------- 1 | // * Multi Scene Tools Lite 2 | // * 3 | // * Copyright (C) 2025 Henrik Hustoft 4 | // * 5 | // * Check the Unity Asset Store for licensing information 6 | // * https://assetstore.unity.com/packages/tools/utilities/multi-scene-tools-lite-304636 7 | // * https://unity.com/legal/as-terms 8 | 9 | 10 | using System.Collections.Generic; 11 | using UnityEngine; 12 | using UnityEngine.SceneManagement; 13 | using System.Linq; 14 | 15 | 16 | #if UNITY_EDITOR 17 | using UnityEditor; 18 | using UnityEditor.SceneManagement; 19 | using HH.MultiSceneToolsEditor; 20 | #endif 21 | 22 | namespace HH.MultiSceneTools 23 | { 24 | public class SceneCollection : ScriptableObject 25 | { 26 | 27 | #if UNITY_EDITOR 28 | [MenuItem("Assets/Create/Multi Scene Tools/SceneCollection", false, 1)] 29 | public static void CreateSceneCollectionIfProjectWindowExists() 30 | { 31 | SceneCollection newCollection = CreateInstance<SceneCollection>(); 32 | 33 | string path = "Assets"; 34 | var target = Selection.activeObject; 35 | if(target != null) 36 | { 37 | path = AssetDatabase.GetAssetPath(target.GetInstanceID()); 38 | } 39 | 40 | string assetPath = ""; 41 | 42 | if(path.Length > 0) // If a location to create the object was selected 43 | { 44 | if(!System.IO.Directory.Exists(path)) // if selected is object, remove object from path 45 | { 46 | string[] folders = path.Split('/'); 47 | 48 | path = ""; 49 | for (int i = 0; i < folders.Length-1; i++) 50 | { 51 | path += folders[i] + "/"; 52 | } 53 | } 54 | else // if selected was a folder 55 | { 56 | path += "/"; 57 | } 58 | 59 | assetPath = AssetDatabase.GenerateUniqueAssetPath(path + "New SceneCollection.asset"); 60 | ProjectWindowUtil.StartNameEditingIfProjectWindowExists(newCollection.GetInstanceID(), ScriptableObject.CreateInstance<HH.MultiSceneTools.Internal.DoCreateNewCollection>(), assetPath, AssetPreview.GetMiniThumbnail(newCollection), null); 61 | 62 | newCollection.Title = newCollection.name; 63 | AssetDatabase.SaveAssets(); 64 | } 65 | } 66 | 67 | public static SceneCollection CreateSceneCollection() 68 | { 69 | SceneCollection newCollection = CreateInstance<SceneCollection>(); 70 | 71 | string path = "Assets"; 72 | var target = Selection.activeObject; 73 | if(target != null) 74 | { 75 | path = AssetDatabase.GetAssetPath(target.GetInstanceID()); 76 | } 77 | 78 | string assetPath = AssetDatabase.GenerateUniqueAssetPath(MultiSceneToolsConfig.instance._SceneCollectionPath + "/New SceneCollection.asset"); 79 | AssetDatabase.CreateAsset(newCollection, assetPath); 80 | Debug.Log("Created SceneCollection at: " + assetPath); 81 | Selection.activeObject = newCollection; 82 | newCollection.Title = newCollection.name; 83 | string[] labels = {"MultiSceneTools", "SceneCollection"}; 84 | AssetDatabase.SetLabels(newCollection, labels); 85 | AssetDatabase.SaveAssets(); 86 | return newCollection; 87 | } 88 | #endif 89 | 90 | [field:SerializeField] public string Title {get; private set;} 91 | [field:SerializeField] public int ActiveSceneIndex {get; private set;} 92 | [SerializeField] private List<string> _SceneNames = new List<string>(); 93 | public List<string> SceneNames => _SceneNames.ToList(); 94 | public string GetNameOfTargetActiveScene() 95 | { 96 | if(ActiveSceneIndex < 0) 97 | { 98 | return ""; 99 | } 100 | 101 | return _SceneNames[ActiveSceneIndex]; 102 | } 103 | 104 | #if UNITY_EDITOR 105 | [SerializeField] public List<ActiveScene> Scenes = new List<ActiveScene>(); 106 | [SerializeField] public Color hierarchyColor; 107 | 108 | public SceneAsset[] GetSceneAssets() 109 | { 110 | SceneAsset[] output = new SceneAsset[Scenes.Count]; 111 | for (int i = 0; i < Scenes.Count; i++) 112 | { 113 | output[i] = Scenes[i].TargetScene; 114 | } 115 | return output; 116 | } 117 | 118 | public void saveCollection(ActiveScene[] scenes) 119 | { 120 | List<ActiveScene> previousScenes = new List<ActiveScene>(Scenes); 121 | ActiveScene[] previousActive = previousScenes.Where(x => x.IsActive).ToArray(); 122 | ActiveScene[] newActive = scenes.Where(x => x.IsActive).ToArray(); 123 | 124 | bool keepPreviousActive = newActive.Equals(previousActive); 125 | 126 | if(keepPreviousActive) 127 | { 128 | ActiveSceneIndex = previousScenes 129 | .Select((item, idx) => new { item, idx }) // Project items with their indices 130 | .FirstOrDefault(x => x.item.TargetScene == previousActive[0].TargetScene)?.idx ?? -1; 131 | } 132 | else 133 | { 134 | ActiveSceneIndex = scenes 135 | .Select((item, idx) => new { item, idx }) // Project items with their indices 136 | .FirstOrDefault(x => x.item.TargetScene == newActive[0].TargetScene)?.idx ?? -1; 137 | } 138 | 139 | Scenes.Clear(); 140 | _SceneNames.Clear(); 141 | for (int i = 0; i < scenes.Length; i++) 142 | { 143 | // if(i < previousScenes.Count) 144 | // { 145 | // if(keepPreviousActive && previousScenes[i].TargetScene == scenes[i].TargetScene && previousScenes[i].IsActive) 146 | // { 147 | // scenes[i].IsActive = true; 148 | // ActiveSceneIndex = i; 149 | // } 150 | // // else 151 | // // { 152 | // // scenes[i].IsActive = false; 153 | // // } 154 | // } 155 | 156 | Scenes.Add(scenes[i]); 157 | _SceneNames.Add(scenes[i].TargetScene.name); 158 | } 159 | } 160 | 161 | private void OnValidate() // updates scene names if any scene would be renamed 162 | { 163 | if(_SceneNames != null) 164 | { 165 | _SceneNames.Clear(); 166 | for (int i = 0; i < Scenes.Count; i++) 167 | { 168 | if(!Scenes[i].TargetScene) 169 | { 170 | _SceneNames.Clear(); 171 | Debug.LogWarning("MultiSceneTools, SceneCollection: " + this.name + " can not be loaded with null reference scenes."); 172 | break; 173 | } 174 | _SceneNames.Add(Scenes[i].TargetScene.name); 175 | } 176 | } 177 | } 178 | 179 | public void LoadCollection() 180 | { 181 | Scene[] DirtyScenes; 182 | if(isScenesDirty(out DirtyScenes)) 183 | { 184 | if(!EditorSceneManager.SaveModifiedScenesIfUserWantsTo(DirtyScenes)) 185 | { 186 | return; 187 | } 188 | } 189 | 190 | if(Scenes.Count > 0) 191 | { 192 | EditorSceneManager.OpenScene(AssetDatabase.GetAssetPath(Scenes[0].TargetScene), OpenSceneMode.Single); 193 | } 194 | 195 | if(Scenes.Count > 1) 196 | { 197 | for (int i = 1; i < Scenes.Count; i++) 198 | { 199 | EditorSceneManager.OpenScene(AssetDatabase.GetAssetPath(Scenes[i].TargetScene), OpenSceneMode.Additive); 200 | } 201 | } 202 | 203 | 204 | if(ActiveSceneIndex >= 0 && ActiveSceneIndex < _SceneNames.Count) 205 | { 206 | EditorSceneManager.SetActiveScene(EditorSceneManager.GetSceneByName(_SceneNames[ActiveSceneIndex])); 207 | } 208 | 209 | MultiSceneToolsConfig.instance.setLoadedCollection(this, LoadCollectionMode.Replace); 210 | MultiSceneToolsConfig.instance.wasCollectionOpened = false; 211 | MultiSceneToolsConfig.instance.wasCollectionClosed = false; 212 | } 213 | 214 | public void LoadAdditive() 215 | { 216 | if(MultiSceneToolsConfig.instance.LoadedCollections.Contains(this)) 217 | { 218 | return; 219 | } 220 | 221 | for (int i = 0; i < this._SceneNames.Count; i++) 222 | { 223 | string path = AssetDatabase.GetAssetPath(this.Scenes[i].TargetScene); 224 | 225 | EditorSceneManager.OpenScene(path, OpenSceneMode.Additive); 226 | } 227 | MultiSceneToolsConfig.instance.setLoadedCollection(this, LoadCollectionMode.Additive); 228 | } 229 | 230 | bool isScenesDirty(out Scene[] DirtyScenes) 231 | { 232 | bool hasDirtied = false; 233 | List<Scene> Dirty = new List<Scene>(); 234 | Scene temp; 235 | for (int i = 0; i < Scenes.Count; i++) 236 | { 237 | temp = SceneManager.GetSceneByName(_SceneNames[i]); 238 | if(temp.isDirty) 239 | { 240 | Dirty.Add(temp); 241 | hasDirtied = true; 242 | } 243 | } 244 | DirtyScenes = Dirty.ToArray(); 245 | return hasDirtied; 246 | } 247 | #endif 248 | } 249 | 250 | namespace HH.MultiSceneTools.Internal 251 | { 252 | #if UNITY_EDITOR 253 | internal class DoCreateNewCollection : UnityEditor.ProjectWindowCallback.EndNameEditAction 254 | { 255 | public override void Action(int instanceId, string pathName, string resourceFile) 256 | { 257 | Object obj = EditorUtility.InstanceIDToObject(instanceId); 258 | 259 | AssetDatabase.CreateAsset(obj, 260 | AssetDatabase.GenerateUniqueAssetPath(pathName)); 261 | 262 | ProjectWindowUtil.ShowCreatedAsset(obj); 263 | 264 | string[] labels = {"MultiSceneTools", "SceneCollection"}; 265 | AssetDatabase.SetLabels(obj, labels); 266 | } 267 | 268 | public override void Cancelled(int instanceId, string pathName, string resourceFile) 269 | { 270 | Selection.activeObject = null; 271 | } 272 | } 273 | #endif 274 | } 275 | } -------------------------------------------------------------------------------- /Runtime/SceneCollection.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8554d268507aaa841afb43e28e84c809 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {fileID: 2800000, guid: db5e86ac06b3e064e9c607f4b46acdcd, type: 3} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 70d668d801ae0144cac3d7935c9248f0 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Scenes/EmptyScene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 12 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_LightingSettings: {fileID: 0} 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | maxJobWorkers: 0 122 | preserveTilesOutsideBounds: 0 123 | debug: 124 | m_Flags: 0 125 | m_NavMeshData: {fileID: 0} 126 | -------------------------------------------------------------------------------- /Scenes/EmptyScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4c3f71ab7d4e95242b04aaaca50c9bc0 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.henrikhustoft.multi-scene-management-tools-lite", 3 | "version": "1.0.2", 4 | "displayName": "Multi Scene Tools Lite", 5 | "description": "Editor and runtime extensions to help manage a multi-scene workflow in unity", 6 | "unity": "2021.3", 7 | "keywords": [ 8 | "multi-scene", 9 | "scene", 10 | "management", 11 | "workflow", 12 | "tools" 13 | ], 14 | "author": { 15 | "name": "Henrik Hustoft", 16 | "url": "https://linktr.ee/henryhouse" 17 | } 18 | } -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9bed7249252a90f4d9ea45bdf8012172 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------