Skip to content

Commit 058481b

Browse files
fix: in-sceneobject NetworkObject update in editor tool (up-port) (#3092)
* update Update to NetworkObject to assist with the refresh in-scene prefab instances * fix Fixing issue where updating a prefab used as in-scene placed prefab instance(s) would not properly get updated if the root prefab asset was updated to have a NetworkObject component. * update changelog entry
1 parent 0bef65c commit 058481b

File tree

3 files changed

+63
-20
lines changed

3 files changed

+63
-20
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
1515

1616
### Fixed
1717

18+
- 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)
1819
- 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)
1920
- Fixed issue where `NetworkObject.SpawnWithObservers` was not being honored when spawning the player prefab. (#3077)
2021
- Fixed issue with the client count not being correct on the host or server side when a client disconnects itself from a session. (#3075)

com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,6 @@ internal void RefreshAllPrefabInstances()
113113
}
114114

115115
// Handle updating the currently active scene
116-
var networkObjects = FindObjectsByType<NetworkObject>(FindObjectsInactive.Include, FindObjectsSortMode.None);
117-
foreach (var networkObject in networkObjects)
118-
{
119-
networkObject.OnValidate();
120-
}
121116
NetworkObjectRefreshTool.ProcessActiveScene();
122117

123118
// Refresh all build settings scenes
@@ -130,14 +125,14 @@ internal void RefreshAllPrefabInstances()
130125
continue;
131126
}
132127
// Add the scene to be processed
133-
NetworkObjectRefreshTool.ProcessScene(editorScene.path, false);
128+
NetworkObjectRefreshTool.ProcessScene(editorScene.path, true);
134129
}
135130

136131
// Process all added scenes
137132
NetworkObjectRefreshTool.ProcessScenes();
138133
}
139134

140-
private void OnValidate()
135+
internal void OnValidate()
141136
{
142137
// do NOT regenerate GlobalObjectIdHash for NetworkPrefabs while Editor is in PlayMode
143138
if (EditorApplication.isPlaying && !string.IsNullOrEmpty(gameObject.scene.name))
@@ -229,6 +224,7 @@ private void CheckForInScenePlaced()
229224
if (sourceAsset != null && sourceAsset.GlobalObjectIdHash != 0 && InScenePlacedSourceGlobalObjectIdHash != sourceAsset.GlobalObjectIdHash)
230225
{
231226
InScenePlacedSourceGlobalObjectIdHash = sourceAsset.GlobalObjectIdHash;
227+
EditorUtility.SetDirty(this);
232228
}
233229
IsSceneObject = true;
234230
}

com.unity.netcode.gameobjects/Runtime/Core/NetworkObjectRefreshTool.cs

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using System;
33
using System.Collections.Generic;
44
using System.Linq;
5+
using System.Text;
6+
using UnityEditor;
57
using UnityEditor.SceneManagement;
68
using UnityEngine;
79
using UnityEngine.SceneManagement;
@@ -21,6 +23,28 @@ internal class NetworkObjectRefreshTool
2123

2224
internal static Action AllScenesProcessed;
2325

26+
internal static NetworkObject PrefabNetworkObject;
27+
28+
internal static void LogInfo(string msg, bool append = false)
29+
{
30+
if (!append)
31+
{
32+
s_Log.AppendLine(msg);
33+
}
34+
else
35+
{
36+
s_Log.Append(msg);
37+
}
38+
}
39+
40+
internal static void FlushLog()
41+
{
42+
Debug.Log(s_Log.ToString());
43+
s_Log.Clear();
44+
}
45+
46+
private static StringBuilder s_Log = new StringBuilder();
47+
2448
internal static void ProcessScene(string scenePath, bool processScenes = true)
2549
{
2650
if (!s_ScenesToUpdate.Contains(scenePath))
@@ -29,14 +53,18 @@ internal static void ProcessScene(string scenePath, bool processScenes = true)
2953
{
3054
EditorSceneManager.sceneOpened += EditorSceneManager_sceneOpened;
3155
EditorSceneManager.sceneSaved += EditorSceneManager_sceneSaved;
56+
s_Log.Clear();
57+
LogInfo("NetworkObject Refresh Scenes to Process:");
3258
}
59+
LogInfo($"[{scenePath}]", true);
3360
s_ScenesToUpdate.Add(scenePath);
3461
}
3562
s_ProcessScenes = processScenes;
3663
}
3764

3865
internal static void ProcessActiveScene()
3966
{
67+
FlushLog();
4068
var activeScene = SceneManager.GetActiveScene();
4169
if (s_ScenesToUpdate.Contains(activeScene.path) && s_ProcessScenes)
4270
{
@@ -54,10 +82,12 @@ internal static void ProcessScenes()
5482
}
5583
else
5684
{
85+
s_ProcessScenes = false;
5786
s_CloseScenes = false;
5887
EditorSceneManager.sceneSaved -= EditorSceneManager_sceneSaved;
5988
EditorSceneManager.sceneOpened -= EditorSceneManager_sceneOpened;
6089
AllScenesProcessed?.Invoke();
90+
FlushLog();
6191
}
6292
}
6393

@@ -68,9 +98,8 @@ private static void FinishedProcessingScene(Scene scene, bool refreshed = false)
6898
// Provide a log of all scenes that were modified to the user
6999
if (refreshed)
70100
{
71-
Debug.Log($"Refreshed and saved updates to scene: {scene.name}");
101+
LogInfo($"Refreshed and saved updates to scene: {scene.name}");
72102
}
73-
s_ProcessScenes = false;
74103
s_ScenesToUpdate.Remove(scene.path);
75104

76105
if (scene != SceneManager.GetActiveScene())
@@ -88,24 +117,41 @@ private static void EditorSceneManager_sceneSaved(Scene scene)
88117

89118
private static void SceneOpened(Scene scene)
90119
{
120+
LogInfo($"Processing scene {scene.name}:");
91121
if (s_ScenesToUpdate.Contains(scene.path))
92122
{
93123
if (s_ProcessScenes)
94124
{
95-
if (!EditorSceneManager.MarkSceneDirty(scene))
96-
{
97-
Debug.Log($"Scene {scene.name} did not get marked as dirty!");
98-
FinishedProcessingScene(scene);
99-
}
100-
else
125+
var prefabInstances = PrefabUtility.FindAllInstancesOfPrefab(PrefabNetworkObject.gameObject);
126+
127+
if (prefabInstances.Length > 0)
101128
{
102-
EditorSceneManager.SaveScene(scene);
129+
var instancesSceneLoadedSpecific = prefabInstances.Where((c) => c.scene == scene).ToList();
130+
131+
if (instancesSceneLoadedSpecific.Count > 0)
132+
{
133+
foreach (var prefabInstance in instancesSceneLoadedSpecific)
134+
{
135+
prefabInstance.GetComponent<NetworkObject>().OnValidate();
136+
}
137+
138+
if (!EditorSceneManager.MarkSceneDirty(scene))
139+
{
140+
LogInfo($"Scene {scene.name} did not get marked as dirty!");
141+
FinishedProcessingScene(scene);
142+
}
143+
else
144+
{
145+
LogInfo($"Changes detected and applied!");
146+
EditorSceneManager.SaveScene(scene);
147+
}
148+
return;
149+
}
103150
}
104151
}
105-
else
106-
{
107-
FinishedProcessingScene(scene);
108-
}
152+
153+
LogInfo($"No changes required.");
154+
FinishedProcessingScene(scene);
109155
}
110156
}
111157

0 commit comments

Comments
 (0)