2018年4月27日 星期五

【Unity官方教學分享】連線時的玩家血量

網頁連結

玩家的血量狀態在伺服器上做變化,之後再讓這些更動給所有用戶端,這稱作伺服器權限(Server Authority),更多關於伺服器權限的資訊可以點這裡
為了讓我們的目前血量和傷害系統能夠在伺服器權限下運作,需要使用SyncVars這個特殊變數,讓各個數值可以同步於網路環境。此變數在腳本中寫做[SyncVar],更多關於SyncVars的資訊可以點這裡

首先開啟Health腳本,修改成以下內容,新增命名空間UnityEngine.Networking,把繼承改成NetworkBehaviour,在currentHealth前加上[SyncVar],最後增加if (!isServer)判斷式讓TakeDamage函式只會在伺服器上執行:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Collections;

public class Health : NetworkBehaviour 
{

    public const int maxHealth = 100;

    [SyncVar]
    public int currentHealth = maxHealth;
    public RectTransform healthBar;

    public void TakeDamage(int amount)
    {
        if (!isServer)
        {
            return;
        }
        
        currentHealth -= amount;
        if (currentHealth <= 0)
        {
            currentHealth = 0;
            Debug.Log("Dead!");
        }

        healthBar.sizeDelta = new Vector2(currentHealth, healthBar.sizeDelta.y);
    }
}
編譯後可以進行測試,測試連線時結果的方法點我

現在我們完成本文開頭提到的;在伺服器上做血量變化,在隨後同步給用戶端。
在但是同步的結果很難讓所有用戶端看到,這是因為healthBar目前只在伺服器上做數值改變,並不適用其他用戶端。現在使用者可以在Inspector介面中看到當前血量currentHealth的數值,接著我們要讓healthBar的顯示結果正確,必須同步Foreground物件的RectTransform數值。

現在我們要使用另一種狀態同步變數;SyncVar hook。
SyncVar hook能把一個函式連接到SyncVar,當被設成SyncVar的變數發生數值改變時,就會在伺服器與所有用戶端上呼叫該函式,關於SyncVar hook的更多資訊可以看這裡
開啟Health腳本,修改以下內容,將原本在TakeDamage做的healthBar.sizeDelta數值修改,調整到OnChangeHealth中執行,並使用[SyncVar(hook = "OnChangeHealth")]讓此函數在currentHealth發生變化時被呼叫,另外要注意的是,呼叫時currentHealth會傳入該函數,所以變數類型必須相同:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Collections;

public class Health : NetworkBehaviour
{

    public const int maxHealth = 100;

    [SyncVar(hook = "OnChangeHealth")]
    public int currentHealth = maxHealth;
    public RectTransform healthBar;

    public void TakeDamage(int amount)
    {
        if (!isServer)
        {
            return;
        }
        
        currentHealth -= amount;
        if (currentHealth <= 0)
        {
            currentHealth = 0;
            Debug.Log("Dead!");
        }
    }
    
    void OnChangeHealth (int currentHealth)
    {
        healthBar.sizeDelta = new Vector2(health, currentHealth.sizeDelta.y);
    }
}
編譯後可以進行測試,測試連線時結果的方法點我
現在Healthbar在所有用戶端上應該是同步的,下一篇我們要做的是死亡判斷及重生。

上一篇:玩家血量(單機)
下一篇:死亡和重生

建立一個簡單的多人連線範例

1 則留言:

  1. void OnChangeHealth(int currentHealth)
    {
    healthBar.sizeDelta = new Vector2(currentHealth, healthBar.sizeDelta.y);
    }

    回覆刪除

【自製小遊戲】水平思考猜謎(海龜湯)

遊戲連結 海龜湯的玩法是由出題者提出一個難以理解的事件,參與猜題者可以提出任何問題以試圖縮小範圍並找出事件背後真正的原因。但出題者僅能以「是」、「不是」或「沒有關係」來回答問題。 本遊戲蒐集各種論壇、平台的42個題目,提供給想玩海龜湯卻愁找不到題目的你們。 ...