Skip to content

Commit

Permalink
fix: preview system does not correctly reinitialize after a scene cha…
Browse files Browse the repository at this point in the history
…nge (#328)
  • Loading branch information
bdunderscore authored Aug 14, 2024
1 parent 389e6b9 commit 4dbd00e
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#320] Render nodes are not correctly reused across frames
- [#321] Fix GetTargetGroup being called on every pipeline invalidation
- [#327] Z-fighting occurs in prefab isolation view
- [#328] Fix issue where preview system is not reinitialized after a scene change

### Changed

Expand Down
59 changes: 53 additions & 6 deletions Editor/ChangeStream/ObjectWatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
using Debug = System.Diagnostics.Debug;
using Object = UnityEngine.Object;

#endregion
Expand Down Expand Up @@ -73,10 +74,56 @@ internal ObjectWatcher()
[InitializeOnLoadMethod]
private static void Init()
{
SceneManager.sceneLoaded += (_, _) => Instance.Hierarchy.InvalidateAll();
SceneManager.sceneUnloaded += _ => Instance.Hierarchy.InvalidateAll();
SceneManager.activeSceneChanged += (_, _) => Instance.Hierarchy.InvalidateAll();
Instance.PropertyMonitor.MaybeStartRefreshTimer();
EditorApplication.delayCall += () =>
{
SceneManager.sceneLoaded += (_, _) =>
{
Debug.WriteLine("=== Scene loaded ===");
Instance.Hierarchy.InvalidateAll();
};
SceneManager.sceneUnloaded += _ =>
{
Debug.WriteLine("=== Scene unloaded ===");
Instance.Hierarchy.InvalidateAll();
};
SceneManager.activeSceneChanged += (_, _) =>
{
Debug.WriteLine("=== Active scene changed ===");
Instance.Hierarchy.InvalidateAll();
};
Instance.PropertyMonitor.MaybeStartRefreshTimer();

// These SceneManager callbacks are never invoked, for some reason. Workaround this with a periodic check.
EditorApplication.update += Instance.CheckActiveScenes;
};
}

private Scene[] _activeScenes = Array.Empty<Scene>();

private void CheckActiveScenes()
{
if (SceneManager.sceneCount != _activeScenes.Length)
{
InvalidateScenes();

return;
}

for (var i = 0; i < _activeScenes.Length; i++)
if (_activeScenes[i] != SceneManager.GetSceneAt(i))
{
InvalidateScenes();

return;
}

void InvalidateScenes()
{
_activeScenes = new Scene[SceneManager.sceneCount];
for (var i = 0; i < _activeScenes.Length; i++) _activeScenes[i] = SceneManager.GetSceneAt(i);

Hierarchy.InvalidateAll();
}
}

public ImmutableList<GameObject> MonitorSceneRoots(ComputeContext ctx)
Expand Down Expand Up @@ -207,7 +254,7 @@ private static void InvokeCallback<T>(Action<T> callback, object t) where T : cl
}
catch (Exception e)
{
Debug.LogException(e);
UnityEngine.Debug.LogException(e);
}
}

Expand All @@ -220,7 +267,7 @@ private static bool InvokeCallback<T>(Func<T, bool> callback, object t) where T
}
catch (Exception e)
{
Debug.LogException(e);
UnityEngine.Debug.LogException(e);
return true;
}
}
Expand Down

0 comments on commit 4dbd00e

Please sign in to comment.