Unity3D-network網絡相關(二)

    <一>NetworkManager 類創建服務器和客戶端

<1>NetworkServer類負責創建服務器監聽接口,管理客戶端的連接 

它也負責處理遊戲相關的一些特性 :玩家管理 ,監聽,卵生對象和消息處理

 

Server方法 

靜態方法                 功能

Listen                   根據指定端口開啓服務器

RegisterHandler   註冊回調函數  (接受客戶端連接請求)

Spawn                  在所有已準備的客戶端上實例化物體

 SpawnWithClientAuthority   跟Spawn() 方法一樣 並且設置客戶端權限

Destroy                 在所有客戶端上刪除物體

AddPlayerForConnection   將卵生的物體與客戶端建立關係

 

Server屬性

靜態變量                     功能

active                     檢查服務器是否開啓

connections           當前所有連接的客戶端列表

handles                  以字典形式返回服務器註冊的所有回調方法

listenPort               服務器監聽端口

localClientActive   在服務器上的客戶端,即爲主機是返回true

maxDelay               連接之間發送數據的最大延遲

 

創建服務器

需要引入using UnityEngine.NetWorking ; 系統

Button StartServerButton;

void OnEnable(){

Application.runInBackground=true;

StartServerButton=GetComponent<Button>();

StartServerButton.onClick.RemoveAllListeners;

StartServerButton.onClick.AddListener(StartServer);

}

 

void StartServer(){

//服務器是否打開

if(!NetworkServer.active){

//根據指定端口  開啓服務器

NetworkServer.Listen(7777);

}

//接受客戶端連接請求

 

}

 

 

 

<二>NetworkClient該類對象負責連接服務器,並與服務器通信(即收到服務器消息和發送消息給服務器)

Client方法

對象方法                         功能

Connect                  根據指定IP和Port連接服務器

RegisterHandler      註冊回調函數

 

創建客戶端

需要引入using UnityEngine.Networking;系統

 

Button clientButton;

NetworkClient client;

void OnEnable(){

clientButton=GetComponent<Button>();

clientButton.onClick.AddListener(Connect);

}

void Connect(){

//創建了一個客戶端對象

client=new NetworkClient();

//註冊回調函數

client.RegisterHandler(MsgType.Connect,OnClientConnect);

//連接服務器

client.Connect("127.0.0.1",7777);

}

//成功連接服務器之後

void OnClientConnect(NetworkMessage msg){

print("連接服務器成功");

 

}

 

 ****完整代碼****

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking ;
using UnityEngine.UI ;
public class NetworkMangerScr : MonoBehaviour {

    // 1.創建服務器按鈕
    Button iButton;
    //8.連接服務器按鈕
    Button CButton;
    //12.客戶端對象
    NetworkClient m_client;
    //17.網絡預設體
    public  GameObject m_prefab;
    void Awake(){
        m_client = new NetworkClient ();
        Application.runInBackground = true;
        iButton = GameObject.Find ("IButton").GetComponent <Button > ();
        CButton = GameObject.Find ("CButton").GetComponent <Button > ();
        //2.移除
        iButton.onClick.RemoveAllListeners ();
        //3.綁定
        iButton.onClick.AddListener (InitServerAction);
        //9.移除
        CButton.onClick.RemoveAllListeners ();
        //10.綁定
        CButton.onClick.AddListener (ConnectSever );
    
    }
    //11連接服務器的點擊事件
    void ConnectSever(){
        //13.連接服務器
        m_client.Connect("127.0.0.1",3456);
        //14.註冊連接成功的回調方法
        m_client.RegisterHandler (MsgType.Connect ,OnConnectSever );
    }
    //15.連接成功的回調方法
    void OnConnectSever(NetworkMessage msg){
        print ("連接服務器成功");

        //16.場景已經準備好   客戶端場景準備進入Game窗口 conn 客戶端連接準備

        ClientScene.Ready (msg.conn);
        //18.向服務器註冊玩家預設體
        ClientScene.RegisterPrefab (m_prefab );
        //19.添加一個玩家 使用該方法之後 服務器端的MsgType.AddPlayer 註冊方法就會調用
        ClientScene.AddPlayer (0);
    


    }
    //4.創建服務器的點擊事件
    void InitServerAction(){
        //根據指定端口 開啓服務器
        NetworkServer.Listen (3456);
        //6.接受客戶端連接請求
        NetworkServer.RegisterHandler (MsgType.AddPlayer ,OnServerAddPlayer);
        //23.
        m_client =ClientScene.ConnectLocalServer ();
        m_client.RegisterHandler (MsgType.Connect ,OnConnectSever);
    }
    //7.玩家在服務器創建玩家對象的回調方法
    void OnServerAddPlayer(NetworkMessage msg){
        //20.在服務器端 實例化網絡對象

        GameObject obj=Instantiate (m_prefab ,Vector3.zero ,Quaternion.identity );

        //21. 將創建的遊戲對象與某個玩家建立聯繫,表示該obj由客戶端生成

        NetworkServer.AddPlayerForConnection (msg.conn,obj,0);
        //22.將遊戲對象卵生到所有客戶端
        NetworkServer.Spawn (obj);
    }
    void Start () {
      
    }
    
    // Update is called once per frame
    void Update () {
        
    }

}

<二>Unity網絡卵生

網絡中 ,所有網絡對象都應該由服務器產生

客戶端玩家對象生成步驟:

1.客戶端發請求

2.服務器接收請求後實例化客戶端對象

 

卵生對象步驟

1.新建預設體,添加NetworkIdentity組件 標示爲網絡物體

2.客戶端調用ClientScene.Ready() 方法告知服務器自己已準備好

3.客戶端調用ClientScene.RegisterPrefab()提前 註冊網絡預設體

4.客戶端調用ClientScene.AddPlayer()方法告訴服務器執行卵生對象的程序,參數即給將要產生卵生對象貼一個IP

5.服務器RegisterHandler-->MsgType.AddPlayer的回調AddPlayer

6.服務器在AddPlayer方法實例化物體,調用Spawn方法卵生

<三>Unity狀態同步

1.NetworkIdentity組件是網絡的核心 用NetworkServer.Spawn卵生的物體都必須具備該組件

該組件在卵生的時候會自動分配assetld和權限

 

2.NetworkBehaviour組件是一個特殊組件,它依賴NetworkIdentity組件,用來實現RPC技術和狀態同步屬性.

我們想實現狀態同步 則網絡物體的控制腳本必須繼承自NetworkBehaviour

 

NetworkBehaviour組件包含的常用特性[Attribute]

特性                         功能

[SyncVar]               用於標識序列化變量,實現變量同步

[Client]                   表示只能在客戶端調用

[ClientCallback]     表示客戶端執行的回調

[Command]            表示客戶端向服務端發送的命令,在服務端執行

[ClientRpc]             表示服務端向客戶端發送的命令,在客戶端執行

***特別注意動畫同步中 ,參數爲Trigger的最爲特殊 服務端不能直接執行該動畫 因此需要先在客戶端執行然後再在服務端執行

完整代碼 (續上面代碼)

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking ;
using UnityEngine.UI ;
public class PlayerScript : NetworkBehaviour {
    //血量   客戶端執行服務端調用
    [SyncVar]
    float hp=100f;
    public GameObject bullet;
    Slider hpSlider;
    void Awake(){
        hpSlider = transform.Find ("Canvas/HpSlider").GetComponent <Slider >();
    }
    // Use this for initialization
    void Start () {
        //卵生到客戶端
        ClientScene.RegisterPrefab (bullet );
    }
    
    // Update is called once per frame
    void Update () {
        //實時更新血條
        hpSlider.value =hp/100f;
        //判斷是不是本地客戶端
        if (!isLocalPlayer) {
            return;
        }
        //控制移動
        float hor=Input.GetAxis ("Horizontal");
        float ver = Input.GetAxis ("Vertical");
        if (ver!=0 ||hor!=0) {
            
            transform.position += new Vector3 (hor, ver, 0f) * 5f*Time.deltaTime ;
        }
        if (Input.GetKeyDown (KeyCode.Space )) {
            //發射子彈
            CmdFire ();
            
        }
    }
    //發射子彈
    //由[Command]修飾的方法 表示客戶端調用 服務器執行 方法的名字必須以Cmd開頭
    [Command]
    void CmdFire(){
        
        GameObject obj = Instantiate (bullet, transform.position+transform.right, Quaternion.identity);
        obj.GetComponent <Rigidbody > ().AddForce (transform.right  *1000f);
        NetworkServer.Spawn (obj);
    }
    void OnTriggerEnter(Collider other){
        CmdDemage ();
        Destroy (other.gameObject );
    }
    [Command ]
    void CmdDemage(){
        hp -= 20f;

    }

}

 

(動畫狀態同步重點)

完整代碼

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking ;
public class PlayerController : NetworkBehaviour {
    Animator ani;
    // Use this for initialization
    void Start () {
        ani = GetComponent <Animator > ();
    }

    void Update () {
        if (!isLocalPlayer ) {
            return;
        }

        float ver = Input.GetAxis ("Vertical");
        float hor = Input.GetAxis ("Horizontal");
        transform.position += new Vector3 (hor,ver,0)*5f*Time.deltaTime ;
        if (Input.GetKeyDown (KeyCode.Alpha1 )) {
            //攻擊
            ani.SetBool ("Attack",!ani.GetBool ("Attack"));
        }
        if (Input.GetKeyDown (KeyCode.Alpha2 )) {
            //跳躍
            CmdJump ();
        }

    }



    [Command ]
    void CmdJump(){
        //告訴服務器要執行代碼 服務器去通知其他客戶端執行Trigger控制的動畫
        RpcJump ();
    }
    [ClientRpc ]
    void RpcJump(){
        ani.SetTrigger ("Jump");
    }

}

 

<四>RPC(遠程過程調用)技術

 

需要引入Using UnityEngine.Networking; 系統

網絡系統可以實現客戶端和服務器的通信,則稱之爲:遠程調用Remote Procedure Calls 即RPC

RPC框架可以方便實現方法調用 

Unity中有倆種類型: 客戶端調用服務器方法(Command)  

                              服務器調用客戶端方法(ClientRpc)

<完整代碼看上面>

<五>Unity網絡管理器

重點

網絡管理器(NetworkManager)是Unity新版網絡HLAPI中的一個核心組件 ,該組件封裝了網絡創建,運行和Debug等各種方法

初級開發者,不需要寫一行代碼,即可實現簡單的網絡遊戲

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章