2018年4月30日 星期一

【Unity官方教學分享】生成和重生

網頁連結

設定玩家生成的初始位置
目前玩家物件在遊戲中,生成及重生的位置為原點;也就是(0, 0, 0)的位置。每次遊戲開始,除非玩家移動過自己的玩家物件,否則當其他玩家進入遊戲,這些物件會重疊在同一個位置。
在理想狀況下,這些玩家物件應該要生成在不同的地方。NetworkStartPosition元件可以做到這點,因為它內建生成位置處理的功能。

接下來我們要新增兩個生成位置,首先要新增兩個帶有NetworkStartPosition元件的新物件。

  • 新增一個空物件並命名為SpawnPosition1
  • 選擇SpawnPosition1,並且...
  • 加上Network->NetworkStartPosition元件
  • 設定Position數值為(3, 0, 0)
  • 複製貼上一個SpawnPosition1,並重新命名為SpawnPosition2
  • 將SpawnPosition2的位置設為(-3, 0, 0)
  • 選擇Hierarchy視窗下的NetworkManager
  • 將 Spawn Info屬性展開
  • 將Player Spawn Method改為Round Robin
因為這兩個SpawnPosition物件下有NetworkStartPosition元件,所以NetworkManager會自動去尋找SpawnPosition,接著使用SpawnPosition的位置作為玩家連上伺服器時,物件生成的起始點。
這裡稍微離題談談Player Spawn Method的兩個屬性;Random和Round Robin。
就如同字面上的意思,Random會隨機選取SpawnPosition作為物件生成點,而Round Robin則是依序選取SpawnPosition。
使用Random可能還是會讓玩家物件生成在相同位置,例如本範例測試時,兩個用戶端對兩個生成點還是有可能發生重疊的結果,而Round Robin當生成點多於或等於用戶端時,會是比較好的生成方式。
現在我們編譯後可以進行測試,測試連線時結果的方法點我

設定重生位置
這是本範例中最後的步驟,我們會建立一個陣列,把帶有NetworkStartPosition元件的這些物件SpawnPosition帶入,讓玩家物件在重生時可以從陣列中選擇位置,這步驟雖然與多人線無關,但可以讓我們的範例更加完整。

開啟Health腳本,並新增以下內容,新稱變數類別為NetworkStartPosition的陣列spawnPoints,在Start中if (isLocalPlayer)的判斷式內,使用FindObjectsOfType找到所有帶著NetworkStartPosition元件的物件,並將它們加入陣列,刪除RpcRespawn函式中的transform.position = Vector3.zero;,改為以下紅字那樣:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Collections;

public class Health : NetworkBehaviour {

    public const int maxHealth = 100;
    public bool destroyOnDeath;

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

    public RectTransform healthBar;

    private NetworkStartPosition[] spawnPoints;

    void Start ()
    {
        if (isLocalPlayer)
        {
            spawnPoints = FindObjectsOfType();
        }
    }

    public void TakeDamage(int amount)
    {
        if (!isServer)
            return;
        
        currentHealth -= amount;
        if (currentHealth <= 0)
        {
            if (destroyOnDeath)
            {
                Destroy(gameObject);
            } 
            else
            {
                currentHealth = maxHealth;

                // called on the Server, invoked on the Clients
                RpcRespawn();
            }
        }
    }

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

    [ClientRpc]
    void RpcRespawn()
    {
        if (isLocalPlayer)
        {
            // Set the spawn point to origin as a default value
            Vector3 spawnPoint = Vector3.zero;

            // If there is a spawn point array and the array is not empty, pick one at random
            if (spawnPoints != null && spawnPoints.Length > 0)
            {
                spawnPoint = spawnPoints[Random.Range(0, spawnPoints.Length)].transform.position;
            }

            // Set the player’s position to the chosen spawn point
            transform.position = spawnPoint;
        }
    }
}
現在我們編譯後可以進行測試,測試連線時結果的方法點我
目前不論我們是進入遊戲或是死亡時重生,物件都在生成位置上出現。

上一篇:銷毀敵人物件
下一篇:簡單的遊戲概要

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

沒有留言:

張貼留言

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

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