Unity Network 使用小結

zhutaorun發表於2015-10-27

Unity提供了NetWork的方法來實現網路連線,而實際專案中缺很少備用到了。這裡作為了解NetWork的使用,做了一個CS區域網遊戲的功能

建立伺服器和連線客戶端的方法

using UnityEngine;
using System.Collections;

public class MyNetwork : MonoBehaviour
{
    public int connections = 10;
    public int listenPort = 8899;
    public bool useNat = false;
    public string ip = "127.0.0.1";
    public GameObject playerPrefab;
	void OnGUI()
    {
	    if (Network.peerType == NetworkPeerType.Disconnected)
	    {
	        if (GUILayout.Button("建立伺服器"))
	        {
	            //進行建立伺服器的操作
	            NetworkConnectionError error = Network.InitializeServer(connections, listenPort, useNat);
	            print(error);
	        }
	        if (GUILayout.Button("連結伺服器"))
	        {
	            NetworkConnectionError error = Network.Connect(ip, listenPort);
                print(error);
	        }
	    }
        else if (Network.peerType == NetworkPeerType.Server)
        {
            GUILayout.Label("伺服器建立完成");
        }
        else if(Network.peerType == NetworkPeerType.Client)
        {
            GUILayout.Label("客戶端已經接入");
        }
	}

    //注意,這兩個方法都是在伺服器上呼叫的
    private void OnServerInitlized()
    {
        print("Server 完成初始化");
        //Network.player;//訪問到當前的player,客戶端
        int group = int.Parse(Network.player + "");//直接訪問Network.player會得到當前客戶端的索引是唯一的
        Network.Instantiate(playerPrefab,new Vector3(0,10,0),Quaternion.identity,group );
    }

    private void OnPlayerConnected(NetworkPlayer player)
    {
        print("一個客戶端連線過來,Index,number:" +player);
    }

    private void OnConnectedToServer()
    {
        print("我成功連線到伺服器了");
        int group = int.Parse(Network.player + "");//直接訪問Network.player會得到當前客戶端的索引是唯一的
        Network.Instantiate(playerPrefab, new Vector3(0, 10, 0), Quaternion.identity, group);
    }
    //network view 元件用來在區域網之內去同步一個遊戲物體的元件屬性
    //network view 會把建立出來的客戶端作為主人,就是主客戶端,其他的客戶端都是會以主客戶端為準
}


Network

class in UnityEngine

Description

The network class is at the heart of the network implementation and provides the core functions.

This class configures the network interface and all the network parameters. You use it to set up a server or connect to one and have a row of helper functions to help you with those tasks. For more information on what is exposed in the editor see the Network Manger component reference.

NetworkConnectionError error = Network.InitializeServer(connections, listenPort, useNat);

建立伺服器,連線數,埠,是否使用Nat功能;

Network.InitializeServer(connections, listenPort, useNat)<span style="color: rgb(27, 34, 41); line-height: 1em; font-family: 'Open Sans', sans-serif; background-color: rgb(255, 255, 255);"> Description</span>

Initialize the server.

connections  the number of allowed incomingis connections (note that this is generally not the same as the number of players). listenPortis the port number we want to listen to. useNat sets the NAT punchthrough functionality. If you want this server to be able to accept connections using NAT punchthrough, using the facilitator, set this to true.

連線錯誤,通過Debug,可以判斷連線是否成功

NetworkConnectionError error<span style="color: rgb(27, 34, 41); line-height: 1em; font-family: 'Open Sans', sans-serif; background-color: rgb(255, 255, 255);"> Description</span>

Possible status messages returned by Network.Connect and in OnFailedToConnect in case the error was not immediate.

OnServerInitlized,<span style="font-family: Arial, Helvetica, sans-serif;">OnConnectedToServer 是Unity提供的伺服器建立成功,客戶端連線到伺服器的執行</span>

在Network建立物體的方法由GameObject.Instantiate=>Network.Instantitae。原因是不論是客戶端和伺服器都要同步相應的建立操作,原來的方法顯然是不能滿足的。

private void OnServerInitialized()
{
        //服務端
        //GameController.Instantiate(soldierPrefab, pos1.position, Quaternion.identity);
        NetworkPlayer player = Network.player;
        int group = int.Parse(player + "");
        GameObject go = Network.Instantiate(soldierPrefab, pos1.position, Quaternion.identity, group) as GameObject;
        go.GetComponent<Player>().SetOwnerPlayer(Network.player);// 這個程式碼值設定了當前建立者的戰士的ownerPlayer屬性,在其他客戶端這個屬性是為null的
        //RPC:遠端過程呼叫
        go.networkView.RPC("SetOwnerPlayer",RPCMode.AllBuffered,Network.player);//完成一個遠端呼叫,會執行所有連線的客戶端上的setownerplayer方法
        Screen.showCursor = false;
}
go.GetComponent<Player>().SetOwnerPlayer(Network.player);// 這個程式碼值設定了當前建立者的戰士的ownerPlayer屬性,在其他客戶端這個屬性是為null的
是呼叫伺服器本地的方法。
go.networkView.RPC("SetOwnerPlayer",RPCMode.AllBuffered,Network.player);//完成一個遠端呼叫,會執行所有連線的客戶端上的setownerplayer方法
呼叫客戶端執行相同的方法。

關於RPC要解釋下,“SetOwnerPlyer” 方法名,類似SeneMessage方法,RPCMode.AllBuffered通知所有物件和快取。


[RPC]//使用這個註解表示這個方法是一個遠端呼叫的方法
    public void SetOwnerPlayer(NetworkPlayer player)
    {
        this.ownpalyer = player;
        if (Network.player != player)
        {
            LoseControl();//如果當前角色不是這個戰士的建立者,就要把戰士的控制禁用掉
        }
    }
    


相關文章