Unity MMORPG遊戲開發教程(一)——初識Unity

五邑隱俠,本名關健昌,10年遊戲生涯,現隱居五邑。本系列文章以C#爲介紹語言,基於Unity2017.4.x。

 

一、環境搭建

我使用的是Unity+VSCode,用的是mac系統,windows的自己搜資料,步驟差不多。

1.安裝Unity:下載Unity,我下載的是Unity2017.4.21f1。下載下來是一個下載助手UnityDownloadAssistant-2017.4.21f1.dmg,雙擊打開安裝。選擇安裝內容Unity2017.4.21f1、MonoDevelop/Unity Debugger、Documentation、Standard Assets。

2.安裝VSCode:個人喜好,VSCode比較輕量,寫代碼流暢一點。下載最新版本就可以。

3.下載dotnet:我下載的是dotnet-dev-osx-x64.1.1.11.pkg,雙擊打開安裝。

4.安裝VSCode插件:插件可以選擇unity3d-pack,由於我安裝失敗,所以把unity3d-pack裏面的插件都安裝了一遍:

  C#

  C# FixFormat

  C# Snippets

  C# XML Documentation Comments

  Debugger for Unity

  eppz! (C# theme for Unity)

  MonoBehaviour Snippets

  ShaderlabVSCode(Free)

  Unity Code Snippets

  Unity Tools

5.建立Unity項目:打開Unity,我新建的是2D項目

6.建立C#項目,目的是讓VSCode對C#代碼有提示。終端命令行cd到Unity項目根目錄,運行命令dotnet new console創建dotnet命令行工程。Unity項目根目錄下會生成 xx.csproj文件、obj目錄、bin目錄

7.添加unity庫引用,目的是讓VSCode能識別Unity的命名空間(UnityEngine、UnityEngine.UI等)。打開obj/project.assets.json文件,在compile節添加unity庫路徑,包括(有用到其他庫自己添加):

  "/Applications/Unity/Unity.app/Contents/Managed/UnityEngine.dll": {},

  "/Applications/Unity/Unity.app/Contents/UnityExtensions/Unity/GUISystem/UnityEngine.UI.dll": {},

這樣,Unity+VSCode的環境就搭建好,可以用VSCode寫腳本了。

 

二、編輯器簡介

1.工程結構管理器

 

 

2.場景層級管理器

 

3.場景編輯器

 

4.屬性編輯器

 

 

新建工程時,工程結構管理器中,Assets目錄下爲空,可以在下面創建場景,雙擊場景在場景層級管理器看到它的結構,在場景編輯器裏可視化編輯,右邊的屬性編輯器可以對相應對GameObject設置屬性、添加組件(包括腳本)。有使用過cocos creator經驗會很熟悉,不詳述。

 

三、熟悉開發流程

首先必須瞭解一些基本概念,

1.在Unity裏,遊戲由GameObject組成(可以理解成cocos裏的cc.Node),GameObject可以添加組件

2.組件基類爲Component,但用戶自定義的腳本都繼承自MonoBehaviour(Component的子類,如同cocos creator裏的cc.Component)

3.每個GameObject有基本的Transform,設置GameObject的座標

 

Assets目錄是遊戲開發所有資源存放的地方,包括圖片、聲音、腳本資源。我開發遊戲,一般只做一個scene,Assets目錄下新建一個目錄Scene,在下面新建場景Main(在文件系統中可以看到它的全稱是Main.unity)。

 

雙擊,在場景層級管理器中可以看到它的層級結構,默認只有一個Main Camera。爲了支持屏幕適配,編寫一個C#腳本,在Assets目錄下新建一個目錄Script,用於存放C#腳本。新建C#腳本MainCamera(文件系統中MainCamera.cs),用VSCode打開(VSCode直接打開整個項目的根目錄),添加以下代碼

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MainCamera : MonoBehaviour {

	public float designWidth = 6.4f;
	public float designHeight = 9.6f;

	// Use this for initialization
	void Start () {
		float screenHeight = Screen.height;
		float orthographicSize = this.GetComponent<Camera>().orthographicSize;
		float aspectRatio = Screen.width * 1.0f / Screen.height;
		// fix the litte side
		if (aspectRatio < designWidth / designHeight) { // fix width
			orthographicSize = designWidth / (2 * aspectRatio);
			this.GetComponent<Camera>().orthographicSize = orthographicSize;
			Debug.Log("FIX_WIDTH, orthographicSize is " + orthographicSize);
		} else { // fix height
			orthographicSize = designHeight / 2;
			this.GetComponent<Camera>().orthographicSize = orthographicSize;
			Debug.Log("FIX_HEIGHT, orthographicSize is " + orthographicSize);
		}
	}
	
	// Update is called once per frame
	void Update () {
		
	}
}

  

在Unity編輯器的場景層級管理器選擇Main Camera,在屬性編輯器中給它添加組件(Add Component -> Scripts -> Main Camera),現在可以設置遊戲的設計分辨率了。

 

遊戲啓動後,會根據GameObject“Main Camera”的生命週期觸發Main Camera腳本的Start方法,根據遊戲尺寸對照相機調整顯示高度(不適用於UGUI,UGUI待會介紹)。該適配方案要注意幾個概念,Unity默認單元大小爲100個像素,所以寬高是實際像素數除以100,照相機的orthographicSize等於照相機顯示高度的一半。如設置爲6.4x9.6,那麼美術出資源時一屏的大小就是640x960。不同的手機屏幕自動做等比例縮放,具體縮放倍數,當實際屏幕寬高比小於設計分辨率時寬縮放到跟實際屏幕一樣,否則高縮放到跟實際屏幕一樣。另外一邊相應等比例縮放,小的一邊鋪滿全屏可以避免出現黑邊,但也導致被裁剪,這種方式主要針對全屏的場景。

 

給主場景添加兩個GameObject:SceneLayer和PopupLayer,分別作爲場景和彈窗的根節點。

 

 默認組件Transform只有位置沒有大小,換成組件RectTransform,設置其大小爲設計分辨率

 
現在可以寫遊戲入口代碼了,在Script目錄新建腳本StartCtrl.ts,添加兩個屬性sceneLayer、popupLayer用於跟編輯器場景中的兩個GameObject關聯。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class StartCtrl : MonoBehaviour {

	public GameObject sceneLayer = null;
	public GameObject popupLayer = null;

	// Use this for initialization
	void Start () {

	}
	
	// Update is called once per frame
	void Update () {
		
	}
}

  

在Unity編輯器的場景層級管理器選擇Main Camera,在屬性編輯器中給它添加組件(Add Component -> Scripts -> Start Ctrl),把場景層級管理器的sceneLayer、popupLayer拖到對應的屬性完成關聯。啓動遊戲後,GameObject“Main Camera”的生命週期就會觸發StartCtrl裏對應的方法,StartCtrl裏的sceneLayer和popupLayer屬性已被賦值爲Main場景對應的子節點。後面我們會繼續講解如何使用這兩個屬性對界面進行分層管理。

 

我們先看看怎樣製作界面。我們可以把每一個界面都做成一個prefab預製體。Assets目錄下新建一個目錄Resources(該目錄資源可以用Resources.Load直接加載),Resources目錄下新建一個目錄Prefabs,預製體放到這個目錄(Unity建議使用AssetBoundle方式,可以將資源分包,後面調整結構)。
 
製作預製體的方法很簡單。先雙擊Scene/Main.unity打開,新建空GameObject,屬性面板將新GameObject名字改爲TestView,修改Transform組件爲RectTransform組件,設置大小爲設計分辨率,如6.4x9.6(注意1個單元100個像素),拖動該GameObject到工程結構管理器面板的Assets/Resources/Prefabs目錄。這樣一個預製體TestView就生成了。
 
預製體編輯完後可以從場景中刪除,需要再次編輯時從Prefabs目錄拖回場景中,修改完後點擊屬性面板的Apply同步,並從場景中刪除。
 
在預製體裏添加UI -> Text,會自動添加Canvas和EventSystem,一個負責渲染一個負責事件處理。這裏需要對界面做適配,Canvas屬於UGUI,需要在Canvas Scaler組件設置其設計分辨率和適配方案,其中這裏填的大小是設計分辨率的一半,如640x960填320x480。Match 0表示寬縮放到跟實際屏幕一樣,1表示高縮放到跟實際屏幕一樣。另外一邊相應等比例縮放。
 
 
同樣我們可以開始寫這個界面的腳本TestViewCtrl.cs,控制界面邏輯和刷新。這個腳本還是繼承MonoBehaviour,定義對應的Text等類型的屬性(記得using UnityEngine.UI),這樣就可以把界面的元素關聯到腳本,通過腳本來刷新。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TestViewCtrl : MonoBehaviour {

	public Text txtHello = null;

	// Use this for initialization
	void Start () {
		txtHello.text = "你好";
	}
	
	// Update is called once per frame
	void Update () {
		
	}
}

  

打開回剛纔那個預製體,選擇根GameObject,在屬性面板選擇添加組件TestViewCtrl,並將對應ui組件拖到腳本組件的屬性上進行關聯,這樣我們就可以通過TestViewCtrl控制這個界面了。

 
要顯示這個界面,首先要加載prefab。Unity提供了Resources.Load方法,加載Resources目錄下的資源(不要填後綴名),加載成功後通過Instantiate方法把預製體實例出一個GameObject,Unity的界面佈局也是基於組合模式的一棵樹,transform通過SetParent把自己添加到父的GameObject。所以,我們通過gameObj.transform.SetParent把這個界面放到屏幕,這些代碼可以寫在入口腳本StartCtrl的Start方法裏。可以通過GameObject.GetComponent獲取TestViewCtrl的實例來操作界面。不過,我一般是通過MonoBehaviour的生命週期和消息來實現界面更新,降低耦合,後面會詳細介紹這種方式。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class StartCtrl : MonoBehaviour {

	public GameObject sceneLayer = null;
	public GameObject popupLayer = null;

	// Use this for initialization
	void Start () {
		Object prefab = Resources.Load("Prefabs/TestView", typeof(GameObject));
		if (!prefab) {
			Debug.Log("Prefab is null");
			return;
		}

		GameObject gameObj = Instantiate(prefab) as GameObject;
		gameObj.transform.SetParent(popupLayer.transform);
	}
	
	// Update is called once per frame
	void Update () {
		
	}
}

  

現在我們已經知道怎樣建立遊戲入口,怎樣製作、加載、顯示界面,下一章將講解怎樣對彈窗分層管理。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章