要讓網路系統能知道玩家物件的移動,並且確定只有本機的玩家才能操控自己的物件,我們需要更新PlayerController腳本。
在PlayerController腳本中,我們將會做兩個重大的改變:首先需要新的命名空間UnityEngine.Networking,接著要將PlayerController的繼承從MonoBehaviour改為NetworkBehaviour 。
開啟PlayerController腳本,並新增紅字的部分,除了上面提到的兩點外,我們還需要在執行Update時做一個是否為本機玩家的判斷,也就是if(!isLoacalPlayer)這個判斷式。
using UnityEngine; using UnityEngine.Networking; public class PlayerController : NetworkBehaviour { void Update() { if (!isLocalPlayer) { return; } float x = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f; float z = Input.GetAxis("Vertical") * Time.deltaTime * 3.0f; transform.Rotate(0, x, 0); transform.Translate(0, 0, z); } }
命名空間UnityEngine.Networking中,有我們需要的"網路識別"腳本,更多關於命名空間的資訊,可以參考這裡。
這段講UnityEngine.Networking,結果是給命名空間的連結喔‧‧‧
NetworkBehaviour類別是一個基於Monobehaviour的特殊類別。當一個物件需要使用有關網路功能的動作時,該物件下的腳本就必須繼承NetworkBehaviour,更多關於NetworkBehaviour的資訊可以看這裡或這裡。
接著看到使用!isLocalPlayer的地方,"LocalPlayer"是NetworkBehaviour下的一部分,而且所有從NetworkBehaviour衍生出的腳本都能了解"LocalPlayer"這個概念。什麼是LocalPlayer,以及它在多人連線HLAPI的專案架構中,是如何運作的,更多資訊可以參考HLAPI的網頁。
在一個有網路系統的專案裡,伺服器和全部的用戶端會在同一時間,在同一個物件的腳本上,執行相同一段的程式碼。這代表如果一個伺服器和兩個用戶端的情況,將會有六個玩家物件同時執行,因為在伺服器中,會有兩個用戶端的玩家,而兩個用戶端都包含自己和對方,合計就有六個玩家物件。
所有的玩家物件都是從同一個Player prefab生成的,並且共享同一個PlayerController腳本。所以需要在腳本中了解自己擁有的玩家物件是哪一個,就必須使用LocalPlayer做判斷。當某個用戶端連接到伺服器時,NetworkManager會使用Player prefab生成玩家物件並設置其所有權。這時在該用戶端上生成的物件將會標註為LocalPlayer,而其他用戶端所生成的物件則不會在該用戶端上標註LocalPlayer。
所以透過if(!isLoacalPlayer)return;判斷式,腳本可以確定接下來的內容只會在LoacalPlayer的狀況下執行,其他情況則會直接忽略之後的內容。
到這裡我們像上一篇一樣,開啟主機端和用戶端同時執行兩個範例,會發現各自的移動結果還是沒辦法保持同步,移動旋轉的輸入還是只能在本機端更新,並不會更新到網路上。
要讓各個玩家的物件保持同步,需要新增NetworkTransform元件到Player prefab上。
- 點選Player prefab
- 新增元件Network > NetworkTransform
NetworkTransform可以在網路上同步物件的transform 數值。當玩家按下按鍵,輸入移動旋轉數值,首先會判斷是否為本地玩家,之後NetworkTransform會同步移動、旋轉和縮放等數值給伺服器和全體用戶端,讓伺服器和用戶端對各自輸入的數值,更多關於NetworkTransform的資訊可以參考這裡。
上一篇:測試連線時玩家物件的移動腳本
下一篇:測試多人連線的移動
沒有留言:
張貼留言