Skip to content

Commit

Permalink
feat: now you can assign scenes even if not in Editor (#1576)
Browse files Browse the repository at this point in the history
* feat: now you can assign scenes even if not in Editor

Instead of using scene name, scenes are now identified by path.
This fixes a couple problems:

1) In the room example, now you can assign the scenes even if they have
not been added to the editor.  This was a constant pain because if you
open the offlinescene, all the scenes got wiped.  You had to add the
scenes to the editor and reassign them all again.   With this PR you
will still need to add them to the editor, but they will remain
assigned.

2) It is possible for multiple scenes to have the same name,  but it is
not possible for multiple scenes to have the same path. So this is
a more robust way to identify scenes

This also greatly simplifies the scene SceneDrawer

BREAKING CHANGE: You will need to reassign your scenes after upgrade

* Automatically fix properties that were using name

If you open a NetworkManager or other gameobject that uses a scene name
it now gets converted to scene path by the SceneDrawer

* Use get scene by name

* Scene can never be null

* Update Assets/Mirror/Examples/AdditiveScenes/Scenes/MainScene.unity

* Issue warning if we drop the scene

* Issue error if scene is lost

* Add suggestion on how to fix the error

* Keep backwards compatibility, check for scene name

* cache the active scene

* Update Assets/Mirror/Editor/SceneDrawer.cs

Co-Authored-By: James Frowen <jamesfrowendev@gmail.com>

* GetSceneByName only works if scene is loaded

* Remove unused using

Co-authored-by: James Frowen <jamesfrowendev@gmail.com>
  • Loading branch information
paulpach and James-Frowen committed Mar 26, 2020
1 parent 8c6ae0f commit c8a1a5e
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 50 deletions.
18 changes: 9 additions & 9 deletions Assets/Mirror/Components/NetworkRoomManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,9 @@ public override void OnServerReady(NetworkConnection conn)

void SceneLoadedForPlayer(NetworkConnection conn, GameObject roomPlayer)
{
if (LogFilter.Debug) Debug.LogFormat("NetworkRoom SceneLoadedForPlayer scene: {0} {1}", SceneManager.GetActiveScene().name, conn);
if (LogFilter.Debug) Debug.LogFormat("NetworkRoom SceneLoadedForPlayer scene: {0} {1}", SceneManager.GetActiveScene().path, conn);

if (SceneManager.GetActiveScene().name == RoomScene)
if (IsSceneActive(RoomScene))
{
// cant be ready in room, add to ready list
PendingPlayer pending;
Expand Down Expand Up @@ -179,7 +179,7 @@ void SceneLoadedForPlayer(NetworkConnection conn, GameObject roomPlayer)
/// </summary>
public void CheckReadyToBegin()
{
if (SceneManager.GetActiveScene().name != RoomScene)
if (!IsSceneActive(RoomScene))
return;

if (minPlayers > 0 && NetworkServer.connections.Count(conn => conn.Value != null && conn.Value.identity.gameObject.GetComponent<NetworkRoomPlayer>().readyToBegin) < minPlayers)
Expand Down Expand Up @@ -229,7 +229,7 @@ public override void OnServerConnect(NetworkConnection conn)
}

// cannot join game in progress
if (SceneManager.GetActiveScene().name != RoomScene)
if (!IsSceneActive(RoomScene))
{
conn.Disconnect();
return;
Expand Down Expand Up @@ -262,7 +262,7 @@ public override void OnServerDisconnect(NetworkConnection conn)
player.GetComponent<NetworkRoomPlayer>().readyToBegin = false;
}

if (SceneManager.GetActiveScene().name == RoomScene)
if (IsSceneActive(RoomScene))
RecalculateRoomPlayerIndices();

base.OnServerDisconnect(conn);
Expand All @@ -276,7 +276,7 @@ public override void OnServerDisconnect(NetworkConnection conn)
/// <param name="conn">Connection from client.</param>
public override void OnServerAddPlayer(NetworkConnection conn)
{
if (SceneManager.GetActiveScene().name == RoomScene)
if (IsSceneActive(RoomScene))
{
if (roomSlots.Count == maxConnections)
return;
Expand Down Expand Up @@ -464,7 +464,7 @@ public override void OnStopClient()
/// <param name="conn">Connection of the client</param>
public override void OnClientSceneChanged(NetworkConnection conn)
{
if (SceneManager.GetActiveScene().name == RoomScene)
if (IsSceneActive(RoomScene))
{
if (NetworkClient.isConnected)
CallOnClientEnterRoom();
Expand Down Expand Up @@ -659,15 +659,15 @@ public virtual void OnGUI()
if (!showRoomGUI)
return;

if (NetworkServer.active && SceneManager.GetActiveScene().name == GameplayScene)
if (NetworkServer.active && IsSceneActive(GameplayScene))
{
GUILayout.BeginArea(new Rect(Screen.width - 150f, 10f, 140f, 30f));
if (GUILayout.Button("Return to Room"))
ServerChangeScene(RoomScene);
GUILayout.EndArea();
}

if (SceneManager.GetActiveScene().name == RoomScene)
if (IsSceneActive(RoomScene))
GUI.Box(new Rect(10f, 180f, 520f, 150f), "PLAYERS");
}

Expand Down
3 changes: 1 addition & 2 deletions Assets/Mirror/Components/NetworkRoomPlayer.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using UnityEngine;
using UnityEngine.SceneManagement;

namespace Mirror
{
Expand Down Expand Up @@ -125,7 +124,7 @@ public virtual void OnGUI()
if (!room.showRoomGUI)
return;

if (SceneManager.GetActiveScene().name != room.RoomScene)
if (!NetworkManager.IsSceneActive(room.RoomScene))
return;

DrawPlayerReadyState();
Expand Down
39 changes: 15 additions & 24 deletions Assets/Mirror/Editor/SceneDrawer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,37 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
{
if (property.propertyType == SerializedPropertyType.String)
{
SceneAsset sceneObject = GetSceneObject(property.stringValue);
SceneAsset scene = (SceneAsset)EditorGUI.ObjectField(position, label, sceneObject, typeof(SceneAsset), true);
if (scene == null)
SceneAsset sceneObject = AssetDatabase.LoadAssetAtPath<SceneAsset>(property.stringValue);

if (sceneObject == null && !string.IsNullOrEmpty(property.stringValue))
{
property.stringValue = "";
// try to load it from the build settings for legacy compatibility
sceneObject = GetBuildSettingsSceneObject(property.stringValue);
}
else if (scene.name != property.stringValue)
if (sceneObject == null && !string.IsNullOrEmpty(property.stringValue))
{
SceneAsset sceneObj = GetSceneObject(scene.name);
if (sceneObj == null)
{
Debug.LogWarning("The scene " + scene.name + " cannot be used. To use this scene add it to the build settings for the project");
}
else
{
property.stringValue = scene.name;
}
Debug.LogError($"Could not find scene {property.stringValue} in {property.propertyPath}, assign the proper scenes in your NetworkManager");
}
SceneAsset scene = (SceneAsset)EditorGUI.ObjectField(position, label, sceneObject, typeof(SceneAsset), true);

property.stringValue = AssetDatabase.GetAssetPath(scene);
}
else
{
EditorGUI.LabelField(position, label.text, "Use [Scene] with strings.");
}
}

protected SceneAsset GetSceneObject(string sceneObjectName)
protected SceneAsset GetBuildSettingsSceneObject(string sceneName)
{
if (string.IsNullOrEmpty(sceneObjectName))
{
return null;
}

foreach (EditorBuildSettingsScene editorScene in EditorBuildSettings.scenes)
foreach (EditorBuildSettingsScene buildScene in EditorBuildSettings.scenes)
{
if (editorScene.path.IndexOf(sceneObjectName) != -1)
SceneAsset sceneAsset = AssetDatabase.LoadAssetAtPath<SceneAsset>(buildScene.path);
if (sceneAsset.name == sceneName)
{
return AssetDatabase.LoadAssetAtPath(editorScene.path, typeof(SceneAsset)) as SceneAsset;
return sceneAsset;
}
}
Debug.LogWarning("Scene [" + sceneObjectName + "] cannot be used. Add this scene to the 'Scenes in the Build' in build settings.");
return null;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
syncMode: 0
syncInterval: 0.1
subScene: SubScene
subScene: Assets/Mirror/Examples/AdditiveScenes/Scenes/SubScene.unity
--- !u!1001 &160176455
PrefabInstance:
m_ObjectHideFlags: 0
Expand Down
12 changes: 6 additions & 6 deletions Assets/Mirror/Examples/Room/Scenes/OfflineScene.unity
Original file line number Diff line number Diff line change
Expand Up @@ -268,10 +268,10 @@ MonoBehaviour:
dontDestroyOnLoad: 1
runInBackground: 1
startOnHeadless: 1
serverTickRate: 30
showDebugMessages: 0
offlineScene: OfflineScene
onlineScene: RoomScene
serverTickRate: 30
offlineScene: Assets/Mirror/Examples/Room/Scenes/OfflineScene.unity
onlineScene: Assets/Mirror/Examples/Room/Scenes/RoomScene.unity
transport: {fileID: 2008127830}
networkAddress: localhost
maxConnections: 5
Expand All @@ -286,10 +286,10 @@ MonoBehaviour:
minPlayers: 1
roomPlayerPrefab: {fileID: 114033720796874720, guid: deae2134a1d77704b9c595efe69767dd,
type: 3}
RoomScene: RoomScene
GameplayScene: OnlineScene
roomSlots: []
RoomScene: Assets/Mirror/Examples/Room/Scenes/RoomScene.unity
GameplayScene: Assets/Mirror/Examples/Room/Scenes/OnlineScene.unity
allPlayersReady: 0
roomSlots: []
--- !u!4 &2008127832
Transform:
m_ObjectHideFlags: 0
Expand Down
6 changes: 3 additions & 3 deletions Assets/Mirror/Examples/Room/Scripts/NetworkRoomPlayerExt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ public class NetworkRoomPlayerExt : NetworkRoomPlayer
{
public override void OnStartClient()
{
if (LogFilter.Debug) Debug.LogFormat("OnStartClient {0}", SceneManager.GetActiveScene().name);
if (LogFilter.Debug) Debug.LogFormat("OnStartClient {0}", SceneManager.GetActiveScene().path);

base.OnStartClient();
}

public override void OnClientEnterRoom()
{
if (LogFilter.Debug) Debug.LogFormat("OnClientEnterRoom {0}", SceneManager.GetActiveScene().name);
if (LogFilter.Debug) Debug.LogFormat("OnClientEnterRoom {0}", SceneManager.GetActiveScene().path);
}

public override void OnClientExitRoom()
{
if (LogFilter.Debug) Debug.LogFormat("OnClientExitRoom {0}", SceneManager.GetActiveScene().name);
if (LogFilter.Debug) Debug.LogFormat("OnClientExitRoom {0}", SceneManager.GetActiveScene().path);
}
}
}
14 changes: 9 additions & 5 deletions Assets/Mirror/Runtime/NetworkManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,13 @@ public virtual void LateUpdate()
bool IsServerOnlineSceneChangeNeeded()
{
// Only change scene if the requested online scene is not blank, and is not already loaded
string loadedSceneName = SceneManager.GetActiveScene().name;
return !string.IsNullOrEmpty(onlineScene) && onlineScene != loadedSceneName && onlineScene != offlineScene;
return !string.IsNullOrEmpty(onlineScene) && !IsSceneActive(onlineScene) && onlineScene != offlineScene;
}

public static bool IsSceneActive(string scene)
{
Scene activeScene = SceneManager.GetActiveScene();
return activeScene.path == scene || activeScene.name == scene;
}

// full server setup code, without spawning objects yet
Expand Down Expand Up @@ -599,7 +604,7 @@ public void StopClient()

// If this is the host player, StopServer will already be changing scenes.
// Check loadingSceneAsync to ensure we don't double-invoke the scene change.
if (!string.IsNullOrEmpty(offlineScene) && SceneManager.GetActiveScene().name != offlineScene && loadingSceneAsync == null)
if (!string.IsNullOrEmpty(offlineScene) && !IsSceneActive(offlineScene) && loadingSceneAsync == null)
{
ClientChangeScene(offlineScene, SceneOperation.Normal);
}
Expand Down Expand Up @@ -1173,8 +1178,7 @@ void OnClientAuthenticated(NetworkConnection conn)
conn.isAuthenticated = true;

// proceed with the login handshake by calling OnClientConnect
string loadedSceneName = SceneManager.GetActiveScene().name;
if (string.IsNullOrEmpty(onlineScene) || onlineScene == offlineScene || loadedSceneName == onlineScene)
if (string.IsNullOrEmpty(onlineScene) || onlineScene == offlineScene || IsSceneActive(onlineScene))
{
clientLoadedScene = false;
OnClientConnect(conn);
Expand Down

0 comments on commit c8a1a5e

Please sign in to comment.