The SceneAsset is useless thing.
I just want to get some info about scene like build index. But I have to make ultra difficult alghorithm to get it
Why you just cant make things simple? I want to load scenes in runtime with SceneAsset, but I cant, I have to write own ScriptableObject decorator with buildIndex serialization.
public class SceneContainer : ScriptableObject
{
[field: SerializeField, HideInInspector]
public int sceneIndex { get; private set; }
#if UNITY_EDITOR
[SerializeField]
private SceneAsset _sceneAsset;
private void OnValidate()
{
string path = AssetDatabase.GetAssetOrScenePath(_sceneAsset);
List<EditorBuildSettingsScene> editorBuildSettingsScenes = EditorBuildSettings.scenes.ToList();
EditorBuildSettingsScene buildSettingsScene = editorBuildSettingsScenes.First(scene => scene.path == path);
int buildIndex = editorBuildSettingsScenes.IndexOf(buildSettingsScene);
if (sceneIndex == buildIndex) return;
sceneIndex = buildIndex;
}
#endif
}
Itās an editor only thing because they donāt exist at runtime. Scenes in your build settings get crunched up into a different file type for use in runtime.
Itās unwieldy, for sure. One of those old parts of Unity that we canāt really shed without Unity doing some big breaking update that probably will never happen.
The process for loading/unloading scenes is a lot more straightforward with Addressables as you can āreferenceā scenes directly via an AddressableReference.
Itās only perceived by you as ultra difficult.
For one, you are not using āvarā which makes your code far more verbose than it needs to be.
Then you are not utilizing LINQ to its fullest. For instance, it works with arrays too.
Lastly, you havenāt cleaned up your code ⦠the second to last line doesnāt make any sense. You can just assign it, regardless of whether the value might be the same or not.
Pretty sure there may be a way to combine both the exists and count check but itās already simple enough to prove my point that there is nothing āultra difficultā about this. And yes, I spent 2 minutes googling the LINQ usage myself and as usual, found the solutions on stackoverflow. I donāt know these off the top of my head either.
The first one just checks if the scene is in the list to begin with, because the TakeWhile only counts the ones that donāt match to increment up to the desired index - which would be wrong (equal to last index) if we didnāt check first whether the scene is actually in the build list.
Exactly why I redesigned the AssetDatabase.
I might be doing more of the same for other ~20 year old rotten API depending on where I consistently run into pains myself.
You can run into serious build issues if you #if out serialized fields because the serialization format then differs between editor and build.
Depending on where you add more fields Unity will throw an error in builds noting that something is off about the serialization format of the scene and fail to load the scene.
Have you tried to build and run this? If not, do that. If it works, add another [SerializeField] below the #endif and try again. At the latest that should throw an error in the build.
You should move that code to an editor-only script.
I think last time I ran into this was with Unity 2018 or 2019 and ever since that was ingrained as a no-no given how awful it was to figure out the cause.
Its not difficult because I implemented this and gave you ready code. You just refactor it. But when you have only task: āmake the runtime sceneAsset decorator because unity dont have itā. You have to spent 20-30 minutes to find a solution.