Network Level Loading

以下是多人游戏中某个等级加载方式的简单示例。它确保加载等级时不处理任何网络消息。它还确保一切就绪之前都不发送任何消息。最后,当等级加载完毕时,它会向所有脚本发送消息,以便脚本知道此等级已加载,并可以对此做出反应。SetLevelPrefix 函数帮助使新加载的等级始终不进行不需要的网络更新。例如,不需要的更新可能是来自前一个等级的更新。示例还使用群组将游戏数据和等级加载通信分入各群组。群组 0 用于游戏数据流通而群组 1 用于等级加载。加载等级时群组 0 被阻塞,但群组 1 开放,群组 1 还能进行聊天通信以便等级加载时保持开放状态。

var supportedNetworkLevels : String[] = [ "mylevel" ];
var disconnectedLevel : String = "loader";
private var lastLevelPrefix = 0;

function Awake ()
{
    // 网络等级加载在某个单独的通道中完成。
    DontDestroyOnLoad(this);
    networkView.group = 1;
    Application.LoadLevel(disconnectedLevel);
}

function OnGUI ()
{
	if (Network.peerType != NetworkPeerType.Disconnected)
	{
		GUILayout.BeginArea(Rect(0, Screen.height - 30, Screen.width, 30));
		GUILayout.BeginHorizontal();

		for (var level in supportedNetworkLevels)
		{
			if (GUILayout.Button(level))
			{
				Network.RemoveRPCsInGroup(0);
				Network.RemoveRPCsInGroup(1);
				networkView.RPC( "LoadLevel", RPCMode.AllBuffered, level, lastLevelPrefix + 1);
			}
		}
		GUILayout.FlexibleSpace();
		GUILayout.EndHorizontal();
		GUILayout.EndArea();
	}
}

@RPC
function LoadLevel (level : String, levelPrefix : int)
{
	lastLevelPrefix = levelPrefix;

		//没有理由再通过网络在默认的通道上发送数据,
		//因为我们即将加载等级,这样所有那些对象无论如何都将被删除


		//我们需要停止接收,因为首先等级必须先被加载。
		//等级一旦加载,附加到等级中对象的 rpc 状态更新和其他状态更新就可以投入使用

		Network.isMessageQueueRunning = false;

		//从某个等级加载的所有网络视图都将在其 NetworkViewID 中加入一个前缀。
		//这将阻止之前的更新从客户端泄露到某个新创建的场景中。
		Network.SetLevelPrefix(levelPrefix);
		Application.LoadLevel(level);
		yield;
		yield;

		// 允许重新接收数据
		Network.isMessageQueueRunning = true;
		// 现在等级已经加载,我们可以开始给客户端发送数据了
		Network.SetSendingEnabled(0, true);


		for (var go in FindObjectsOfType(GameObject))
			go.SendMessage("OnNetworkLoadedLevel", SendMessageOptions.DontRequireReceiver);	
}

function OnDisconnectedFromServer ()
{
	Application.LoadLevel(disconnectedLevel);
}

@script RequireComponent(NetworkView)

Page last updated: 2013-06-27