使用 Unity 和 C# 開發您的第一個遊戲 (Part 2)
微軟資深技術傳道士 Adam Tuiliper 所寫的 Unity 系列第 2 篇文章,這次主要說明如何在 Unity 中建立 2D 遊戲。原文連結;以下則是機器翻譯的中文版,若有不流暢處請見諒。
第 1 篇文章請見: 使用 Unity 和 C# 開發您的第一款遊戲(MSDN文章)。
使用 Unity 和 C# 開發您的第一個遊戲 (Part 2)
歡迎回到關於 Unity 的系列教程。在第一篇文章中,我介紹了一些有關 Unity 的基礎知識和體系結構。在這篇文章中,我將在 Unity 中探討 2D,其建立於在 4.3 版本中添加的 2D 支持 Unity 的基礎之上。您可以在 Unity 4.3 之前的 Unity 版本中製作 2D,但是如果沒有協力廠商工具包,那麼這個過程是相當痛苦的。我要做的就是將圖片拖放到我的場景,並通過拖/放介面讓它按照我希望的形式出現和發揮作用。這是 Unity 4.3 帶來的一些功能,在本文中,我將在開發基本的 2D 平臺遊戲的同時,介紹它的更多功能和一些必要的 Unity 概念。
Unity 中的 2D
為了在 Unity 中獲得 2D 支持,當在創建一個新的專案時,請在新建項目對話方塊的下拉清單中選擇 2D。當您選擇了 2D 之後,預設情況下專案會被設置為 2D(在“編輯|專案設置|編輯器”下查看),任何導入到專案中的圖像都顯示為 sprite 類型,而不僅僅是紋理類型。(我將在下一節對其進行介紹。)此外,場景視圖默認設置為 2D 模式。這只是提供了一個説明按鈕,説明您在場景開發過程中固定兩軸,但對實際遊戲沒有影響。您可以在任何時候按一下它,跳進跳出 2D 工作模式。Unity 中的 2D 遊戲也還是一個 3D 環境;您的工作只受限於 X 軸和 Y 軸。圖 1 和圖 2 顯示了選中和未選中的 2D 模式。我讓照相機突出顯示,以便您可以看到照相機可視區域的輪廓,但要注意,它向外的視角空間為矩形形狀。
圖 1 選擇 2D 模式——照相機保持焦點
圖 2 未選擇 2D 模式——照相機保持焦點
突出顯示的照相機被設置為正交照相機,即 Unity 中的兩種相機模式之一。這種照相機的類型,通常在 2D 中使用,不能在所見範圍之內進一步縮放物件;即從照相機的位置看過去,沒有深度。另一個照相機類型是透視圖,呈現的是眼睛看到的有深度的物件。出於各種原因而使用其中一種照相機類型而不用另一種,但在一般情況下,如果需要視覺深度,可以選擇透視相機,除非您想相應地放大您的對象。您只需選擇照相機和改變投影類型就可以輕鬆更改模式。我建議您嘗試上述操作,在您將物體向著 Z 軸方向移動時看看您的照相機的可視區域是如何變化的。您可以在任何時候更改預設的行為模式,這只會對未來將圖像導入到您的項目產生影響。
如果在 Unity 中存在現有項目或者您不清楚是否已經在項目對話方塊中選擇了 2D,則可以前往“編輯|項目設置|編輯器”將您的專案設置為默認 2D;否則,就必須對每個導入的 2D 圖像手動設置紋理類型,如果您的作品很多,這會是一項乏味的工作。
關於 Sprite 的全部內容
當將 3D 選作預設的行為模式時,圖像被識別為“紋理”類型。您不能將紋理拖到場景中;紋理必須應用到物件中。對於創建 2D 遊戲來說,這種方法不是很有趣。我只想拖放圖像,並讓它出現在我的場景中。如果您的預設行為模式是 2D,事情就變得容易多了。當我將圖像拖放到 Unity 中後,它被識別為 Sprite 類型。
這使您可以輕鬆將您的作品拖放到 Unity 中,然後從 Unity 將其拖放到您的場景中,從而構建遊戲。如果您的作品看起來比較小,而且不需要處處重新調整,那麼您只需要將圖元縮小到單位值大小。這種操作方法普遍存在於 Unity 的 2D 和 3D 模式中,通常比通過 transform 的縮放屬性來縮放物件具有更佳的性能。
當釋放物件時,您可能會注意到物件們一個接一個地完成。Unity 在場景後面創建一系列頂點,即便 2D 圖像也是如此,所以繪製順序可以根據圖像的各個部分而有所不同。通常最好的做法是明確指定圖像的 Z 軸的位置。為此,您可以通過三種方法來實現,這些方法按照 Unity 繪製 sprite 的順序列出:
1. 在 Sprite 渲染器中設置“層排序”屬性。
2. 在 Sprite 渲染器上設置“層順序”屬性。
3. 設置 Transform 的 Z 軸位置值。
層排序的優先順序高於一切,其次是層順序,而這反過來又優先於 transform 的 Z 值。
層排序按照定義順序繪製。當您添加其他層時(在“編輯|項目設置|標籤和圖層”中),Unity 首先繪製出它在默認層上找到的所有物件(然後是層順序,再然後是 Transform 的 Z 軸位置值),然後是背景,再然後是平臺,等等。所以,您可以通過將圖像設置到平臺層,並指定您想在第 1 個層順序中放在頂部的圖像,從而輕鬆解決重疊的這些圖像,因此可以在 0 層順序後繼續進行繪製。
常用功能
圖 3 所示的關卡包含了一些通過拖放和設置層排序佈置的平臺和背景圖像。
圖 3 遊戲關卡
就現在而言,它看起來像一個遊戲,卻沒法玩。至少,它需要一些功能才能成為一款功能性的遊戲。我將在下面的章節中討論這些內容。
鍵盤、滑鼠和觸摸移動在 Unity 中,鍵盤、滑鼠、加速計和觸摸都是通過輸入系統來讀取的。您可以在主播放機上使用類似于下方列出的腳本,輕鬆讀取輸入移動和滑鼠點擊或觸摸(我將很快根據此腳本構建。):
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");
}
如果您選中“編輯|項目設置|輸入”,就可以看到默認的輸入(Unity 在每個新項目中為您提供一組),或設定新的輸入。圖 4 顯示了讀取水準運動的默認設置。“左”和“右”設置表示左右方向鍵,但還要注意的是“a”和“d”用於水準運動。這些都可以映射到搖桿輸入。您可以添加新的輸入或更改默認輸入。敏感欄位控制 Unity 從 0 移到 1 或 -1 的速度。當按下右方向鍵時,第一幀可能產生一個 .01 的數值,然後很快達到 1,雖然可以調整速度,為您的角色指定暫態水準速度或運動速度。稍後不久,我會向您展示將這些值應用到遊戲物件的程式碼。不存在讀取這些值所需的實際的 GameObject 組件;您只需在您的程式碼中使用輸入關鍵字來訪問可讀取輸入的功能。作為一般規則,應以 Update 函數讀取輸入,而不是 FixedUpdate,以避免丟失輸入事件。
圖 4 水準輸入預設值
直線運動物體需要能夠移動。如果這是一個自上而下的遊戲,重力通常並不重要。如果它是一個平臺遊戲,重力是極為重要的。無論是哪種情況,物件的碰撞檢測是至關重要的。以下是一些基本規則。添加到遊戲物件的 Rigidbody2D 或 RigidBody(用於 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);
}
}
作為一般規則,直線運動應通過 Update 發生,加速運動應通過 FixedUpdate 發生。如果您是一個初學者,似乎在何時使用哪一個的問題上感到困惑,事實上,直線運動適用於各種函數。但您要按照這個規則才能獲得更好的視覺效果。
碰撞檢測一個物件可從 RigidBody 元件中獲得其品質,但您還需要告訴 Unity 如何處理與此物件的碰撞。雖然縮放對物件本身物理特性會產生影響,但您的作品或模型的大小和形狀在這裡並不重要。重要的是發生碰撞的元件的大小和形狀,簡單來說是一個您想讓 Unity 檢測另一個物件接觸的在本物件的附近、表面或內部的定義區域。這是實現場景的方法,比如當您進入有僵屍閒逛的區域,或進入從山一側彈跳下來巨石的區域就會執行檢測。
有形狀各異的碰撞體。2D 碰撞體可以是圓形體、邊緣體、多邊體或盒體。盒狀碰撞體適用於形狀像正方形或長方形的物件,或者您只是想檢測發生在正方形區域中的碰撞。想像您能站在上面的平臺 - 這是盒狀碰撞體的一個很好的範例。將這個元件添加到您的遊戲物件,您就能使用物理碰撞了。在圖 6 中,我將一個圓形碰撞體和一個剛體添加到角色中,將一個盒狀碰撞體添加到平臺中。當我在編輯器中按一下播放時,玩家立刻下降到平臺上,然後停止。無需程式碼。
圖 6 添加碰撞體
您可以通過更改碰撞體元件的屬性來移動和調整該碰撞體覆蓋的區域大小。預設情況下,含碰撞體的物件不會彼此穿過(觸發器例外,我會在下節中進行介紹)。碰撞需要兩個遊戲物件上都有碰撞體元件,至少其中的一個物件必須有一個 RigidBody 元件,除非它是一個觸發器。
如果我想在第一次發生此碰撞實例時讓 Unity 調用我的程式碼,我只需通過一個腳本元件將以下程式碼添加到遊戲物件(在之前的文章中討論過):
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(也包含碰撞體)的區域內時,Unity 只會調用您的程式碼。在這種情況下,程式碼方法是 OnTriggerEnter2D 而不是 OnCollisionEnter2D:
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);
}
}
要記住的一點是,對於觸發器,沒有物理作用,它基本上只是一個通知。觸發器也不需要遊戲物件具備 Rigidbody 元件,或者說,因為不需要進行力計算。
一件經常難倒新開發人員的事就是當您將碰撞體添加到剛體上時,這些剛體的行為。如果我的物件具有一個圓形碰撞體,我將此物件放在一個斜面上(注意其碰撞體的形狀),讓它開始滾動,如圖 7 所示。您在物質世界中看到的此模型是否是被設置在斜面上的一個滾輪。我之所以不將盒狀碰撞體用於我的角色是因為當在其他碰撞體的邊緣移動時,由於盒子的邊有可能被拖住,由此會產生不很流暢的體驗。而圓形碰撞體可以使這更順暢。然而,對於不接受平穩旋轉的情況,您可以使用 Rigidbody 元件的固定角度設置。
圖 7 使用圓形碰撞體做平滑移動
音訊為了聽到聲音,你需要一個音訊偵聽器元件,預設情況下,已經存在於任何照相機上。若要播放聲音,只要將音訊源元件添加到遊戲物件,並設置音訊剪輯即可。Unity 支援大多數主流音訊格式,且可以將較長的剪輯編碼成 MP3。如果您有許多音訊源,它們的剪輯已在 Unity 編輯器中進行了指定,請記住在運行時它們都會被載入。另一方面,您也可以通過位於特定資源檔案夾中的程式碼載入音訊,當完成時,再將它銷毀。
當我將音訊導入到我的專案中時,我將它保存為 WAV 檔,它是未壓縮的音訊。Unity 將重新編碼更長的音訊來優化它,所以始終使用您最優質的音訊。這對短文件尤其如此,比如,Unity 不對聲音效果進行編碼。我還將音訊源元件添加到我的主照相機中,雖然我可能已經把它添加到其他的遊戲物件中。然後,我將 Adventure 音訊剪輯指定到這個音訊源元件中,並勾選了迴圈,因此它可以不斷地迴圈。通過三個簡單的步驟,現在我在玩遊戲時可以播放背景音樂。
GUI/ 平視顯示在一個遊戲中,GUI 系統由好多東西構成。它可能涉及到功能表系統、運行狀況及得分顯示、武器庫存,等等。通常情況下,GUI 系統是無論照相機在看哪兒(雖然這不是必要的),您都能在螢幕上看到的原地不動的內容。Unity 的 GUI 功能目前正在全面修訂,新的 uGUI 系統將出現在 Unity 4.6 中。因為還沒有發佈,我在這裡將簡單地討論一些基本功能,若要瞭解有關新的 GUI 系統的詳細資訊,可以查閱我的 Channel9 部落格channel9.msdn.com/Blogs/AdamTuliper。
為了將簡單的顯示文本添加到螢幕(例如,得分:0),請按一下“遊戲物件|創建其他| GUI文本”。此選項不再出現在 Unity 4.6 中,所以您要觀看我提到過的有關 uGUI 的視頻。在 4.6 版中,您仍然可以通過按一下“添加元件”按鈕將 GUI 文本元件添加到遊戲物件上;它只是從編輯器功能表中消失了而已。通過現有的(舊版)Unity GUI 系統,您無法在場景視圖中看到您的 GUI 物件,只有在遊戲視圖中才能看到,這使得佈局創建有些奇怪。如果您喜歡,您可以用純程式碼來設置您的 GUI,而且 GUILayout 類可以讓您自動跟蹤小部件。但我更喜歡使用 GUI 系統,因為我可以在其中執行按一下和拖動操作,工作起來更輕鬆,這就是我覺得 uGUI 更為優越的原因。(在 uGUI 之前,這一領域中的主導產品是一個叫 NGUI 的相當可靠的協力廠商產品,它實際上被用作 uGUI 的初始程式碼庫。)
更新該顯示文本的最簡單方法就是在編輯器中搜索或指定對 GUI 文本遊戲物件的引用,並把它當作 .NET 中的標籤並更新其文字屬性。這使得更新螢幕 GUI 文本變得非常簡單:
void UpdateScore()
{
var score = GameObject.Find("Score").GetComponent<GUIText>();
score.text = "Score: 0";
}
這是一個稍微縮短了的範例。對於性能,在 Start 方法中,我其實是要緩存對 GUIText 元件的引用,以便在調用每個方法時都不對其進行查詢。
得分跟蹤跟蹤得分很容易。您只需要有一個類,能夠顯示公共方法或設定分數的屬性。在遊戲中將充當遊戲組織者的對象稱為“遊戲控制器”很常見。遊戲控制器可以負責觸發遊戲保存、載入、記分等。在這個範例中,我可以有一個類,能夠顯示分數變數,如圖 8 所示。我將這個元件分配給一個空的遊戲物件,以便在場景載入時使用。當更新得分時,GUI 被依次更新。在 Unity 編輯器中,對 _scoreText 變數進行指定。只需將任何 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 一樣,通過在關鍵幀中執行各種操作來創建動畫。我可以輕鬆地用整篇文章來介紹 Unity 中的動畫,但由於空間有限,我將在此簡要說明。Unity 有兩種動畫系統,舊系統和最新的 Mecanim 系統。舊系統使用動畫 (.ani) 檔,而 Mecanim 使用狀態來控制動畫檔的播放。
在預設情況下,2D 動畫使用 Mecanim。製作動畫的最簡單的方法是將圖片拖放到您的場景中,讓 Unity 為您創建動畫。開始時,我將一些單個 sprite 拖動到 Unity 中,接下來 Unity 為我創建一些東西。首先,它使用用來繪製 sprite 的 sprite 渲染器元件來創建遊戲物件。然後,它會創建一個動畫檔。您可以通過“視窗|動畫”和突出顯示自己的遊戲物件來進行查看。動畫器會顯示分配的動畫檔,就我的情況而言,包含六個關鍵幀,因為我將六幅圖像放進了我的場景中。每個關鍵幀控制元件上一個或多個參數;此處,它更改了 Sprite 渲染器元件的 Sprite 屬性。動畫只不過是以某個使眼睛能夠感知運動的速度顯示的一些單個圖像。
接下來,Unity 在遊戲對象上創建動畫器組件,如圖 9 所示。
圖 9 指向控制器的動畫器組件
該元件指向一個稱為動畫控制器的簡單狀態機。這是一個由 Unity 創建的檔,它只是顯示了預設狀態;換句話說,它總是處於“空閒”狀態,而這是也是唯一可用的狀態。這種空閒狀態除了指向我的動畫檔之外,沒有其他作用。圖 10 顯示了在時間線上的實際關鍵幀資料。
圖 10 空閒的動畫數據
只是要播放動畫,但是看上去似乎有很多事情要做。儘管狀態機的功能就是使您可以通過設置簡單的變數來控制它們。但請記住,狀態只會指向動畫檔(雖然在 3D 中,您可以別出心裁地做一些將動畫融合在一起之類的事情)。
然後,我將用更多的圖像來製作跑動的動畫,並將它們拖放到我的 Yeti 遊戲物件上。因為我已經將動畫器元件添加到遊戲物件上,所以 Unity 只創建一個新的動畫檔,並添加一個稱為“跑動”的新狀態。我只要在空閒狀態上按一下滑鼠右鍵,創建一個過渡來跑動。這將在空閒狀態和跑動狀態之間創建一個箭頭。那麼我可以添加一個名為“Running”的新變數,它簡單易用,您只需在狀態之間的箭頭上按一下,並更改使用變數的條件,如圖 11所示。
圖 11 從“空閒”狀態更改為“跑動”狀態
當“Running”為 true 時,空閒動畫狀態會更改為跑動動畫狀態,這僅僅意味著跑動動畫檔在播放。您可以輕鬆控制程式碼中的這些變數。如果您想在按一下滑鼠按鈕時通過觸發跑動狀態來啟動跑動動畫,您可以添加圖 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);
}
}
在我的範例中,我使用單個 sprite 來創建動畫。雖然,使用 sprite 表(一個單獨的影像檔,裡面含有多個圖像)是很常見的。Unity 支持 sprite 表,所以問題在於告訴 Unity 如何分割您的 sprite,然後將這些片段拖放到場景中。有所不同的幾個步驟分別為在 Sprite 屬性中將 Sprite 模式由單一更改為多個和打開 Sprite 編輯器,這樣可以自動分割 sprite 並應用所做的更改,如圖 13 所示。最後,展開 sprite(點擊專案視圖中的 sprite 圖示上的小箭頭),突出顯示所產生的 sprite,像之前那樣將它們拖放到場景中。
圖 13 創建 Sprite 表
在您學會這個系統之前,動畫一直都可能是一個很複雜的課題。若要瞭解詳細資訊,請查看我的 Channel9 部落格或 Unity 學習網站上的優秀資源。
關卡末尾當玩家玩到關卡末尾時,您可以簡單將碰撞體設置為觸發器,並允許玩家擊打該區域。當他這樣做時,您只需載入另一關卡或重新載入當前關卡:
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 遊戲中,流程是非常簡單的。玩家開始。剛體受到的重力會使玩家下落。玩家和平臺上設置了碰撞體,所以玩家會停止。讀取鍵盤、滑鼠和觸摸輸入並移動玩家。玩家通過應用使其能夠跳躍的 rigidbody.AddForce 在平臺之間進行跳躍,通過讀取 Input.GetAxis(“水準”),並將其應用到 rigidbody.velocity 來進行向左移動或向右移動。玩家拾起蘑菇(正是被設置為觸發器的碰撞體)。當玩家碰觸到它們,可以增加得分,同時也會自我毀滅。當玩家終於成功到達最後一個標誌時,會有一個碰撞體/觸發器重新載入當前關卡。此處,另一個待辦事項是在地面下添加一個大型碰撞體來檢測玩家掉落平臺的時刻,然後再重新載入該關卡。
預設在編碼和設計中,重複使用都是很重要的。當您指定一些元件並且自訂您的遊戲物件之後,總是要在相同的場景中,甚至多個場景或遊戲中重複使用它們。您可以在場景中創建某個遊戲物件的另一個實例,但您也可以創建一個並不存在於場景中的預設實例。考慮平臺及其碰撞體。如果您想在整個場景中重複使用它們,目前還不可以。但是,通過創建預設,就能做到。只需將任何遊戲物件從層次結構中拖回到專案檔案夾中,然後創建一個副檔名為 .prefab 的新檔,並且該新檔包括所有子層次結構。現在,您可以將這個檔拖放到您的場景中並重新使用它。原來的遊戲物件會變成藍色,表明它現在已連接到預設。更新 .prefab 檔可以更新場景中的所有實例,您也可以將更改從經過修改的場景預設推送回到 .prefab 文件中。
按一下預設可顯示裡面包含的遊戲物件,如圖 15 所示。如果在此處進行更改,場景中的所有實例都將被更新。
圖 15 查看預設內容
總結
還有一些在整個遊戲中執行的常用操作。在本文中,我介紹了使用碰撞體、剛體、動畫、得分記錄、基本的 GUI 文本以及讀取使用者輸入以使用力來移動玩家的遊戲平臺的基礎知識。這些構建的模組可以在各種遊戲類型中重複使用。請在我的下一篇文章中繼續關注 3D 討論話題!
其他學習
§ 請查看已構建好的此專案:channel9.msdn.com/Events/Build/2014/2-503
§ Microsoft Virtual 學院 - 使用 Windows 的 Unity 開發 2D 和 3D 遊戲:aka.ms/UnityMVA
§ Adam 的 Channel 9 部落格:aka.ms/AdamChannel9
§ Unity 資源:unity3d.com/learn
Adam Tuliper 是生活在陽光明媚的加利福尼亞州南部的一位 Microsoft 資深技術傳教士。他是一位獨立的遊戲開發人員,Orange County Unity Meetup(奧蘭治縣 Unity 聚會)的共同管理者,以及 pluralsight.com 的作者。他和他的妻子即將擁有自己的第三個孩子,所以在他尚有閒暇的時間裡,您可以通過訪問adamt@microsoft.com 或 Twitter twitter.com/AdamTuliper 來聯繫到他。
衷心感謝以下技術專家對本文的審閱:Matt Newman (Subscience Studios)、Tautvydas Žilys (Unity)
Comments
- Anonymous
October 12, 2014
Nice! This is also what people want: visualstudio.uservoice.com/.../3725445-xna-5 visualstudio.uservoice.com/.../4233646-allow-net-games-on-xbox-one