Skip to content

Commit 25ecdd8

Browse files
committed
Improve library UX, quality of life changes (guards, more config)
1 parent 58d8e25 commit 25ecdd8

6 files changed

Lines changed: 184 additions & 49 deletions

File tree

Assets/Scenes/SetupScene.unity

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ MonoBehaviour:
564564
m_Name:
565565
m_EditorClassIdentifier:
566566
initialCollection: {fileID: 11400000, guid: 29b938dba078c954bb3082acd12f028d, type: 2}
567+
initialSceneLoadMode: 1
567568
collectionEvents:
568569
onLoadEntered:
569570
m_PersistentCalls:
@@ -580,6 +581,18 @@ MonoBehaviour:
580581
onUnloadExited:
581582
m_PersistentCalls:
582583
m_Calls: []
584+
onShowTransitionEntered:
585+
m_PersistentCalls:
586+
m_Calls: []
587+
onShowTransitionExited:
588+
m_PersistentCalls:
589+
m_Calls: []
590+
onHideTransitionEntered:
591+
m_PersistentCalls:
592+
m_Calls: []
593+
onHideTransitionExited:
594+
m_PersistentCalls:
595+
m_Calls: []
583596
sceneEvents:
584597
onLoadEntered:
585598
m_PersistentCalls:

Packages/com.chark.scriptable-scenes/CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [0.0.4] - 2022-09-28
8+
9+
### Added
10+
- Added more initial scene load options to `ScriptableSceneController`.
11+
- Added more guards when loading invalid scenes.
12+
-
13+
### Changed
14+
- Updated package.json with new version.
15+
16+
### Fixed
17+
- `ScriptableSceneController` not cleaning up `IsLoading` and `loadingCollection` on exception.
18+
719
## [0.0.3] - 2022-09-28
820

921
### Fixed
@@ -25,7 +37,7 @@ Minor UX updates and bug fixes.
2537
### Fixed
2638
- Incorrect collection progress being reported when a collection is loading.
2739

28-
## [0.0.1] - 2022-05-21
40+
## [v0.0.1] - 2022-05-21
2941
Initial preview version.
3042

3143
### Added

Packages/com.chark.scriptable-scenes/Runtime/ScriptableScene.cs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,17 @@ public override void SetActive()
128128

129129
private IEnumerator LoadInternalRoutine()
130130
{
131+
if (sceneBuildIndex < 0)
132+
{
133+
Debug.LogWarning(
134+
"Cannot load an invalid Scene Build Index. Make sure a Scene Asset is assigned, " +
135+
"ensure that the scene is added to project Build Settings and is enabled",
136+
this
137+
);
138+
139+
yield break;
140+
}
141+
131142
var operation = SceneManager.LoadSceneAsync(sceneBuildIndex, LoadSceneMode.Additive);
132143

133144
while (operation.isDone == false)
@@ -142,12 +153,34 @@ private IEnumerator LoadInternalRoutine()
142153

143154
private IEnumerator UnloadInternalRoutine()
144155
{
156+
if (sceneBuildIndex < 0)
157+
{
158+
Debug.LogWarning(
159+
"Cannot unload invalid Scene Build Index. Make sure a Scene Asset is assigned, " +
160+
"ensure that the scene is added to project Build Settings and is enabled",
161+
this
162+
);
163+
164+
yield break;
165+
}
166+
145167
yield return SceneManager.UnloadSceneAsync(sceneBuildIndex);
146168
}
147169

148170
private void SetActiveInternal()
149171
{
150172
var scene = GetScene();
173+
if (scene.IsValid() == false)
174+
{
175+
Debug.LogWarning(
176+
"Cannot activate an invalid scene. Make sure a Scene Asset is assigned, " +
177+
"ensure that the scene is added to project Build Settings and is enabled",
178+
this
179+
);
180+
181+
return;
182+
}
183+
151184
SceneManager.SetActiveScene(scene);
152185
}
153186

@@ -159,7 +192,17 @@ private bool IsLoaded()
159192

160193
private Scene GetScene()
161194
{
162-
return SceneManager.GetSceneByBuildIndex(sceneBuildIndex);
195+
if (sceneBuildIndex >= 0)
196+
{
197+
return SceneManager.GetSceneByBuildIndex(sceneBuildIndex);
198+
}
199+
200+
var invalidScene = new Scene
201+
{
202+
name = "Invalid Scene"
203+
};
204+
205+
return invalidScene;
163206
}
164207

165208
#endregion

Packages/com.chark.scriptable-scenes/Runtime/ScriptableSceneController.cs

Lines changed: 98 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,28 @@ public sealed class ScriptableSceneController : MonoBehaviour
1616
{
1717
#region Editor Fields
1818

19+
private enum SceneLoadMode
20+
{
21+
[Tooltip("Scenes will not be loaded automatically")]
22+
None,
23+
24+
[Tooltip("Automatically load scenes in Awake")]
25+
Awake,
26+
27+
[Tooltip("Automatically load scenes in Start")]
28+
Start
29+
}
30+
1931
// ReSharper disable once NotAccessedField.Local
2032
[Header("Configuration")]
2133
[Tooltip("Scene collection which is first to be loaded when the game runs in build mode")]
2234
[SerializeField]
2335
private BaseScriptableSceneCollection initialCollection;
2436

37+
[Tooltip("Should and when " + nameof(initialCollection) + " be loaded?")]
38+
[SerializeField]
39+
private SceneLoadMode initialSceneLoadMode = SceneLoadMode.Start;
40+
2541
[Header("Events")]
2642
[Tooltip("handler for global (invoked for all collections) collection events")]
2743
[SerializeField]
@@ -63,40 +79,31 @@ public sealed class ScriptableSceneController : MonoBehaviour
6379

6480
#region Unity Lifecycle
6581

66-
private IEnumerator Start()
82+
private void Awake()
6783
{
68-
#if UNITY_EDITOR
69-
if (ScriptableSceneUtilities.TryGetSelectedCollection(out var selected))
70-
{
71-
yield return LoadSceneCollectionRoutine(selected);
72-
yield break;
73-
}
74-
75-
if (ScriptableSceneUtilities.TryGetLoadedCollection(out var loaded))
84+
if (initialSceneLoadMode != SceneLoadMode.Awake)
7685
{
77-
yield return LoadSceneCollectionRoutine(loaded);
78-
yield break;
86+
return;
7987
}
8088

81-
Debug.LogWarning(
82-
$"Cannot load initial {nameof(BaseScriptableSceneCollection)}, make sure a valid " +
83-
$"{nameof(BaseScriptableSceneCollection)} exists which matches currently loaded " +
84-
$"scenes or use the Scene Manager Window",
85-
this
86-
);
87-
89+
#if UNITY_EDITOR
90+
LoadScriptableSceneCollection();
8891
#else
89-
if (initialCollection == false)
92+
LoadInitialSceneCollection();
93+
#endif
94+
}
95+
96+
private void Start()
97+
{
98+
if (initialSceneLoadMode != SceneLoadMode.Start)
9099
{
91-
Debug.LogWarning(
92-
$"{nameof(initialCollection)} is not set, initial scene setup will not be " +
93-
$"loaded",
94-
this
95-
);
96-
yield break;
100+
return;
97101
}
98102

99-
yield return LoadSceneCollectionRoutine(initialCollection);
103+
#if UNITY_EDITOR
104+
LoadScriptableSceneCollection();
105+
#else
106+
LoadInitialSceneCollection();
100107
#endif
101108
}
102109

@@ -155,6 +162,61 @@ public bool TryGetLoadedSceneCollection(out BaseScriptableSceneCollection collec
155162

156163
#region Private Methods
157164

165+
/// <summary>
166+
/// Load scene collection based on custom Scriptable Scene logic.
167+
/// </summary>
168+
private void LoadScriptableSceneCollection()
169+
{
170+
StartCoroutine(LoadScriptableSceneCollectionRoutine());
171+
}
172+
173+
/// <summary>
174+
/// Load scene collection specified in <see cref="initialCollection"/>.
175+
/// </summary>
176+
// ReSharper disable once UnusedMember.Local
177+
private void LoadInitialSceneCollection()
178+
{
179+
StartCoroutine(LoadInitialSceneCollectionRoutine());
180+
}
181+
182+
private IEnumerator LoadScriptableSceneCollectionRoutine()
183+
{
184+
if (ScriptableSceneUtilities.TryGetSelectedCollection(out var selected))
185+
{
186+
yield return LoadSceneCollectionRoutine(selected);
187+
yield break;
188+
}
189+
190+
if (ScriptableSceneUtilities.TryGetLoadedCollection(out var loaded))
191+
{
192+
yield return LoadSceneCollectionRoutine(loaded);
193+
yield break;
194+
}
195+
196+
Debug.LogWarning(
197+
$"Cannot load initial {nameof(BaseScriptableSceneCollection)}, make sure a valid " +
198+
$"{nameof(BaseScriptableSceneCollection)} exists which matches currently loaded " +
199+
$"scenes or use the Scene Manager Window",
200+
this
201+
);
202+
}
203+
204+
private IEnumerator LoadInitialSceneCollectionRoutine()
205+
{
206+
if (initialCollection == false)
207+
{
208+
Debug.LogWarning(
209+
$"{nameof(initialCollection)} is not set, initial scene setup will not be " +
210+
$"loaded",
211+
this
212+
);
213+
214+
yield break;
215+
}
216+
217+
yield return LoadSceneCollectionRoutine(initialCollection);
218+
}
219+
158220
private IEnumerator LoadSceneCollectionRoutine(BaseScriptableSceneCollection collection)
159221
{
160222
if (collection.SceneCount == 0)
@@ -182,11 +244,16 @@ private IEnumerator LoadSceneCollectionRoutine(BaseScriptableSceneCollection col
182244
loadingCollection = collection;
183245
IsLoading = true;
184246

185-
yield return LoadSceneCollectionInternalRoutine(collection);
186-
187-
loadingCollection = null;
188-
loadedCollection = collection;
189-
IsLoading = false;
247+
try
248+
{
249+
yield return LoadSceneCollectionInternalRoutine(collection);
250+
loadedCollection = collection;
251+
}
252+
finally
253+
{
254+
loadingCollection = null;
255+
IsLoading = false;
256+
}
190257
}
191258

192259
private IEnumerator LoadSceneCollectionInternalRoutine(

Packages/com.chark.scriptable-scenes/Runtime/Utilities/ScriptableSceneUtilities.cs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ internal static bool TryGetLoadedScene(BaseScriptableScene scriptableScene, out
156156
var targetSceneBuildIndex = scriptableScene.SceneBuildIndex;
157157
scene = default;
158158

159-
foreach (var loadedScene in GetLoadedScenes())
159+
foreach (var loadedScene in GetValidScenes())
160160
{
161161
var loadedSceneBuildIndex = loadedScene.buildIndex;
162162
if (targetSceneBuildIndex == loadedSceneBuildIndex)
@@ -253,31 +253,31 @@ SceneEventHandler otherHandler
253253

254254
#region Private Methods
255255

256-
private static IEnumerable<Scene> GetLoadedScenes()
257-
{
258-
for (var sceneIndex = 0; sceneIndex < SceneManager.sceneCount; sceneIndex++)
259-
{
260-
var scene = SceneManager.GetSceneAt(sceneIndex);
261-
if (scene.isLoaded)
262-
{
263-
yield return scene;
264-
}
265-
}
266-
}
267-
268256
private static bool IsLoaded(BaseScriptableSceneCollection collection)
269257
{
270258
var scriptableSceneIndices = collection.Scenes
271259
.Select(scene => scene.SceneBuildIndex);
272260

273261
var uniqueScriptableSceneIndices = new HashSet<int>(scriptableSceneIndices);
274262

275-
var loadedSceneIndices = GetLoadedScenes().Select(scene => scene.buildIndex);
276-
var uniqueLoadedSceneIndices = new HashSet<int>(loadedSceneIndices);
263+
var validSceneIndices = GetValidScenes().Select(scene => scene.buildIndex);
264+
var uniqueLoadedSceneIndices = new HashSet<int>(validSceneIndices);
277265

278266
return uniqueScriptableSceneIndices.SetEquals(uniqueLoadedSceneIndices);
279267
}
280268

269+
private static IEnumerable<Scene> GetValidScenes()
270+
{
271+
for (var sceneIndex = 0; sceneIndex < SceneManager.sceneCount; sceneIndex++)
272+
{
273+
var scene = SceneManager.GetSceneAt(sceneIndex);
274+
if (scene.IsValid())
275+
{
276+
yield return scene;
277+
}
278+
}
279+
}
280+
281281
#endregion
282282
}
283283
}

Packages/com.chark.scriptable-scenes/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"name": "CHARK",
66
"url": "https://chark.io"
77
},
8-
"version": "0.0.3",
8+
"version": "0.0.4",
99
"unity": "2020.3",
1010
"description": "Simple scene loading and management system for Unity Engine, implemented via scriptable objects.",
1111
"keywords": [

0 commit comments

Comments
 (0)