NetworkBehaviour是在UNet中代替MonoBehaviour的基底類別。
要存取物件的網路資訊都必須透過NetworkBehaviour才能達成,因此在撰寫網路物件的新腳本時必須將繼承的MonoBehaviour改為NetworkBehaviour。
若要使用UNet相關API,必須先引入UnityEngine.Networking
using UnityEngine.Networking;
一個空的網路腳本大致上會像這樣
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; public class Move : NetworkBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () { } }
在開始介紹之前大家必須先有些基本概念:
在多人連線的處理上,「應當」一切遵從於「Server」,也就是說Server必須掌握大權,所有玩家是單純同步於Server處理後的結果,這樣的主從關係是必須的,否則會造成A玩家與B玩家在顯示上或計算上出現差異。
但有時為了讓玩家畫面表現流暢,不會被等待中的封包影響流暢性,會讓Client自行處理一些判斷讓整體更加順暢,例如:Client端發出攻擊指令時自行處理動畫演出與扣血、傷害等等,待伺服器回傳資料後進行校正。
NetworkBehaviour中有幾項常用的屬性
- hasAuthority – 玩家是否擁有控制權
- 可以用於各玩家的角色上,由Client端發出請求讓Server執行動作,如移動、攻擊等等。
- isServer – 是否是在伺服器端運行
- 十分常用的屬性,在撰寫遊戲邏輯時都需要以Server為基準
- isClient – 是否是在客戶端運行
- 有些腳本只需要Server去處理,Client便可以移除掉以節省效能
- isLocalPlayer – 是否屬於本地玩家
- 在連線成功時Server會替玩家創造一個Player物件,在#1的教學中即是PlayerActor,可以透過isLocalPlayer判斷此Player是否屬於自己。
- 這個屬性和hasAuthority類似,但只有Player物件的isLocalPlayer會返回True,而Player物件亦是唯一的。
將上一篇教學中提到的Move程式碼更改成以下
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; public class Move : NetworkBehaviour { public float speed = 3; // Use this for initialization void Start () { } // Update is called once per frame void Update () { if (!isLocalPlayer) { return; } float x = Input.GetAxis("Horizontal"); float y = Input.GetAxis("Vertical"); transform.Translate(new Vector2(x,y) * Time.deltaTime * speed); } }
這樣各自玩家就只能操控自己的物件,而不會每個相同的物件都被移動到。
順待一提,若物件添加了NetworkTransform,Client端擁有控制權的物件會自動將位置同步至Server而非同步於Server。
本篇教學到此結束,感謝大家的閱讀!