unity之network客戶端向服務器發送消息【Command】方法詳解

如果是純粹是聊天室功能則可以使用NetworkView的方法來進行,簡單實用。

如果不是聊天室功能而是要傳遞數據給服務器,同時爲了以後更多功能的拓展性,還是應該用network manager來實現。

無論是哪種方式,unet裏的的一個特點就是:服務器端是會包括客戶端的。換言之客戶端和服務器是在同一個場景裏開發的。。。此處的包括二字何解?就是服務器端會自動生成一個player(之前很多文章都在講unet的player與服務器同步的問題,那是入門級別的東西,多看看就知道是怎麼回事)。這個player身上具備的屬性就是客戶端的玩傢俱備的屬性。當然這個player只是代指客戶端而已。實際可以理解爲在networkmanager裏自動生成一個客戶端。

如果是做局域網的傳輸,在networkmanager裏一定要注意不要勾選use websockets這一項。

本文案例爲局域網,需求是客戶端進行考覈之後,客戶端的系統邏輯會判斷出分數,然後將分數傳給服務器。而此處只說如何從客戶端把分數傳給服務器這一功能。

開始搞起:

新建一個場景,內容network(空物體)、client(紅色的cube)、UI的Text顯示文本(需要把客戶端傳來的值顯示出來)。

然後在network物體上添加上networkmananger組件和managerHUD組件。不需要其他的另外的腳本了。

client這個物體添加network identity,和我寫的Clientmanager腳本

然後看Clientmanager腳本的具體內容,如下:

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using UnityEngine.UI;

public class clientmanager : NetworkBehaviour
{
    private Text GetTexts;    
   
    //[SyncVar]/// 用來標記同步成員變量,可以是任何基本數據類型,但不能是類、列表或其他集合
    private int scores = 95;
    // Use this for initialization
    void Start()
    {      
        GetTexts = GameObject.Find("Canvas").gameObject.transform.FindChild("Text").gameObject.GetComponent<Text>();       
    }

    // Update is called once per frame
    void Update()
    {
        if (isLocalPlayer)
        {
            if (Input.GetMouseButtonDown(1))
            {
                Debug.Log("點擊右鍵發送");
                //爲了測試每次點擊讓分數+2
                scores += 2;
                CmdSendMessage(scores);
            }            
        }

    }


    ///加了Command之後,該方法必須Cmd開頭,方法雖然寫在客戶端的腳本里,但是是在服務器執行的,所以執行的效果也是隻有服務器能看到。

    [Command]
    void CmdSendMessage(int i)
    {              
        GetTexts.text += i.ToString() + "在服務器端執行\n";        
    }
}

 

這樣打包來進行測試,打開兩個,一個作爲服務器,另一個打開的作爲客戶端。

當鼠標右鍵點擊客戶端的時候會看到,在服務器的Text顯示列表中會不斷的打印出東西,說明完成了客戶端的數據上穿到服務器功能:

至此功能已經完成了。。。下面的文字用來解釋原理。

 


然後說說原理吧,可以看到,服務端我們沒有綁定自己寫的任何腳本,同步功能用了系統 的networkmanager,在初始化的時候就會自動生成了客戶端,UI用的是系統自帶的network namager HUD來實現的,所以重點是在客戶端了。

客戶端的代碼也非常簡單,在Update裏面確定了是isLocalPlayer也就是說只有本地客戶端的時候就可以進行右鍵點擊,當右鍵點擊的時候就會給初始化的scores = 95這值加2,然後調用了CmdSendMessage(scores);這個方法,把分數的值作爲參數傳遞。

重點說說[Command]這個玩意,雖然之前的文章中說過它的功能但此處還是再詳細講解下。如下述:

CmdSendMessage();這個方法是被 [Command]標記過的,所以是會在服務器端執行的,不會再本地執行。如果取消了[Command]的標誌那就肯定只在本地執行了也就是完全的本地的方法啊和服務端沒關係。。。所以如果沒有[Command]的標誌,上圖中的那些值就會在本客戶端顯示出來而不會顯示在服務器。

所以最後的總結就是:如果要從客戶端把數據傳到服務器,腳本綁定到客戶端,並且需要在對應的方法前加上 [Command],這樣這個方法雖然寫在客戶端但是實際運行會在服務端,運行的效果也只會呈現在服務端而不是客戶端。

發佈了187 篇原創文章 · 獲贊 143 · 訪問量 78萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章