Skip to content

Fall back to scene.name for scenes not in Build Settings - #1083

Open
jimdroberts wants to merge 1 commit into
FirstGearGames:mainfrom
jimdroberts:fix/scenelookupdata-non-build-scenes
Open

jimdroberts wants to merge 1 commit into
FirstGearGames:mainfrom
jimdroberts:fix/scenelookupdata-non-build-scenes

Conversation

@jimdroberts

Copy link
Copy Markdown
Contributor

Problem

In 4.7.3, when the server loads a scene that is not in Build Settings, such as an Addressables scene, clients are told to load a scene with an empty name. The client-side load fails, so the client never joins the scene. Loading an already-loaded non-build scene for a connection fails the same way. Projects that load scenes through a custom SceneProcessorBase, like the Addressables processor in the docs, are affected. We hit this in a project that loads every world scene through Addressables.

Cause

Runtime/Managing/Scened/SceneLookupData.cs L115-116 on main, SceneLookupData(Scene scene):

string fullPath = SceneUtility.GetScenePathByBuildIndex(scene.buildIndex);
FullName = Path.GetFileNameWithoutExtension(fullPath);

A scene loaded from an AssetBundle or Addressables has buildIndex == -1, and GetScenePathByBuildIndex(-1) returns an empty string. FullName is therefore "".

The server builds the lookup data it broadcasts from the loaded Scene objects, in SceneManager.cs L1462 (broadcastLookupData[i] = new(scene);) for newly loaded scenes and L1110 for scenes that are already loaded. The client receives a handle it cannot resolve locally and an empty name, and passes that empty name to BeginLoadAsync.

The same constructor is also used by SceneLoadData(Scene, ...) and by RemoveFromGlobalScenes(Scene) (L2321, called from SceneManager_SceneUnloaded). With FullName empty, an unloaded non-build global scene is not removed from _globalScenes.

This is a regression from 4.7.3R (dad140e). Earlier versions, including 4.6.x and 4.7.2, set Name = scene.name.

Fix

If there is no build path, use scene.name. For scenes that are in Build Settings, Path.GetFileNameWithoutExtension(fullPath) and scene.name are the same value, so nothing changes for them. Scenes outside Build Settings get their name back, as they did before 4.7.3.

I checked the other places on main that use a build index or derive a scene name. DefaultScene.GetSceneName and SceneManager.IsGlobalScene/CheckForDuplicateGlobalSceneNames work from user-supplied strings, not from build indices. ReserializeNetworkObjectsEditor and GameKit's SceneDrawer are editor-only and enumerate EditorBuildSettings.scenes. This constructor is the only runtime place where a name is derived from buildIndex.

Evidence

Verified by reading. SceneUtility.GetScenePathByBuildIndex is documented to return an empty string for an invalid index, and Scene.buildIndex is documented as -1 for scenes loaded from an AssetBundle. The broadcast path above sends that value to clients unchanged. Compiled against Unity 6000.4 with no new errors or warnings.

SceneLookupData(Scene) derived FullName from
SceneUtility.GetScenePathByBuildIndex, which is empty for a scene not in Build
Settings (buildIndex -1, e.g. Addressables). The server then told clients to
load a scene named "". Fall back to scene.name when there is no build path;
scenes in Build Settings are unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant