Is there a way to find out if a particular scenes is already open and running? Before I asynchronously open a scene, I want to check to see if it's already open.
Per documentation: https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.html SceneManager.sceneCount is the number of currently loaded scenes. SceneManager.GetSceneAt returns a Scene at that index in its list of loaded scenes (the list that sceneCount is the length of) So if you wanted to get an enumerable of all of them... something like: Code (csharp): public static IEnumerable<Scene> GetAllLoadedScenes() { for(int i = 0; i < SceneManager.sceneCount; i++) { yield return SceneManager.GetSceneAt(i); } } Or you could put them in an array, or a list, if you preferred. [edit] Sorry I interpretted your OP to want to know the names of all scenes loaded since the title was "list of open scenes". But you actually want to know if a particular scene is loaded. From this you can check if that scene's name is in that list. Or you could use SceneManager.GetSceneByName and check the 'isLoaded' property like previously mentioned. Or SceneManager.GetSceneByBuildIndex if you know its index rather than name.
lorofduct, You're right that my subject is bit off. Yes, GetSceneByBuildIndex combined with .isLoaded, is the best because it'll go through every scene in my project, telling me what is currently loaded. The icing on the cake would be a var that tells me how many scenes GetSceneByBuildIndex can loop through, like "GetNumberOfScenesInBuild". Otherwise I just have to hardcode how many times I loop through....?
At Editor time you can tell from the EditorBuildSettings class, if that helps. I'm guessing at runtime you can also hit SceneUtility classes starting at zero and going up and maybe see if it returns a null when you go off the end? Or just catch the exception yourself and stop counting? Edit: here, check this, it's pretty straighforward: https://davikingcode.com/blog/retrieving-the-names-of-your-scenes-at-runtime-with-unity/
This means I only need to store the int "EditorBuildSettings.scenes.Length" in the .asset file in my resources....when it runs in the editor. The stand-alone will only read that file. Now, I'm having a silly problem reading the scriptableobject that gets created when running in editor. It reads fine in editor, but is null in stand-alone. The "ScenesStore sStore =......" line returns null in stand-alone: Code (CSharp): public class ScenesStore : ScriptableObject { public int scenesInBuildLength; } void Start(){ ScenesStore sStore = Resources.Load<ScenesStore>("ScenesInBuildLength"); Debug.Log("--asset? " + sStore.name); totalScenesInBuild = sStore.scenesInBuildLength; Debug.Log("--here? " + totalScenesInBuild); }
The obvious first check is the usual suspect: is your ScenesStore object in folder called "Resources" ?
I appreciate your help. I've attached the asset file in case that can be read as text. Reimport didn't help and I'm certain this is my fault. Here is the bit that saves the int. You'll notice the #if UNITY_EDITOR because a couple of these classes are editor-only: Code (CSharp): #if UNITY_EDITOR void SaveScenesNames() { // First, try to load the list if already exists ScenesStore sceneStore = (ScenesStore)AssetDatabase.LoadAssetAtPath("Assets/Resources/ScenesInBuildLength.asset", typeof(ScenesStore)); // If doesn't exist, create it ! if (sceneStore == null) { sceneStore = ScriptableObject.CreateInstance<ScenesStore>(); AssetDatabase.CreateAsset(sceneStore, "Assets/Resources/ScenesInBuildLength.asset"); } // Fill the int sceneStore.scenesInBuildLength = EditorBuildSettings.scenes.Length; // Writes all unsaved asset changes to disk AssetDatabase.SaveAssets(); } #endif ...and again how I read the asset in editor and stand-alone. It gives a null exception in stand-alone only Code (CSharp): ScenesStore sStore = Resources.Load<ScenesStore>("ScenesInBuildLength"); Debug.Log("--asset? " + sStore.name);
Looked at the asset and I suspect there's a problem with your ScriptableObject: your m_Script file ID is zero. It should be the GUID of the ScriptableObject class file's meta file. That's how Unity links stuff. Did you try putting your SO class definiition into its own file if it isn't already? And make that file named the same as the SO derivative, obviously, just like a Monobehaviour. Yours SceneStore instance: Code (csharp): %YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !u!114 &11400000 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 0} <---- this can't be good! m_Name: ScenesInBuildLength m_EditorClassIdentifier: Assembly-CSharp::ManagerLevels/ScenesStore scenesInBuildLength: 0 An unrelated healthy-and-functional example SO-derived object from one of my random projects: Code (csharp): %YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !u!114 &11400000 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 0dd80a3df493a44e488bb676b9005058, type: 3} m_Name: Rat1 m_EditorClassIdentifier: Description: Small rat Count: 1 Level: 1 Note how my m_Script field is nonzero. That guid is the GUID for the SO-derived class file in my case.
I made a new C# file named, ScenesStore.cs with this content Code (CSharp): using System.Collections; using System.Collections.Generic; using UnityEngine; public class ScenesStore : ScriptableObject { public int scenesInBuildLength; } ...I deleted the old asset and rand the project again to make a new asset. But the m_Script is still 0. Somehow, I'm not creating this asset correctly....?
Whacky. I copy-pasted your code and it works fine for me, using Unity 2018.4.2 (latest I had on hand). I did add the create decorator though: (ScenesStore.cs) I added the CreateAssetMenu decorator because I forgot the old way of making ScriptableObject instances and I never want to remember it again. Code (csharp): using System.Collections; using System.Collections.Generic; using UnityEngine; [CreateAssetMenu] public class ScenesStore : ScriptableObject { public int scenesInBuildLength; } And here's the asset that it generated: Code (csharp): %YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !u!114 &11400000 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: d376730f030644e36a26a7554baadfbe, type: 3} m_Name: SceneStoreAsset m_EditorClassIdentifier: scenesInBuildLength: 0 And then as far as the script goes, this is the metafile: (ScenesStore.cs.meta) Code (csharp): fileFormatVersion: 2 guid: d376730f030644e36a26a7554baadfbe MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant:
Oh yeah, how DID your editor script create it? I take it you used ScriptableObject.CreateInstance<ScenesStore>(); to generate it, right?? Pretty sure if you try to just new() one up it won't work.
You did it. My last post was wrong, sorry. I didn't integrate the scriptableObject class file correctly, but my journey was otherwise instructive. To summarize, the solution was to put Code (CSharp): public class ScenesStore : ScriptableObject in a separate .cs file. Thank you Kurt.
It would be nice to read the project panel data directly. Unity does it so how come that process is not documented?