Redefine SceneMessage (#1093)

* Redefine SceneMessage

* Add obsolete method

* Removed SceneLoader
This commit is contained in:
MrGadget 2019-09-17 16:59:16 -04:00 committed by vis2k
parent 7ac43cd56a
commit 958e2ad612
7 changed files with 67 additions and 129 deletions

View File

@ -92,7 +92,6 @@ GameObject:
- component: {fileID: 8537344390966522168} - component: {fileID: 8537344390966522168}
- component: {fileID: 8704659178864205755} - component: {fileID: 8704659178864205755}
- component: {fileID: 887491563423388292} - component: {fileID: 887491563423388292}
- component: {fileID: 3117920708280701079}
m_Layer: 9 m_Layer: 9
m_Name: Player m_Name: Player
m_TagString: Untagged m_TagString: Untagged
@ -206,8 +205,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: e8f68561248aaca4fb96847ce24742ee, type: 3} m_Script: {fileID: 11500000, guid: e8f68561248aaca4fb96847ce24742ee, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
syncMode: 0
syncInterval: 0 syncInterval: 0
playerColor: {r: 0, g: 0, b: 0, a: 1}
moveSpeed: 8 moveSpeed: 8
turnSpeedAccel: 5 turnSpeedAccel: 5
turnSpeedDecel: 5 turnSpeedDecel: 5
@ -232,18 +231,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 2f74aedd71d9a4f55b3ce499326d45fb, type: 3} m_Script: {fileID: 11500000, guid: 2f74aedd71d9a4f55b3ce499326d45fb, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
syncMode: 0
syncInterval: 0.1 syncInterval: 0.1
compressRotation: 1 compressRotation: 1
--- !u!114 &3117920708280701079
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8872462076811691049}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2925d2020e4083646acf0ba4f4a06858, type: 3}
m_Name:
m_EditorClassIdentifier:
syncInterval: 0.1

View File

@ -1,56 +0,0 @@
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
namespace Mirror.Examples.Additive
{
// This script is attached to the player prefab
public class SceneLoader : NetworkBehaviour
{
public enum LoadAction
{
Load,
Unload
}
// Tell the client to load a single subscene
// This is called from ZoneHandler's server-only OnTrigger events
[TargetRpc]
public void TargetLoadUnloadScene(NetworkConnection networkConnection, string sceneName, LoadAction loadAction)
{
// Check if server here because we already pre-loaded the subscenes on the server
if (!isServer) StartCoroutine(LoadUnloadScene(sceneName, loadAction));
}
// isBusy protects us from being overwhelmed by server messages to load several subscenes at once.
bool isBusy = false;
IEnumerator LoadUnloadScene(string sceneName, LoadAction loadAction)
{
while (isBusy) yield return null;
isBusy = true;
if (loadAction == LoadAction.Load)
yield return SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
else
{
yield return SceneManager.UnloadSceneAsync(sceneName);
yield return Resources.UnloadUnusedAssets();
}
isBusy = false;
Debug.LogFormat("{0} {1} Done", sceneName, loadAction.ToString());
CmdSceneDone(sceneName, loadAction);
}
[Command]
public void CmdSceneDone(string sceneName, LoadAction loadAction)
{
// The point of this is to show the client telling server it has loaded the subscene
// so the server might take some further action, e.g. reposition the player.
Debug.LogFormat("{0} {1} done on client", sceneName, loadAction.ToString());
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 2925d2020e4083646acf0ba4f4a06858
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -18,14 +18,8 @@ void OnTriggerEnter(Collider other)
{ {
Debug.LogFormat("Loading {0}", subScene); Debug.LogFormat("Loading {0}", subScene);
// Get a reference to the SceneLoader component on the player prefab
SceneLoader sceneLoader = other.gameObject.GetComponent<SceneLoader>();
NetworkIdentity networkIdentity = other.gameObject.GetComponent<NetworkIdentity>(); NetworkIdentity networkIdentity = other.gameObject.GetComponent<NetworkIdentity>();
NetworkServer.SendToClientOfPlayer(networkIdentity, new SceneMessage { sceneName = subScene, sceneOperation = SceneOperation.LoadAdditive });
// One or both of these might be null if you don't have Layers set up properly
if (sceneLoader != null && networkIdentity != null)
sceneLoader.TargetLoadUnloadScene(networkIdentity.connectionToClient, subScene, SceneLoader.LoadAction.Load);
} }
[Server] [Server]
@ -33,14 +27,8 @@ void OnTriggerExit(Collider other)
{ {
Debug.LogFormat("Unloading {0}", subScene); Debug.LogFormat("Unloading {0}", subScene);
// Get a reference to the SceneLoader component on the player prefab
SceneLoader sceneLoader = other.gameObject.GetComponent<SceneLoader>();
NetworkIdentity networkIdentity = other.gameObject.GetComponent<NetworkIdentity>(); NetworkIdentity networkIdentity = other.gameObject.GetComponent<NetworkIdentity>();
NetworkServer.SendToClientOfPlayer(networkIdentity, new SceneMessage { sceneName = subScene, sceneOperation = SceneOperation.UnloadAdditive });
// One or both of these might be null if you don't have Layers set up properly
if (sceneLoader != null && networkIdentity != null)
sceneLoader.TargetLoadUnloadScene(networkIdentity.connectionToClient, subScene, SceneLoader.LoadAction.Unload);
} }
} }
} }

View File

@ -14,10 +14,10 @@ public interface IMessageBase
public abstract class MessageBase : IMessageBase public abstract class MessageBase : IMessageBase
{ {
// De-serialize the contents of the reader into this message // De-serialize the contents of the reader into this message
public virtual void Deserialize(NetworkReader reader) {} public virtual void Deserialize(NetworkReader reader) { }
// Serialize the contents of this message into the writer // Serialize the contents of this message into the writer
public virtual void Serialize(NetworkWriter writer) {} public virtual void Serialize(NetworkWriter writer) { }
} }
#region General Typed Messages #region General Typed Messages
@ -25,7 +25,7 @@ public class StringMessage : MessageBase
{ {
public string value; public string value;
public StringMessage() {} public StringMessage() { }
public StringMessage(string v) public StringMessage(string v)
{ {
@ -47,7 +47,7 @@ public class ByteMessage : MessageBase
{ {
public byte value; public byte value;
public ByteMessage() {} public ByteMessage() { }
public ByteMessage(byte v) public ByteMessage(byte v)
{ {
@ -69,7 +69,7 @@ public class BytesMessage : MessageBase
{ {
public byte[] value; public byte[] value;
public BytesMessage() {} public BytesMessage() { }
public BytesMessage(byte[] v) public BytesMessage(byte[] v)
{ {
@ -91,7 +91,7 @@ public class IntegerMessage : MessageBase
{ {
public int value; public int value;
public IntegerMessage() {} public IntegerMessage() { }
public IntegerMessage(int v) public IntegerMessage(int v)
{ {
@ -113,7 +113,7 @@ public class DoubleMessage : MessageBase
{ {
public double value; public double value;
public DoubleMessage() {} public DoubleMessage() { }
public DoubleMessage(double v) public DoubleMessage(double v)
{ {
@ -133,14 +133,14 @@ public override void Serialize(NetworkWriter writer)
public class EmptyMessage : MessageBase public class EmptyMessage : MessageBase
{ {
public override void Deserialize(NetworkReader reader) {} public override void Deserialize(NetworkReader reader) { }
public override void Serialize(NetworkWriter writer) {} public override void Serialize(NetworkWriter writer) { }
} }
#endregion #endregion
#region Public System Messages #region Public System Messages
public class ErrorMessage : ByteMessage {} public class ErrorMessage : ByteMessage { }
public struct ReadyMessage : IMessageBase public struct ReadyMessage : IMessageBase
{ {
@ -195,23 +195,28 @@ public void Serialize(NetworkWriter writer) { }
public struct SceneMessage : IMessageBase public struct SceneMessage : IMessageBase
{ {
public string sceneName; public string sceneName;
public LoadSceneMode sceneMode; // Single = 0, Additive = 1 public SceneOperation sceneOperation; // Normal = 0, LoadAdditive = 1, UnloadAdditive = 2
public LocalPhysicsMode physicsMode; // None = 0, Physics3D = 1, Physics2D = 2
public void Deserialize(NetworkReader reader) public void Deserialize(NetworkReader reader)
{ {
sceneName = reader.ReadString(); sceneName = reader.ReadString();
sceneMode = (LoadSceneMode)reader.ReadByte(); sceneOperation = (SceneOperation)reader.ReadByte();
physicsMode = (LocalPhysicsMode)reader.ReadByte();
} }
public void Serialize(NetworkWriter writer) public void Serialize(NetworkWriter writer)
{ {
writer.WriteString(sceneName); writer.WriteString(sceneName);
writer.WriteByte((byte)sceneMode); writer.WriteByte((byte)sceneOperation);
writer.WriteByte((byte)physicsMode);
} }
} }
public enum SceneOperation : byte
{
Normal,
LoadAdditive,
UnloadAdditive
}
#endregion #endregion
#region System Messages requried for code gen path #region System Messages requried for code gen path
@ -466,7 +471,7 @@ public void Deserialize(NetworkReader reader)
public void Serialize(NetworkWriter writer) public void Serialize(NetworkWriter writer)
{ {
writer.WriteDouble(clientTime); writer.WriteDouble(clientTime);
} }
} }
// The server responds with this message // The server responds with this message

View File

@ -581,7 +581,7 @@ public void StopClient()
if (!string.IsNullOrEmpty(offlineScene) && SceneManager.GetActiveScene().name != offlineScene) if (!string.IsNullOrEmpty(offlineScene) && SceneManager.GetActiveScene().name != offlineScene)
{ {
ClientChangeScene(offlineScene, LoadSceneMode.Single, LocalPhysicsMode.None); ClientChangeScene(offlineScene, SceneOperation.Normal);
} }
CleanupNetworkIdentities(); CleanupNetworkIdentities();
@ -619,15 +619,11 @@ public virtual void ServerChangeScene(string newSceneName, LoadSceneMode sceneMo
// Let server prepare for scene change // Let server prepare for scene change
OnServerChangeScene(newSceneName); OnServerChangeScene(newSceneName);
LoadSceneParameters loadSceneParameters = new LoadSceneParameters(sceneMode, physicsMode); loadingSceneAsync = SceneManager.LoadSceneAsync(newSceneName);
loadingSceneAsync = SceneManager.LoadSceneAsync(newSceneName, loadSceneParameters);
SceneMessage msg = new SceneMessage() SceneMessage msg = new SceneMessage()
{ {
sceneName = newSceneName, sceneName = newSceneName,
sceneMode = loadSceneParameters.loadSceneMode,
physicsMode = loadSceneParameters.localPhysicsMode
}; };
NetworkServer.SendToAll(msg); NetworkServer.SendToAll(msg);
@ -644,7 +640,7 @@ void CleanupNetworkIdentities()
} }
} }
internal void ClientChangeScene(string newSceneName, LoadSceneMode sceneMode, LocalPhysicsMode physicsMode) internal void ClientChangeScene(string newSceneName, SceneOperation sceneOperation = SceneOperation.Normal)
{ {
if (string.IsNullOrEmpty(newSceneName)) if (string.IsNullOrEmpty(newSceneName))
{ {
@ -661,16 +657,32 @@ internal void ClientChangeScene(string newSceneName, LoadSceneMode sceneMode, Lo
Transport.activeTransport.enabled = false; Transport.activeTransport.enabled = false;
// Let client prepare for scene change // Let client prepare for scene change
OnClientChangeScene(newSceneName); OnClientChangeScene(newSceneName, sceneOperation);
loadingSceneAsync = SceneManager.LoadSceneAsync(newSceneName, new LoadSceneParameters() switch (sceneOperation)
{ {
loadSceneMode = sceneMode, case SceneOperation.Normal:
localPhysicsMode = physicsMode, loadingSceneAsync = SceneManager.LoadSceneAsync(newSceneName);
}); break;
case SceneOperation.LoadAdditive:
if (!SceneManager.GetSceneByName(newSceneName).IsValid())
loadingSceneAsync = SceneManager.LoadSceneAsync(newSceneName, LoadSceneMode.Additive);
else
Debug.LogWarningFormat("Scene {0} is already loaded", newSceneName);
break;
case SceneOperation.UnloadAdditive:
if (SceneManager.GetSceneByName(newSceneName).IsValid())
{
if (SceneManager.GetSceneByName(newSceneName) != null)
loadingSceneAsync = SceneManager.UnloadSceneAsync(newSceneName, UnloadSceneOptions.UnloadAllEmbeddedSceneObjects);
}
else
Debug.LogWarning("Cannot unload the active scene with UnloadAdditive operation");
break;
}
// don't change the client's current networkSceneName when loading additive scene content // don't change the client's current networkSceneName when loading additive scene content
if (sceneMode == LoadSceneMode.Single) if (sceneOperation == SceneOperation.Normal)
networkSceneName = newSceneName; networkSceneName = newSceneName;
} }
@ -935,7 +947,7 @@ void OnClientSceneInternal(NetworkConnection conn, SceneMessage msg)
if (NetworkClient.isConnected && !NetworkServer.active) if (NetworkClient.isConnected && !NetworkServer.active)
{ {
ClientChangeScene(msg.sceneName, msg.sceneMode, msg.physicsMode); ClientChangeScene(msg.sceneName, msg.sceneOperation);
} }
} }
@ -1097,12 +1109,23 @@ public virtual void OnClientError(NetworkConnection conn, int errorCode) { }
/// <param name="conn">Connection to the server.</param> /// <param name="conn">Connection to the server.</param>
public virtual void OnClientNotReady(NetworkConnection conn) { } public virtual void OnClientNotReady(NetworkConnection conn) { }
/// <summary>
/// Obsolete: Use <see cref="OnClientChangeScene(string newSceneName, SceneOperation sceneOperation)"/> instead.).
/// </summary>
/// <param name="newSceneName">Name of the scene that's about to be loaded</param>
[EditorBrowsable(EditorBrowsableState.Never), Obsolete("Override OnClientChangeScene(string newSceneName, SceneOperation sceneOperation) instead")]
public virtual void OnClientChangeScene(string newSceneName)
{
OnClientChangeScene(newSceneName, SceneOperation.Normal);
}
/// <summary> /// <summary>
/// Called from ClientChangeScene immediately before SceneManager.LoadSceneAsync is executed /// Called from ClientChangeScene immediately before SceneManager.LoadSceneAsync is executed
/// <para>This allows client to do work / cleanup / prep before the scene changes.</para> /// <para>This allows client to do work / cleanup / prep before the scene changes.</para>
/// </summary> /// </summary>
/// <param name="newSceneName">Name of the scene that's about to be loaded</param> /// <param name="newSceneName">Name of the scene that's about to be loaded</param>
public virtual void OnClientChangeScene(string newSceneName) { } /// <param name="sceneOperation">Scene operation that's about to happen</param>
public virtual void OnClientChangeScene(string newSceneName, SceneOperation sceneOperation) { }
/// <summary> /// <summary>
/// Called on clients when a scene has completed loaded, when the scene load was initiated by the server. /// Called on clients when a scene has completed loaded, when the scene load was initiated by the server.

View File

@ -9,7 +9,8 @@ public void TestPacking()
{ {
SceneMessage message = new SceneMessage() SceneMessage message = new SceneMessage()
{ {
sceneName = "Hello world" sceneName = "Hello world",
sceneOperation = SceneOperation.LoadAdditive
}; };
byte[] data = MessagePacker.Pack(message); byte[] data = MessagePacker.Pack(message);
@ -17,6 +18,7 @@ public void TestPacking()
SceneMessage unpacked = MessagePacker.Unpack<SceneMessage>(data); SceneMessage unpacked = MessagePacker.Unpack<SceneMessage>(data);
Assert.That(unpacked.sceneName, Is.EqualTo("Hello world")); Assert.That(unpacked.sceneName, Is.EqualTo("Hello world"));
Assert.That(unpacked.sceneOperation, Is.EqualTo(SceneOperation.LoadAdditive));
} }
} }
} }