[Unity] Mirror Networking 物件位置、動畫、剛體同步組件使用教學

發表日期:
2021.02.08
/
分類:
在多人連線系統中,要讓一個物件的行為能同步到所有客戶端的行為稱為 RPC (Remote Procedure Call),在 Mirror 中也不例外。 Mirror 中有提供 ClientRpc 來快速實作行為同步,但在這篇文

在多人連線系統中,要讓一個物件的行為能同步到所有客戶端的行為稱為 RPC (Remote Procedure Call),在 Mirror 中也不例外。

Mirror 中有提供 ClientRpc 來快速實作行為同步,但在這篇文章中我們還不會碰到這一塊的程式碼,因為 Mirror 已經實作了位置座標 (包含旋轉、縮放)、動畫和剛體同步功能,我們先介紹這幾個組件的用法。

新增並設置組件

我們繼續上一篇文章的進度,開啟 BasicPlayer 物件的 Inspector 視窗,為它新增 ColliderRigidbodyAnimator 組件,你可以依需求進行取捨,但碰撞器與剛體的行為觸發條件一樣要合法。

接下來在 BasicPlayer 物件下加入 NetworkTransformNetworkRigidbodyNetworkAnimator 組件,基本上 NetworkTransform 是一定會加入的 (要同步位置、旋轉、縮放座標),NetworkRigidbody 是看你有沒有 Rigidbody 組件,以此類推。

因為這些組件是放在玩家物件上,未來我們會直接用程式碼在客戶端控制它的行為,所以要記得都要勾上 Client Authority

當這個物件所有的行為都是透過伺服器直接控制才可以不勾選 Client Authority。

注意:NetworkAnimator 不會自動去抓 Animator 組件 (如上圖),要記得自己將 Animator 拉進去。

位置、旋轉、縮放操作

還記得我們在 BasicPlayer 上掛的 BasicNetworkBehaviour 腳本嗎?請編輯此腳本,並加入以下程式碼。

控制物件座標行為的寫法跟單機的是一樣的,這部分的同步作業 NetworkTransform 組件都會幫我們完成,但是要記得在操作行為前要去檢查 hasAuthority 是否為 True,否則資料是無法同步的。

private void Update()
{
    if (!hasAuthority) return;
    float delta = .1f;
    // 位置
    Vector3 targetPos = transform.position;
    if (Input.GetKey(KeyCode.A)) targetPos.x -= delta;
    if (Input.GetKey(KeyCode.D)) targetPos.x += delta;
    transform.position = targetPos;
    // 旋轉
    Vector3 targetRotate = transform.rotation.eulerAngles;
    if (Input.GetKey(KeyCode.Q)) targetRotate.z += delta;
    if (Input.GetKey(KeyCode.E)) targetRotate.z -= delta;
    transform.rotation = Quaternion.Euler(targetRotate);
    // 縮放
    Vector3 targetScale = transform.localScale;
    if (Input.GetKey(KeyCode.W)) targetScale -= new Vector3(delta, delta, delta);
    if (Input.GetKey(KeyCode.S)) targetScale += new Vector3(delta, delta, delta);
    if (targetScale.x < 0) targetScale = Vector3.zero;
    transform.localScale = targetScale;
}

剛體操作

剛體一樣必須先檢查是否有權限操作,再進行其他物理行為。只要兩物件該有的碰撞器和剛體存在,NetworkRigidbody 會自動處理好所有的同步。

private void Update()
{
    if (!hasAuthority) return;
    Rigidbody rigid = GetComponent<Rigidbody>();
    if (Input.GetKeyDown(KeyCode.Space)) rigid.AddForce(new Vector3(0, 5, 0), ForceMode.Impulse);
}

動畫操作

動畫部分也一樣,檢查權限後直接操作即可,NetworkAnimator 會自動進行同步。

private void Update()
{
    if (!hasAuthority) return;
    Animator anim = GetComponent<Animator>();
    if (Input.GetKeyDown(KeyCode.Z)) anim.Play("Player\_Highlight");
}

結果預覽

影片中的旋轉應該會看不太出來,物件閃爍的部分是動畫的同步。

關於基本座標控制、剛體與動畫的教學到這邊,有問題請於留言版提出。

comments powered by Disqus