Version: 2017.3
ネットワークのインスタンス化(旧)
マスターサーバー(非推奨)

ネットワークレベルロード(旧)

(Unity 5.1 からは UNET の使用を推奨しています。下記の情報は旧ネットワークシステムのものです。)

以下でマルチプレイヤーゲームでレベルロードする簡単なサンプルを示します。レベルロードの途中でネットワークメッセージの処理が行われないことをチェックしてます。さらにすべて準備が整った後でないかぎりメッセージ送信が行われないこともあわせてチェックしてます。最後にレベルロード完了時にすべてのスクリプトにメッセージ送信を行いレベルロードが終わってなんらかの処理を受け付けできることを示します。SetLevelPrefix 関数により新しくロードしたレベルに不要なネットワーク更新が行われないようにします。不要な更新とは例えば前のレベルでの更新です。このサンプルではグループを使用してゲームデータとグループへのレベルロード通信を分離します。グループ 0 はゲームデータのトラフィックで使用されグループ 1 はレベルロードに使用します。レベルロードの途中ではグループ 0 はブロックされますがグループ 1 は開放されていて、レベルロードの際にチャット通信も別に行うことができるよう開放されてます。

using UnityEngine;
using UnityEngine.Network;
using System.Collections;

[RequireComponent(NetworkView)]
public class ExampleScript : MonoBehaviour {
    string[] supportedNetworkLevels  = new[]{ "mylevel" };
    string disconnectedLevel = "loader";
    int lastLevelPrefix = 0;
    NetworkView networkView;    

    void Awake ()
    {
        // ネットワークレベルの読み込みは、別のチャンネルで行われます
        DontDestroyOnLoad(this);
        networkView = new NetworkView ();
        networkView.group = 1;
        Application.LoadLevel(disconnectedLevel);
    }
    
    void OnGUI ()
    {
        if (Network.peerType != NetworkPeerType.Disconnected)
        {
            GUILayout.BeginArea(Rect(0, Screen.height - 30, Screen.width, 30));
            GUILayout.BeginHorizontal();
            
            foreach (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]
    IEnumerator LoadLevel (string level, int levelPrefix)
    {
        lastLevelPrefix = levelPrefix;
        
        // デフォルトチャンネルのネットワークで、これ以上データを送信する必要はありません。
        // なぜなら、今、レベルを読み込もうとしているところで、すべてのオブジェクトはどのみち削除されるからです。
        Network.SetSendingEnabled(0, false);    
        

        // レベルが最初に読み込まれるべきなので、受信を停止します。
        // レベルが読み込まれたら、そのレベルのオブジェクトにアタッチされたRPCと他のステートの更新を行うことができます。
        Network.isMessageQueueRunning = false;
        
        // レベルから読み込まれたすべてのネットワークビューはNetworkViewID にプレフィックスを得ます。
        // これで、クライアントからの古い更新が新しく作成されたシーンに漏出することを防ぎます。
        Network.SetLevelPrefix(levelPrefix);
        Application.LoadLevel(level);
        yield return;

        // データの受信を再び可能にします。
        Network.isMessageQueueRunning = true;
        // レベルが読み込まれ、クライアントにデータを送信し始めることができます。
        Network.SetSendingEnabled(0, true);

        var gameObjects = FindObjectsOfType(GameObject) as GameObject[];
        foreach (var go in gameObjects)
            go.SendMessage("OnNetworkLoadedLevel", SendMessageOptions.DontRequireReceiver); 
    }
    
    void OnDisconnectedFromServer ()
    {
        Application.LoadLevel(disconnectedLevel);
    }
}

C# スクリプトの例

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;

        // デフォルトチャンネルのネットワークで、これ以上データを送信する必要はありません。
        // なぜなら、今、レベルを読み込もうとしているところで、すべてのオブジェクトはどのみち削除されるからです。
        Network.SetSendingEnabled(0, false);    

        // レベルが最初に読み込まれるべきなので、受信を停止します。
        // レベルが読み込まれたら、そのレベルのオブジェクトにアタッチされたRPCと他のステートの更新を行うことができます。
        Network.isMessageQueueRunning = false;
        
        // レベルから読み込まれたすべてのネットワークビューはNetworkViewID にプレフィックスを得ます。
        //これで、クライアントからの古い更新が新しく作成されたシーンに漏出することを防ぎます。
        Network.SetLevelPrefix(levelPrefix);
        Application.LoadLevel(level);
        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)

JS スクリプトの例

ネットワークのインスタンス化(旧)
マスターサーバー(非推奨)
Copyright © 2023 Unity Technologies
优美缔软件(上海)有限公司 版权所有
"Unity"、Unity 徽标及其他 Unity 商标是 Unity Technologies 或其附属机构在美国及其他地区的商标或注册商标。其他名称或品牌是其各自所有者的商标。
公安部备案号:
31010902002961