2018年5月3日 星期四

【Unity官方教學分享】遊戲物件和元件

網頁連結

在Unity場景中被建立的物件稱為遊戲物件(Game Object),任何存在於場景中的東西都被視為Game Object,而一個Game Object是由多個元件(Component)所組成。

2018年5月2日 星期三

【Unity】非固定式虛擬方向鍵製作Part.2

上一篇中我們完成了滑鼠按下及拖曳時的回饋圖示,接下來要把拖曳中滑鼠位置的數值,帶入角色圖中完成移動的效果。

首先我們直覺一點來考慮移動這件事,目前我們已經有了開始位置startPos和當前位置nowPos,那只要把這兩點距離算出來,就有一個數值可以作為移動量值。
開啟Controller腳本,在dragState = true;後加入以下程式碼:
float dis = Vector2.Distance(nowPos, startPos);
Vector2 dir = (nowPos - startPos).normalized;
actor.Translate(new Vector2(dis * dir.x, dis * dir.y) * speed);
Debug.Log(new Vector2(dis * dir.x, dis * dir.y) * speed);
float變數dis為nowPos到startPos的距離,接著用兩點距離的normalized數值作為方向並帶入變數dir,最後將 dis * dir * speed的數值帶入actor.Translate就完成目前的移動,可以用Debug.Log看看目前移動的數值。(這裡的speed是一個全域float變數,數值0.1f)

2018年5月1日 星期二

【Unity官方教學分享】簡單的多人連線遊戲概要

網頁連結

在一整個多人連線系列的教學中,我們把握了大部分基本概念,以及多人連線遊戲中所需的元件。

我們同時也知道如何使用HLAPI建置一個專案,了解到當使用HLAPI 伺服器和所有用戶端,是在同一時間對同一物件的腳本執行同一段程式碼,接著我們討論使用HLAPI去檢查伺服器、 LocalPlayer、用戶端時,如何去控制當中的邏輯流程。

我們學習到HLAPI中的RPCs變數;Commands和ClientRpc’s,Commands是由用戶端呼叫伺服器執行,而ClientRpc’s則是由伺服器呼叫用戶端執行。

接著是SyncVars和SyncVar hooks,使用[SyncVar]變數可以讓數值保持同步,而且再使用SyncVar hooks的話,可以在該數值變化時,呼叫某個函式。

使用NetworkIdentity和NetworkTransform元件,可以讓多人連線中物件的Transforms數值保持同步。

我們學到許多關於網路的內建元件;NetworkManager、NetworkManagerHUD 和NetworkStartPosition,當然關於網路的內建元件還有許多,但它們更加專業而且也不常使用,我以我們會在其他章節中介紹。

我們希望本教學是製作多人連線遊戲的好起點,同時這個範例展現了在Unity中,製作多人遊戲是非常方便的。

上一篇:生成和重生

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

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的位置作為玩家連上伺服器時,物件生成的起始點。

2018年4月29日 星期日

【Unity官方教學分享】銷毀敵人物件

網頁連結

雖然敵人物件可以被子彈攻擊並且造成傷害,但是當敵人的血量歸零時,該物件應該要被銷毀。
要做到這件事,我們需要調整Health腳本,最簡單的方法是使用一個布林變數DestroyOnDeath,來調整該物件是否在死亡時銷毀。

開啟Health腳本,修改以下內容,新增布林變數DestroyOnDeath,接著用if (destroyOnDeath)判斷是否要銷毀該物件
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;

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

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

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

    [ClientRpc]
    void RpcRespawn()
    {        if (isLocalPlayer)
        {
            // Set the player’s position to origin
            transform.position = Vector3.zero;
        }
    }
}

【Unity官方教學分享】處理非玩家角色物件

網頁連結

目前我們的範例主要都集中在玩家物件上,但是大部分的遊戲會有非玩家物件存在於遊戲世界中。這次我們忽略環境物件,先集中在非玩家角色物件上。
玩家物件會在用戶端連上伺服器時生成,但敵人物件需要由伺服器主動生成。

在本次教學中,我們會新增一個敵人生成器(Enemy Spawner),用來創建可以被玩家攻擊的敵人物件。

  • 新增空物件命名為EnemySpawner,並在EnemySpawner上...
  • 新增Network->NetworkIdentity元件
  • 將NetworkIdentity中的Server Only設為true
將Server Only設為true,可以防止EnemySpawner發送給用戶端。

2018年4月28日 星期六

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

網頁連結

目前當玩家血量歸零時,除了在console視窗中顯示文字外,不會發生任何事,現在我們要將此範例修改的更像遊戲,當玩家的血量歸零,將會被傳送到起始位置並恢復血量。

接下來我們會使用[ClientRpc]屬性,這是另一個狀態同步工具。
加上ClientRpc的函式會從;帶有NetworkIdentity元件,並且是從伺服器生成的任意物件執行,即使在伺服器上呼叫帶有ClientRpc的函式,它也會在用戶端上執行。
先前提過的Command和ClientRpc相反,Command是在用戶端上呼叫,伺服器上執行。

要在一個函式前加上ClientRpc,要使用 [ClientRpc]變數,而且函式名稱前必須加上Rpc。此函數會在伺服器呼叫它時,於用戶端上執行。任何需要的變數會自動傳送給用戶端,更多關於[ClientRpc]變數的資訊,可以參考這裡

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

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