本文章是由機器翻譯。

Unity

使用 Unity 及 C# 開發您的第一款遊戲,第 2 部分

Adam Tuliper

下載代碼示例

歡迎回到我的系列論統一。在第一篇文章中,我談一些統一的基礎和架構。在這篇文章,我要去探索 2D 團結,團結在 4.3 版本中添加的 2D 支援為基礎。4.3 之前,你可以做統一的 2D,但過程是相當痛苦的沒有協力廠商工具。自己想要的什麼是只需要拖動和將圖像放入我的場景,並有它出現,並且希望通過拖放介面的工作。那是一些統一 4.3 所帶來的對表和在這篇文章,在發展基本的 2D 遊戲平臺遊戲,學習一些基本的統一概念的同時,我將討論更多的特點。

在統一的 2D

要得到二維的支援在統一中,創建一個新專案時應從新建專案對話方塊中的下拉清單中選擇 2D。當你這樣做,專案預設值被設置為 2D (查看下編輯 |專案設置 |編輯器中) 和導入您的專案中的任何圖像都帶著而不是只是紋理的精靈。(我將在下一節。)此外,場景視圖預設為 2D 模式下。這真的只是提供一個説明按鈕,修復你兩個軸向在現場開發過程中,但在實際遊戲中不起任何作用。你可以在任何時候流行和 2D 工作模式下按一下它。在統一的 2D 遊戲仍然是真正的 3D 環境 ; 你的工作僅限於 X 和 Y 軸。圖 1圖 2 顯示 2D 模式下選中和未選中。我有相機突出顯示所以你可以看到相機的查看區域,但請注意,它探究空間作為一個矩形形狀的輪廓。

2D 模式下選擇 — — 相機具有焦點
圖 1 2D 模式下選擇 — — 相機具有焦點

2D 模式下未選中 — — 相機具有焦點
圖 2 2D 模式下未選中 — — 相機具有焦點

突出顯示的相機設置為正交相機,在統一中的兩種相機模式之一。這種相機類型,常用的在 2D,不帶走縮放物件進一步,正如你的眼睛會看到他們 ; 那就是,沒有從攝像機位置的深度。另一種相機類型是顯示物件,正如我們的眼睛看到他們,隨深度的角度。有各種原因,使用一種相機類型而不是其他,但一般情況下,選擇角度來看如果你需要視覺深度,除非您想要相應縮放您的物件。你可以簡單地通過選擇攝像機和改變的投影類型更改模式。我建議在摸索階段,看到如何你的相機的查看面積變化,當你開始移動物件進一步走到 Z 軸。在任何時間,影響只有未來的圖像導入到您的專案,您可以更改預設行為模式。

如果您有一個現有的專案在統一或不確定的如果您已經從專案對話方塊中選擇 2D,您可以通過編輯,為 2D 設置專案預設設置 |專案設置 |編輯器 ; 否則,您將必須手動設置的紋理類型,對每一個二維的圖像導入,這是有點麻煩,如果你有很多藝術品。

它是所有關于雪碧

當 3D 被選為預設行為模式時,圖像被公認的紋理類型。您不能將一個紋理拖到你的場景 ; 紋理必須應用於物件。這種方式不是很多有趣的創建的 2D 遊戲。我想要只是拖放圖像並將它顯示在我的場景。如果您的預設行為模式為 2d 圖元,不過,事情變得容易些。當我拖,將圖像放入統一時,它現在被公認為類型雪碧。

這允許您只需拖放圖稿到團結,然後從統一拖,把它扔到你的場景,打造出了你的遊戲。如果你有看起來很小,而不是縮放它無處不在的藝術品只是可以減少圖元為單位的值。這是非常常見的操作,在統一為 2D 和 3D,通常是更好的性能,比縮放物件通過其變換縮放屬性。

當刪除物件,您可能會注意到一個物體在另一個之上而告終。統一創建一系列的頂點在幕後,甚至對於 2D 圖像,所以繪製順序可能會有所不同的各個部分的圖像。它總是最好顯式指定您的圖片的 z 順序。你可以通過三種方法,統一繪製的順序列出你的精靈:

  1. 在精靈渲染器中設置"排序層"屬性。
  2. 屬性設置為"圖層中的秩序",也對雪碧渲染器。
  3. 設置轉換的 Z 位置的值。

排序的層優先,總的來說,其次是在層,依次優先轉換的 z 值的順序。

排序圖層按定義的順序繪製。當您添加其它圖層 (在編輯 |專案設置 |標籤和圖層),統一繪製出它第一次發現預設圖層的任何物件 (順序在層接管,然後變換的 Z 位置的值),然後背景,然後平臺,等等等等。這樣你就可以輕鬆地修復重疊圖像由將其設置為平台層和給那個你頂部想要的順序在層 1,所以它將畫後任何與 0 層中的訂單。

通用的功能

圖 3 顯示了一個包含一些平臺和被修造了通過拖放和設置排序圖層的背景圖像的水準。

遊戲的水準
圖 3 遊戲的水準

就目前的情況來看,它看起來像一場遊戲,但它並不表現的像一個人。至少,它需要大量的功能,是一個功能的遊戲。我將討論幾個在以下各節中。

鍵盤、 滑鼠和觸摸運動在團結、 鍵盤、 滑鼠、 加速度計和觸摸讀完輸入系統。您可以讀取輸入的運動和滑鼠點擊或觸摸很容易在主力 (我將基於此腳本不久。) 上使用類似下面的腳本:

void Update()
{
  // Returns -1 to 1
  var horizontal = Input.GetAxis("Horizontal");
  // Returns true or false. A left-click
  // or a touch event on mobile triggers this.
  var firing = Input.GetButtonDown("Fire1");
}

如果你檢查編輯 |專案設置 |輸入,你可以看到 (統一給你在每個新的專案中存在一群) 的預設輸入或設置新的。圖 4 顯示為閱讀水準運動的預設值。"左"和"右"設置也代表卻通知左、 右方向鍵,"a"和"d"用於水準運動。這些可以映射到操縱杆輸入。您可以添加新的或更改的預設值。敏感度欄位控制速度有多快團結會從 0 到 1 或-1。 當按下右箭頭時,第一幀可能屈服值的.01,然後縮放很快達 1,雖然您可以調整速度,給你的性格瞬間的橫向速度或運動。我會向你展示的代碼不久將這些值應用於您的遊戲物件。沒有實際的遊戲物件元件所需的讀取這些值 ; 你只需輸入關鍵字你在代碼中使用訪問讀取輸入的功能。輸入,作為一般規則,應該讀的更新功能,而不是 FixedUpdate,以避免丟失輸入的事件。

水準輸入預設值
圖 4 水準輸入預設值

線性運動的東西必須要能夠移動。如果這是一個自上而下的遊戲,重力通常並不重要。如果它是遊戲,重力是極其重要的。在任一情況下,物件碰撞檢測是關鍵。這裡有基本規則。Rigidbody2D 或剛體 (用於 3D) 元件添加到一個遊戲物體會自動給該元件品質,使其瞭解重力、 接受力。根據維琪百科,"在物理學中,剛性的身體是一個理想化的固體變形忽略。換句話說,任何剛體的給定兩點之間的距離保持不變的時間對它施加外力。"同樣的原則適用于遊戲。添加一個剛體允許您像打電話圖 5

圖 5 添加運動和速度

void FixedUpdate()
{
  // -1 to 1 value for horizontal movement
  float moveHorizontal = Input.GetAxis("Horizontal");
  // A Vector gives you simply a value x,y,z, ex  1,0,0 for
  // max right input, 0,1,0 for max up.
  // Keep the current Y value, which increases 
  // for each interval because of gravity.
  var movement = new Vector3(moveHorizontal * 
    _moveSpeed, rigidbody.velocity.y, 0);
  rigidbody.velocity = movement;
  if (Input.GetButtonDown("Fire1"))
  {
    rigidbody.AddForce(0, _jumpForce, 0);
  }
}

作為一般規則,直線運動通過更新應該發生,而且通過 FixedUpdate 加速運動。如果你是一個初學者,似乎有些困惑什麼要使用時,而事實上,直線運動將工作或執行功能。但你會遵循這一規則得到更好的視覺效果。

碰撞檢測物件獲取它的品質從其剛體元件,但您還需要告訴 Unity 如何處理與此物件的碰撞。大小和形狀的您的作品或是模型也不要緊,雖然縮放不會影響物件本身的物理。要緊的是大小和形狀的對撞機組件,它是只是一個定義的區域周圍,或內要統一檢測到另一個物件接觸的物件。這就是使得像檢測輸入空閒的僵屍或去探討沿著山邊彈跳的巨石區域時的情景。

不同的形狀碰撞。為 2D 的對撞機可以是圓形、 邊緣、 多邊形或框。盒碰撞器是偉大的形狀像正方形或長方形,或者當你只是想要在一個正方形區域檢測到碰撞的物體。想想你可以站在一個平臺 — — 這是一個盒碰撞器的一個好例子。只將此元件添加到您的遊戲物件允許您利用物理碰撞。在圖 6,我添加一個圓對撞機和剛體特徵和盒碰撞器的平臺。當我按一下播放在編輯器中的時,球員立即落在平臺和停止。無需任何代碼。

添加碰撞
圖 6 添加碰撞

您可以移動和調整大小對撞機涵蓋通過更改其屬性的對撞機組件上的區域。預設情況下,物件與碰撞不穿過對方 (除了事件觸發器,這些我會掩護下一步)。碰撞需要上這兩個遊戲物件的碰撞器元件和至少一個物件必須要有一個剛體元件,除非它是一個觸發器。

如果我想團結在此碰撞實例第一次發生時調用我的代碼,只需將添加到一個遊戲物體通過腳本元件 (在上一篇文章中討論) 下面的代碼:

void OnCollisionEnter2D(Collision2D collision)
{
  // If you want to check who you collided with,
  // you should typically use tags, not names.
  if (collision.gameObject.tag == "Platform")
  {
    // Play footsteps or a landing sound.
  }
}

觸發器有時你想要檢測到碰撞,但不要任何物理。想想一個像撿寶在遊戲中的場景。你不想要的硬幣被踢出前面的球員當它接近 ; 你想要的硬幣拿起並不會干擾運動員運動。在這種情況下,您使用稱為觸發器,觸發器與 IsTrigger 核取方塊啟用的對撞機無非是一個碰撞器。這將關閉物理並統一隻會調用您的代碼時,物件 A (其中包含一個碰撞器) 物件 B (其中也有一個碰撞器) 的區域內。在這種情況下,代碼的方式而不是 OnCollisionEnter2D OnTriggerEnter2D:

void OnTriggerEnter2D(Collider2D collider)
{
  // If the player hits the trigger.
  if (collider.gameObject.tag == "Player")
  {
    // More on game controller shortly.
    GameController.Score++;
    // You don’t do: Destroy(this); because 'this'
    // is a script component on a game object so you use
    // this.gameObject or just gameObject to destroy the object.
    Destroy(gameObject);
  }
}

要記住的一點是與觸發器,沒有物理的交互作用,它基本上是只是通知。觸發器不需要遊戲物件上的剛體元件,因為沒有力的計算正在發生。

經常旅行了新開發的一件事時向其中添加碰撞剛體的行為。如果我有圓對撞機上我的物件,我把此物件放在一個傾斜的平面 (如其對撞機形狀),它開始卷,作為圖 7 顯示。這模特你會看到什麼在物理世界中如果在斜坡上設置了一個輪子。不要盒碰撞器用於我的性格的原因是因為一隻盒子有邊緣可以抓起來時移動到其他碰撞的邊緣,收益率不太順利的經驗。圓對撞機使這更順暢。然而,對於當平滑的旋轉是不能接受的時候,你可以使用固定的角度設置剛體元件上。

圈對撞機用平滑移動
圖 7 圈對撞機用平滑移動

音訊若要聽到聲音,需要音訊攔截器元件,預設情況下已經存在於任何相機上。要播放聲音,只是將音訊源元件添加到一個遊戲物體,並設置音訊剪輯。團結支援大多數主流音訊格式並將編碼更長的片段到 MP3。如果你有大量的音訊源剪輯分配在統一編輯器中,請的記住他們會都將在運行時載入。相反,您可以載入的音訊通過位於特殊的資源資料夾中的代碼並摧毀它時做。

當我進入我的專案導入音訊時,我保持它作為一個 WAV 檔,是未壓縮的音訊。團結會重新編碼你長的音訊來優化它,所以總是使用你有最好品質的音訊。這是尤其如此,短的檔,如統一不會編碼的聲音效果。我還音訊源元件添加到主觀景窗,雖然我無法添加它到任何遊戲物件。然後分配給此音訊源元件的冒險音訊剪輯並核對迴圈,因此它不斷地迴圈。並在三個簡單的步驟,我現在有背景音樂,當我的遊戲。

GUI 首腦上顯示 A GUI 系統可以包含在一個遊戲中的很多事情。它可能涉及功能表系統、 健康和分數顯示、 武器庫存。通常,一個 GUI 系統是你保持不動不管相機正在 (雖然不是必須) 的螢幕上看到了什麼。統一 GUI 功能目前正在進行全面的修訂和新的 uGUI 系統在統一 4.6 就要出來了。因為那不尚未發佈,我將簡單地討論一些基本的功能在這裡,但檢查出我在新的 GUI 系統的詳細資訊的第 9 頻道博客 channel9.msdn.com/Blogs/AdamTuliper

要向螢幕中添加簡單的顯示文本 (例如,分數:0),點擊遊戲物件 |創建其他 |GUI 文本。此選項不再存在於統一 4.6,所以你會想看我提到在 uGUI 上的視頻。你仍然可以向中 4.6 的遊戲物件添加一個 GUI 文本元件,按一下添加元件按鈕 ; 它是從編輯器功能表只是缺掉的。與現有 (舊版) 的統一 GUI 系統中,您無法看到您的 GUI 物件在場景視圖中,只能在遊戲視圖中,這使得佈局創建有點怪異。如果你願意,你可以使用純代碼來設置您的 GUI,而且還有固定的類,它允許你自動跟蹤視窗小部件。但我更喜歡在哪裡我可以按一下並拖動,然後工作很容易,這就是為什麼我發現 uGUI 遠比一個 GUI 系統。(之前 uGUI,在這一領域的領導者是相當可靠的協力廠商產品,叫做 NGUI,實際上被用作初始代碼庫 uGUI。

更新此顯示文本的最簡單方法是簡單地搜索或在編輯器中將引用賦給該 GUI 文本的遊戲物件,和把它像一個在.NET 中的標籤和更新其 text 屬性。這使得它易於更新螢幕 GUI 文本:

void UpdateScore()
{
  var score = GameObject.Find("Score").GetComponent<GUIText>();
  score.text = "Score: 0";
}

這是一個略有縮短的例子。為性能,我有實際緩存中,不會為它查詢每個方法調用 Start 方法 GUIText 元件的引用。

分數跟蹤跟蹤分數很容易。你只是有一個類公開一個公共方法或屬性在其上設置一個分數。它是常見的遊戲,有一個稱為行為作為比賽的召集人的遊戲控制器物件。遊戲控制器可以負責觸發遊戲保存、 載入、 記分和更多。在此示例中,我可以只是有一個類公開一個積分變數,如中所示圖 8。我將此元件分配到一個空的遊戲物件,所以當場景載入時,它才可用。比分更新時,GUI 是反過來更新。_ScoreText 變數是在 Unity 編輯器。只是 GUIText 的任何遊戲物件拖放此暴露的欄位或使用搜索外掛程式,此腳本元件公開分數文本在編輯器中的變數。

圖 8 創建 _scoreText 變數

public class GameController : MonoBehaviour
{
  private int _score;
  // Drag a GuiText game object in the editor onto
  // this exposed field in the Editor or search for it upon startup
  // as done in Figure 12.
  [SerializeField]
  private GUIText _scoreText;
  void Start()
  {
    if (_scoreText == null)
    {
      Debug.LogError("Missing the GuiText reference. ");
    }
  }
  public int Score
  {
    get { return _score; }
    set
    {
      _score = value;
        // Update the score on the screen
      _scoreText.text = string.Format("Score: {0}", _score);
    }
  }
}

你可以然後只需要更新 (在此示例中) 的蘑菇觸發器代碼,如下所示,增加與每個皮卡得分:

void OnTriggerEnter2D(Collider2D collider)
{
  if (collider.gameObject.tag == "Player")
  {
    GameController.Score++;
    Destroy(gameObject);
  }
}

動畫只是因為與 XAML,動畫由開展各種行動,在關鍵幀中創建。我就能很容易把整篇文章只是用於動畫在統一中,不過我會留它簡短這裡空間。統一具有兩個動畫系統、 遺留系統和更新 Mecanim。遺留系統使用 animation(.ani) 檔中,而 Mecanim 使用哪個動畫檔播放的控制的國家。

預設情況下,在二維動畫使用 Mecanim。最簡單的方法來創建動畫是拖放到您的現場圖像,讓團結創建為您的動畫。若要開始,我進統一拖動一些單一的精靈,並反過來團結創造了幾件事對我來說。 首先,它創建一個遊戲物體與雪碧渲染器元件,以繪製精靈。然後,它創建一個動畫檔。你可以看到這去視窗 |動畫師和突出顯示您的遊戲物體。動畫顯示的動畫檔分配,這對我而言,包含六個關鍵幀,因為六個圖像掉到我的場景。每個關鍵幀控制一個或多個參數對某些元件 ; 在這裡,它改變了雪碧渲染器元件的雪碧屬性。動畫是比單一的圖像顯示在一些使眼睛感知運動的速率。

接下來,統一創建動畫元件上的遊戲的物件,如中所示圖 9

動畫元件指向一個控制器
圖 9 動畫元件指向一個控制器

此元件指向一個簡單狀態機稱為動畫控制器。這是一個檔統一創建,它只是顯示的預設狀態 ; 換句話說,它是一直處於"空閒"狀態因為這是唯一可用的狀態。此空閒狀態比我的動畫檔指向更不執行任何操作。圖 10 在時間表上顯示的實際關鍵幀資料。

空閒動畫資料
圖 10 空閒動畫資料

這可能看起來像很多去只是為了播放動畫。狀態機器的力量是你可以通過設置簡單變數來控制他們。請記住,一個國家不執行任何操作超過指向動畫檔 (儘管在 3D 中,你可以得到一種花式和做事情喜歡動畫混合在一起)。

我花了更多的圖片,使運行的動畫然後他們拖我雪人的遊戲物體。因為在遊戲物體上已經動畫元件,團結只是創建一個新的動畫檔和添加一個新的國家,所謂的"運行"。我對閒置用滑鼠右鍵按一下,即可創建的一個過渡,運行。這將創建一個箭頭在空閒狀態和運行狀態之間。我然後可以添加一個新的變數稱為是便於使用的"運行"— — 您只需按一下國家之間的箭頭,並將條件改為使用該變數,如中所示圖 11

改從怠速運行狀態
圖 11 改從怠速運行狀態

當運行變得真即時,空閒動畫狀態更改為運行的動畫狀態,這僅僅意味著運行的動畫檔播放。你可以很輕鬆地控制這些代碼中的變數。如果你想要通過按一下滑鼠按鍵時觸發運行的狀態開始運行的動畫,您可以添加所示的代碼圖 12

圖 12 更改狀態碼

private Animator _animator;
void Awake()
{
    // Cache a reference to the Animator 
    // component from this game object
    _animator = GetComponent<Animator>();
}
void Update()
{
  if (Input.GetButtonDown("Fire1"))
  {
    // This will cause the animation controller to
    // transition from idle to run states 
    _animator.SetBool("Running", true);
  }
}

在我的示例中,我用單精靈來創建動畫。它是相當常見的不過,若要使用雪碧表 — — 與它的多個圖像的單個影像檔。Unity 支援精靈表,所以它是告訴統一如何切片,你的精靈,和那些片然後落入你的場景。所不同的唯一步驟正在改變雪碧模式從單一到雪碧屬性,和雪碧編輯器中,打開可以然後自動切片的雪碧和應用這些更改,如中所示的多圖 13。最後,你展開的雪碧 (一個小箭頭有雪碧的圖示在專案視圖中),突出由此產生的精靈,並放到你的場景,像你早些時候做的那樣。

創建雪碧表
圖 13 創建雪碧表

動畫可以是一個複雜的問題,直到你學會系統。有關更多資訊,查閱我第 9 頻道的博客或統一的學習網站上的很多優秀資源之一。

年底的水準當玩家獲取到年底的水準時,你可以只是有一個碰撞器,設置為觸發器,並且允許玩家擊中那區。當它,你只是載入另一個層面或重新載入當前的一個:

void OnTriggerEnter2D(Collider2D collider)
{
  // If the player hits the trigger.
  if (collider.gameObject.tag == "Player")
  {
    // Reload the current level.
    Application.LoadLevel(Application.loadedLevel);
    // Could instead pass in the name of a scene to load:
    // Application.LoadLevel("Level2");
  }
}

遊戲物件和其各自的屬性將顯示在圖 14。請注意對撞機的高度是足夠高球員不能跳過它,並顯示該對撞機被設置為觸發器。

的遊戲物件和其屬性
圖 14 的遊戲物件和其屬性

遊戲在一個簡單的 2D 遊戲,像這樣,流是相當簡單。玩家開始。剛體上的重力使下降的球員。有是對撞機在播放機上,在平臺上,所以玩家停止。鍵盤、 滑鼠和觸控式螢幕輸入讀取,並且移動播放機。玩家通過應用剛體平臺之間跳轉。AddForce,使其跳轉和移動向左或向右通過閱讀 Input.GetAxis­("橫向") 並將它應用到 rigidbody.velocity。 這名球員撿蘑菇,都只是碰撞器,設置為觸發器。當玩家接觸到他們時,他們增加分數和自我毀滅。當玩家最後把它到最後簽署,只是重新載入當前級別的碰撞/觸發。額外的待辦將添加在地面之下的大型對撞機,來檢測當球員瀑布下講臺和簡單地重新載入水準,然後,以及。

預置重用是重要在編碼中,以及在設計。一旦您指派幾個元件和自訂您的遊戲物件,你經常要重用它們在相同的場景或甚至多個場景或遊戲。你可以在你的場景中,創建一個遊戲物體的另一個實例,但你也可以在你的場景中創建尚不存在一個預設的一個實例。考慮平臺和他們碰撞器。如果您想要重用他們整個場景,很好,目前,你不能。 但通過創建預置,你可以。只是將從層次結構的任何遊戲物件拖回專案資料夾,以包含任何子分層擴展.prefab 創建一個新檔。現在,您可以將此檔拖進你的場景,並重用它。原始的遊戲物件將變成藍色以注意到它現在連接到一個預置。.Prefab 檔更新你的場景中的所有實例和你可以也將更改推送從修改場景預製回到.prefab 檔。

點擊預置顯示遊戲,包含的物件,如下所示的圖 15。如果要更改在這裡,在你的場景中的所有實例將被都更新。

查看一個預置的內容
圖 15 查看一個預置的內容

總結

有大量的跨遊戲執行的常見操作。在本文中,我介紹碰撞、 剛體、 動畫、 記分、 基本 GUI 文本和讀取使用者輸入用於施力移動播放機的動作遊戲的基礎。這些構造塊可重用各種遊戲類型。敬請 3D 進來我下一篇文章中討論 !

額外的學習

 


Adam Tuliper 是與生活在陽光明媚的南加州的微軟高級技術福音傳教士。他是獨立遊戲開發的奧蘭治縣團結 Meetup co 管理員和 pluralsight.com 作者。他和他的妻子都約有三個孩子,所以向他伸出雖然他仍然有時間,就在 adamt@microsoft.com 或在 Twitter 上 twitter.com/AdamTuliper

衷心感謝以下技術專家對本文的審閱:Matt紐曼 (潛科學工作室)、 Tautvydas Žilys (統一)