本篇使用的是5.3版後有UNET的UNITY
目標:基本連線遊戲機制+發射物體同步到其他玩者
1.延續前篇(UNET連線遊戲(一){FPS基本設置&重生點})
- 撰寫我們的槍枝(發射器)程式 GunController.cs
using UnityEngine; using System.Collections; using UnityEngine.Networking; public class GunController : NetworkBehaviour { private float power = 800.0f; private Transform playerCamera; void Start () { playerCamera = transform.FindChild("FirstPersonCharacter"); } void Update () { if(isLocalPlayer) { if(Input.GetButtonDown("Fire1")) { CmdSpawnAmmo(); } } } [Command] void CmdSpawnAmmo () { GameObject instance = Instantiate (Resources.Load ("Ammo")) as GameObject; instance.name = "Ammo"; instance.transform.position = playerCamera.position + playerCamera.forward * 1.5f + playerCamera.up * -.5f; instance.GetComponent<Rigidbody> ().AddForce (playerCamera.forward * power); // NetworkServer.Spawn (instance); } }
參數宣告的部分
power是準備賦予子彈的力道
playerCamera是為了取得主角的攝影機視角(位置座標)
重點在於[Command]標籤以及帶有Cmd字眼的function
這是要給伺服器看的命令方法的命名潛規則
此方法內除了一般的常用寫法,多了一條
NetworkServer.Spawn (instance);
專為網路用戶準備的動態生成功能(基於Network架構下) - 幫我們的PLAYER掛上這支程式,執行專案就可以看到滑鼠左鍵可以打出物件,但還不會移動。
*所以才可以拍出這麼高難度的照片。 - 幫我們的Ammo掛上Rigidbody賦予物理現象
- 若希望子彈可以一段時間後消失,我們需要另隻程式加到子彈上 AmmoController.cs
using UnityEngine; using System.Collections; using UnityEngine.Networking; public class AmmoController : NetworkBehaviour { private float lifeTime; public float maxTime = 3.0f; void Start () { lifeTime = 0.0f; } [ServerCallback] void Update () { lifeTime += Time.deltaTime; if( lifeTime > maxTime ) { NetworkServer.Destroy(gameObject); } } }
透過[ServerCallback]下的Update () 檢查是否大於最大生存時間,並將其刪除
2.網路同步
- 執行遊戲HOST球可以正常打出也會消失,一切都完美了!?
連線測試一下,發現Host可以看到Client打出的子彈,Client端反而看不到
*原因是這樣:
這個子彈是交由SERVER處理生成的,變成只有開房的Host才可以看到這個物件,Client反而看不到由自己下達指令,請SERVER生出的物件 - 解決方案:
到我們的NetworkManager找到RegisteredSpawnable Prefab點下+號新增一個欄位並且把Ammo放入,把這個預製物件註冊
- 而且記得再子彈上加入Network>NetworkTransform 用來同步位移資訊
*詳細步驟請見(UNET基礎介紹)