diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index 1089c4012f..b07b22f3c3 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -12,6 +12,7 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Fixed +- Fixed issue with the in-scene network prefab instance update menu tool where it was not properly updating scenes when invoked on the root prefab instance. (#3092) - Fixed issue where applying the position and/or rotation to the `NetworkManager.ConnectionApprovalResponse` when connection approval and auto-spawn player prefab were enabled would not apply the position and/or rotation when the player prefab was instantiated. (#3078) - Fixed issue where `NetworkObject.SpawnWithObservers` was not being honored when spawning the player prefab. (#3077) - Fixed issue with the client count not being correct on the host or server side when a client disconnects itself from a session. (#3075) diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs index 5cca18a66a..9cd176c39b 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs @@ -113,11 +113,6 @@ internal void RefreshAllPrefabInstances() } // Handle updating the currently active scene - var networkObjects = FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None); - foreach (var networkObject in networkObjects) - { - networkObject.OnValidate(); - } NetworkObjectRefreshTool.ProcessActiveScene(); // Refresh all build settings scenes @@ -130,14 +125,14 @@ internal void RefreshAllPrefabInstances() continue; } // Add the scene to be processed - NetworkObjectRefreshTool.ProcessScene(editorScene.path, false); + NetworkObjectRefreshTool.ProcessScene(editorScene.path, true); } // Process all added scenes NetworkObjectRefreshTool.ProcessScenes(); } - private void OnValidate() + internal void OnValidate() { // do NOT regenerate GlobalObjectIdHash for NetworkPrefabs while Editor is in PlayMode if (EditorApplication.isPlaying && !string.IsNullOrEmpty(gameObject.scene.name)) @@ -229,6 +224,7 @@ private void CheckForInScenePlaced() if (sourceAsset != null && sourceAsset.GlobalObjectIdHash != 0 && InScenePlacedSourceGlobalObjectIdHash != sourceAsset.GlobalObjectIdHash) { InScenePlacedSourceGlobalObjectIdHash = sourceAsset.GlobalObjectIdHash; + EditorUtility.SetDirty(this); } IsSceneObject = true; } diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObjectRefreshTool.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObjectRefreshTool.cs index b9c6db0cf9..63d48e914d 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObjectRefreshTool.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObjectRefreshTool.cs @@ -2,6 +2,8 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; +using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.SceneManagement; @@ -21,6 +23,28 @@ internal class NetworkObjectRefreshTool internal static Action AllScenesProcessed; + internal static NetworkObject PrefabNetworkObject; + + internal static void LogInfo(string msg, bool append = false) + { + if (!append) + { + s_Log.AppendLine(msg); + } + else + { + s_Log.Append(msg); + } + } + + internal static void FlushLog() + { + Debug.Log(s_Log.ToString()); + s_Log.Clear(); + } + + private static StringBuilder s_Log = new StringBuilder(); + internal static void ProcessScene(string scenePath, bool processScenes = true) { if (!s_ScenesToUpdate.Contains(scenePath)) @@ -29,7 +53,10 @@ internal static void ProcessScene(string scenePath, bool processScenes = true) { EditorSceneManager.sceneOpened += EditorSceneManager_sceneOpened; EditorSceneManager.sceneSaved += EditorSceneManager_sceneSaved; + s_Log.Clear(); + LogInfo("NetworkObject Refresh Scenes to Process:"); } + LogInfo($"[{scenePath}]", true); s_ScenesToUpdate.Add(scenePath); } s_ProcessScenes = processScenes; @@ -37,6 +64,7 @@ internal static void ProcessScene(string scenePath, bool processScenes = true) internal static void ProcessActiveScene() { + FlushLog(); var activeScene = SceneManager.GetActiveScene(); if (s_ScenesToUpdate.Contains(activeScene.path) && s_ProcessScenes) { @@ -54,10 +82,12 @@ internal static void ProcessScenes() } else { + s_ProcessScenes = false; s_CloseScenes = false; EditorSceneManager.sceneSaved -= EditorSceneManager_sceneSaved; EditorSceneManager.sceneOpened -= EditorSceneManager_sceneOpened; AllScenesProcessed?.Invoke(); + FlushLog(); } } @@ -68,9 +98,8 @@ private static void FinishedProcessingScene(Scene scene, bool refreshed = false) // Provide a log of all scenes that were modified to the user if (refreshed) { - Debug.Log($"Refreshed and saved updates to scene: {scene.name}"); + LogInfo($"Refreshed and saved updates to scene: {scene.name}"); } - s_ProcessScenes = false; s_ScenesToUpdate.Remove(scene.path); if (scene != SceneManager.GetActiveScene()) @@ -88,24 +117,41 @@ private static void EditorSceneManager_sceneSaved(Scene scene) private static void SceneOpened(Scene scene) { + LogInfo($"Processing scene {scene.name}:"); if (s_ScenesToUpdate.Contains(scene.path)) { if (s_ProcessScenes) { - if (!EditorSceneManager.MarkSceneDirty(scene)) - { - Debug.Log($"Scene {scene.name} did not get marked as dirty!"); - FinishedProcessingScene(scene); - } - else + var prefabInstances = PrefabUtility.FindAllInstancesOfPrefab(PrefabNetworkObject.gameObject); + + if (prefabInstances.Length > 0) { - EditorSceneManager.SaveScene(scene); + var instancesSceneLoadedSpecific = prefabInstances.Where((c) => c.scene == scene).ToList(); + + if (instancesSceneLoadedSpecific.Count > 0) + { + foreach (var prefabInstance in instancesSceneLoadedSpecific) + { + prefabInstance.GetComponent().OnValidate(); + } + + if (!EditorSceneManager.MarkSceneDirty(scene)) + { + LogInfo($"Scene {scene.name} did not get marked as dirty!"); + FinishedProcessingScene(scene); + } + else + { + LogInfo($"Changes detected and applied!"); + EditorSceneManager.SaveScene(scene); + } + return; + } } } - else - { - FinishedProcessingScene(scene); - } + + LogInfo($"No changes required."); + FinishedProcessingScene(scene); } }