1. 程式人生 > 實用技巧 >Unity元件Network(非原創)

Unity元件Network(非原創)

1.網路管理物體

搭建網路,需要先建立一個空物體用來新增網路管理元件,首先要給空物體新增以下兩個元件

注意事項: 1. OffLine Scene代表客戶端連線伺服器前,等待的場景(遊戲大廳)

. OnLine Scene代表客戶端連線伺服器後的場景 (遊戲場景)

2.Spawn Info 伺服器卵生資訊 : 把網路預設體(必須掛有網路元件) 拖入PlayerPrefab , 伺服器會把遊戲物件孿生到所有連線的客戶端中

二.遊戲物件

1.Network Identity

遊戲物件(網路預設體)需要掛Network Identity元件,該元件是網路的核心,由伺服器Spwan(卵生)的物體都必須具備,該元件在卵生的時候會自動分配assetID和許可權

注意事項:1.ServerOnly 勾選後物體只在伺服器中存在

2.Local Player Authority勾選後在客戶端中存在

2.實現狀態同步

遊戲物件的控制指令碼需要繼承NetWorkBehaviour元件(依賴於NetWorkIdentity),用來實現RPC技術和狀態同步屬性. 1.Transform同步 這個元件負責玩家物件在客戶端發出移動指令後,把該玩家的移動同步到所有客戶端中

注意事項:1.Net Work Send Rate 表示同步Transform的頻率

2.Transform Synv Mode 表示同步的模式,可以選擇同步剛體元件,角色控制器等

然後在控制指令碼編寫程式碼

public class ControlMove : NetworkBehaviour {
   
    void Update() {
        if (!isLocalPlayer)   //判斷是否是本地客戶端
        {
            return;
        }
        float x = Input.GetAxis("Horizontal");
        float y = Input.GetAxis("Vertical");
        if (x != 0 || y != 0)
        {
            transform.position += new Vector3(x, 0, y);
        }

這裡需要注意的有兩點 1.所有網路控制指令碼必須要繼承 NetWorkBehaviour

2.在Update裡需要先判斷是否是本地客戶端,不是的話Return~!!! 如果沒有這個判斷條件,在客戶端發出指令,網路裡所有的客戶端都會執行

2.發射子彈與減血的同步

經過上邊的步驟,已經可以實現物體在網路裡的移動,但我們想要實現在網路裡發射子彈,受到攻擊後還要減血,這些指令都需要在伺服器上執行,先來看一下NetWorkBehaviour的常用特性

[SyncVar] 用於標識序列化變數,實現變數同步 例: (把Hp標識,就可以實現同步減血)

[Client] 表示只能在客戶端呼叫

[ClientCallBack] 表示客戶端執行的回撥

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

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

直接來看程式碼如何使用:

 //將血量設定為網路同步變數
    [SyncVar]
    float hp = 100;
    public Slider slider;       //顯示血量的血條
    public GameObject bullet;   //子彈預設體
    void Start () {
        ClientScene.RegisterPrefab(bullet); //在場景註冊預設體
    }
    void Update () {
        // 2.將血量的值賦給slider
        slider.value = hp / 100f;
        if (!isLocalPlayer)
        {
            return;
        }     
        if (Input.GetKeyDown(KeyCode.Q))
        {
            CmdReduceHp();
        }
        if (Input.GetKeyDown(KeyCode.T))
        {
            CmdFire();
        }
    }
    //減血的方法   標識為Command由伺服器執行
    //字首必須是Cmd 開頭
    [Command]
    public void CmdReduceHp()
    {
        hp -= 10;
    }
     //發射子彈的方法
    [Command]
    public void CmdFire()
    {
        GameObject a= Instantiate(bullet, transform.position+transform.right, Quaternion.identity);
        a.GetComponent<Rigidbody>().AddForce(transform.right*100);   //給子彈新增向右的力
        NetworkServer.Spawn(a);   //由伺服器卵生給連線的客戶端
    }

注意事項:1.網路預設體需要先在客戶端場景裡註冊一下,才能正常產生

2.hp賦值給Slider要寫在判斷是否是本地客戶端前,血條才會正常同步顯示

3.Command修飾的方法,由客戶端發起,服務端執行,方法名前必須加Cmd

4.監聽鍵盤事件的Iput.GetKeyDown要放在Update裡,不能放在Cmd方法裡!!! (此時方法由伺服器呼叫,無法監聽鍵盤事件)

3.動畫的同步

要實現遊戲物件的動畫同步,還需要新增一個網路元件,並給元件指定Animator,並勾選Animator裡包含的動畫.

動畫同步需要注意一點,過度條件是Trigger時需要由客戶端發起指令,在服務端執行,再分發給各個客戶端執行,其他條件正常.

這裡Animator的兩個動畫,attack01條件是bool,attack02條件是Trigger ,程式碼如下:

    Animator ani;  
    void Start()
    {
        ani = GetComponent<Animator>();
    }
     void Update () {
     if (Input.GetKeyDown(KeyCode.Q)) 
        {
            ani.SetBool("attack01", !ani.GetBool("attack01"));        
        }
        if (Input.GetKeyDown(KeyCode.E))
        {
            CmdAttack02();
        }
    }
    [Command]    //伺服器執行
    void CmdAttack02()
    {
        RpcPlayTrigger();
    }
    [ClientRpc]   //由伺服器端呼叫,在客戶端執行 
    void RpcPlayTrigger()
    {
        ani.SetTrigger("attack02");
    }