在本教學中將在子彈物件上新增網路功能,我們必須對Bullet prefab及腳本做更新。
首先,Bullet prefab需要NetworkIdentity元件讓網路系統能辨識它,接著需要NetworkTransform同步移動和旋轉,最後必須在NetworkManager的Spawnable Prefab上註冊。
- 在project視窗下點擊Bullet prefab
- 新增元件Network->NetworkIdentity
- 新增元件Network->Network Transform
- 將Network Transform下的Network Send Rate設為0
- 點擊Hierarchy視窗下的NetworkManager
- 在NetworkManager元件下找到Spawn Info並展開
- 看下Registered Spawnable Prefabs清單旁的+按鈕新增一個項目
- 將Bullet prefab拖曳上去
在先前我們談到如何在網路環境中製作移動系統,在多人連線的系統下,基本上伺服器和所有用戶端,會同時在相同物件上執行相同的程式碼,那時我們使用isLocalPlayer來讓各用戶端判斷自己的物件,並只針對該物件做控制。
現在我們要新增的是另一個控制屬性 [Command] , [Command] 屬性代表在它底下的函式將由用戶端呼叫,但由伺服器執行,該函數中的任何參數將透過Command自動傳給伺服器,Command只能由本機玩家送出,當一個函式要製作成網路Command時,必須以"Cmd"開頭命名,更多關於[Command] 的資訊請點這裡。
現在我們把PlayerController腳本打開,找到Fire函式並在它上面新增[Command] ,並將Fire重新命名為CmdFire。
[Command] void CmdFire()接下來要談的是多人連線中一個有點特別的概念;Network Spawning(網路生成)。
"Spawn"在多人連線中不僅僅是"生成",更代表在伺服器及所有用戶端上產生一個物件。這個物件將由Spawning系統管理;當這個物件在伺服器上有狀態更新時,系統會發送狀態資訊給所有用戶端,例如當某用戶端物件被銷毀,伺服器就會將此狀態發送給所有用戶端,當伺服器上的物件被銷毀,用戶端的該物件也將被銷毀,而且該物件會被新增至伺服器管理的物件集合中,以便讓後來加入的其他用戶知道該物件的正確狀態。更多關於Network Spawning的資訊,可以參考這裡。
在CmdFire中新增NetworkServer.Spawn。
NetworkServer.Spawn(bullet);完成後PlayerController腳本會像這樣:
using UnityEngine; using UnityEngine.Networking; public class PlayerController : NetworkBehaviour { public GameObject bulletPrefab; public Transform bulletSpawn; 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); if (Input.GetKeyDown(KeyCode.Space)) { CmdFire(); } } // This [Command] code is called on the Client … // … but it is run on the Server! [Command] void CmdFire() { // Create the Bullet from the Bullet Prefab GameObject bullet = (GameObject)Instantiate( bulletPrefab, bulletSpawn.position, bulletSpawn.rotation); // Add velocity to the bullet bullet.GetComponent<Rigidbody>().velocity = bullet.transform.forward * 6; // Spawn the bullet on the Clients NetworkServer.Spawn(bullet); // Destroy the bullet after 2 seconds Destroy(bullet, 2.0f); } public override void OnStartLocalPlayer () { GetComponent<MeshRenderer>().material.color = Color.blue; } }到這裡我們就像先前一樣測試結果,現在看下空白鍵應該可以在所有用換端上顯示正確的結果,每位玩家應該都能夠將子彈射到其他人身上。
但是目前此射擊功能不會造成任何影響,所以在下一篇我們會製作玩家血量。
上一篇:射擊(單機)
下一篇:玩家血量(單機)
建立一個簡單的多人連線範例
沒有留言:
張貼留言