在本教學中將在子彈物件上新增網路功能,我們必須對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;
}
}
到這裡我們就像先前一樣測試結果,現在看下空白鍵應該可以在所有用換端上顯示正確的結果,每位玩家應該都能夠將子彈射到其他人身上。但是目前此射擊功能不會造成任何影響,所以在下一篇我們會製作玩家血量。
上一篇:射擊(單機)
下一篇:玩家血量(單機)
建立一個簡單的多人連線範例


沒有留言:
張貼留言