Skip to content

Commit aeb191f

Browse files
authored
Merge pull request #55 from arimger/bugfix/fix-serialized-scene-serialization
Bugfix/fix serialized scene serialization
2 parents 57258c3 + f6185fd commit aeb191f

6 files changed

Lines changed: 137 additions & 73 deletions

File tree

Assets/Editor Toolbox/Editor/Drawers/Regular/SerializedSceneDrawer.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,16 +103,24 @@ public static SceneData GetSceneData(SerializedProperty property)
103103
var sceneAsset = property.objectReferenceValue as SceneAsset;
104104
var scenePath = AssetDatabase.GetAssetPath(sceneAsset);
105105
var sceneGuid = AssetDatabase.AssetPathToGUID(scenePath);
106+
var sceneIndex = -1;
106107
for (var i = 0; i < EditorBuildSettings.scenes.Length; i++)
107108
{
108109
var sceneSettings = EditorBuildSettings.scenes[i];
110+
var isEnabled = sceneSettings.enabled;
111+
if (isEnabled)
112+
{
113+
sceneIndex++;
114+
}
115+
109116
var guid = sceneSettings.guid;
110117
if (guid.Equals(new GUID(sceneGuid)))
111118
{
112-
sceneData.index = i;
113-
sceneData.enabled = sceneSettings.enabled;
119+
sceneData.index = isEnabled ? sceneIndex : -1;
120+
sceneData.enabled = isEnabled;
114121
sceneData.guid = guid;
115122
sceneData.inBuild = true;
123+
break;
116124
}
117125
}
118126

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace Toolbox.Serialization
2+
{
3+
internal class SceneData
4+
{
5+
public string SceneName { get; set; }
6+
public string ScenePath { get; set; }
7+
public int BuildIndex { get; set; }
8+
}
9+
}

Assets/Editor Toolbox/Runtime/Serialization/SceneData.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using System.Collections.Generic;
2+
#if UNITY_EDITOR
3+
using UnityEditor;
4+
#endif
5+
6+
namespace Toolbox.Serialization
7+
{
8+
internal static class SceneSerializationUtility
9+
{
10+
#if UNITY_EDITOR
11+
private static readonly Dictionary<SceneAsset, SceneData> cachedScenes = new Dictionary<SceneAsset, SceneData>();
12+
private static bool isInitialized;
13+
14+
15+
[InitializeOnLoadMethod]
16+
private static void Initialize()
17+
{
18+
if (isInitialized)
19+
{
20+
return;
21+
}
22+
23+
ConfirmCache();
24+
EditorBuildSettings.sceneListChanged -= RefreshCache;
25+
EditorBuildSettings.sceneListChanged += RefreshCache;
26+
isInitialized = true;
27+
}
28+
29+
private static void ConfirmCache()
30+
{
31+
//NOTE: refresh data only if the cache is empty,
32+
//it probably means that it's our first time when we are updating it
33+
if (cachedScenes.Count == 0)
34+
{
35+
RefreshCache();
36+
}
37+
}
38+
39+
private static void RefreshCache()
40+
{
41+
cachedScenes.Clear();
42+
var buildIndex = -1;
43+
foreach (var scene in EditorBuildSettings.scenes)
44+
{
45+
if (!scene.enabled)
46+
{
47+
continue;
48+
}
49+
50+
buildIndex++;
51+
var sceneAsset = EditorGUIUtility.Load(scene.path) as SceneAsset;
52+
if (sceneAsset != null)
53+
{
54+
cachedScenes.Add(sceneAsset, new SceneData()
55+
{
56+
BuildIndex = buildIndex,
57+
SceneName = sceneAsset.name,
58+
ScenePath = scene.path
59+
});
60+
}
61+
}
62+
}
63+
64+
65+
public static bool TryGetSceneData(SceneAsset sceneAsset, out SceneData data)
66+
{
67+
ConfirmCache();
68+
if (!sceneAsset || !cachedScenes.TryGetValue(sceneAsset, out data))
69+
{
70+
data = null;
71+
return false;
72+
}
73+
74+
return true;
75+
}
76+
#endif
77+
}
78+
}

Assets/Editor Toolbox/Runtime/Serialization/SceneSerializationUtility.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Editor Toolbox/Runtime/Serialization/SerializedScene.cs

Lines changed: 18 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
2-
using System.Collections.Generic;
2+
3+
using Toolbox.Serialization;
4+
35
#if UNITY_EDITOR
46
using UnityEditor;
57
#endif
@@ -13,8 +15,6 @@ namespace UnityEngine
1315
public class SerializedScene : ISerializationCallbackReceiver
1416
{
1517
#if UNITY_EDITOR
16-
private readonly static Dictionary<SceneAsset, int> cachedBuildIndexes = new Dictionary<SceneAsset, int>();
17-
1818
[SerializeField]
1919
private SceneAsset sceneReference;
2020
#endif
@@ -26,87 +26,34 @@ public class SerializedScene : ISerializationCallbackReceiver
2626
private int buildIndex;
2727

2828

29-
void ISerializationCallbackReceiver.OnAfterDeserialize()
30-
{ }
31-
3229
void ISerializationCallbackReceiver.OnBeforeSerialize()
3330
{
34-
#if UNITY_EDITOR
35-
TryGetBuildIndex(sceneReference, out buildIndex);
36-
TryGetSceneName(sceneReference, out sceneName);
37-
TryGetScenePath(sceneReference, out scenePath);
38-
#endif
31+
UpdateProperties();
3932
}
4033

41-
//TODO:
42-
// 1 - move it to other class
43-
// 2 - try cache indexes in runtime but only if needed
44-
// 3 - update indexes before build
45-
#if UNITY_EDITOR
46-
[InitializeOnLoadMethod, RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
47-
private static void Initialize()
48-
{
49-
UpdateAllIndexes();
50-
51-
EditorBuildSettings.sceneListChanged -= UpdateAllIndexes;
52-
EditorBuildSettings.sceneListChanged += UpdateAllIndexes;
53-
}
54-
55-
private static void UpdateAllIndexes()
56-
{
57-
cachedBuildIndexes.Clear();
58-
59-
var buildIndex = -1;
60-
foreach (var scene in EditorBuildSettings.scenes)
61-
{
62-
if (scene.enabled)
63-
{
64-
buildIndex++;
65-
var sceneAsset = AssetDatabase.LoadAssetAtPath<SceneAsset>(scene.path);
66-
if (sceneAsset != null)
67-
{
68-
cachedBuildIndexes.Add(sceneAsset, buildIndex);
69-
}
70-
}
71-
}
72-
}
73-
74-
private static bool TryGetBuildIndex(SceneAsset sceneAsset, out int index)
75-
{
76-
if (sceneAsset == null || !cachedBuildIndexes.TryGetValue(sceneAsset, out index))
77-
{
78-
index = -1;
79-
return false;
80-
}
34+
void ISerializationCallbackReceiver.OnAfterDeserialize()
35+
{ }
8136

82-
return true;
83-
}
8437

85-
private static bool TryGetSceneName(SceneAsset sceneAsset, out string name)
38+
private void UpdateProperties()
8639
{
87-
if (sceneAsset == null)
40+
#if UNITY_EDITOR
41+
if (SceneSerializationUtility.TryGetSceneData(sceneReference, out var sceneData))
8842
{
89-
name = null;
90-
return false;
43+
SceneName = sceneData.SceneName;
44+
ScenePath = sceneData.ScenePath;
45+
BuildIndex = sceneData.BuildIndex;
9146
}
92-
93-
name = sceneAsset.name;
94-
return true;
95-
}
96-
97-
public static bool TryGetScenePath(SceneAsset sceneAsset, out string path)
98-
{
99-
if (sceneAsset == null)
47+
else
10048
{
101-
path = null;
102-
return false;
49+
SceneName = string.Empty;
50+
ScenePath = string.Empty;
51+
BuildIndex = -1;
10352
}
104-
105-
path = AssetDatabase.GetAssetPath(sceneAsset);
106-
return true;
53+
#endif
10754
}
10855

109-
56+
#if UNITY_EDITOR
11057
public SceneAsset SceneReference
11158
{
11259
get => sceneReference;

0 commit comments

Comments
 (0)