前言
??為了記錄重構(gòu)筆記的進(jìn)度,我在Github上創(chuàng)建了一個(gè)名為PotatoGloryTutorial的Repository,里面的每個(gè)分支都記錄著對(duì)應(yīng)文章所做的修改。因?yàn)槠邢蓿芏嗑唧w的細(xì)節(jié)不會(huì)一一贅述,本篇文章對(duì)應(yīng)的分支為essay1,讀者可以將PotatoGloryTutorial這個(gè)倉庫clone至本地之后切換到essay1分支,以便查看具體的細(xì)節(jié)。
導(dǎo)入資源
??打開Unity(2017.3.0f3),點(diǎn)擊New,創(chuàng)建一個(gè)名為PotatoGloryTutorial的2D項(xiàng)目:

??打開Unity界面之后,我們需要導(dǎo)入資源。前面提到過,本項(xiàng)目大部分素材來源于Unity Assets Store上一個(gè)免費(fèi)的package 2D Platformer,因此可以直接在Asset Store上Download并Import。

??需要注意的是,2D Platformer是一個(gè)完整的項(xiàng)目,里面還包含了很多腳本,里面有很多寫得很不錯(cuò)的代碼,有興趣的讀者可以直接下載下來參考。此外,2D Platformer里面還包含已經(jīng)制作好的Animation和Prefab,不想浪費(fèi)時(shí)間自己從頭制作的讀者可以直接下載2D Platformer后刪除腳本文件,直接使用2D Platformer提供的資源。
??在這里,因?yàn)楸卷?xiàng)目的腳本不完全和2D Platformer一致,所以我們不直接下載完整的項(xiàng)目,而是導(dǎo)入我預(yù)先準(zhǔn)備好的資源package。下載完成之后,在Unity上方的菜單欄找到Assets選項(xiàng),點(diǎn)擊Assets->Import Package->Custom Package...,然后找到自己下載好的PotatoGlory.unitypackage,然后點(diǎn)擊Import導(dǎo)入全部資源。

調(diào)整Unity布局
??在正式開始搭建游戲背景之前,為了提高開發(fā)的效率,我們還需要調(diào)整一下Unity界面的布局。點(diǎn)擊右上角的Layout按鈕,會(huì)出現(xiàn)一個(gè)下拉菜單。

??個(gè)人最喜歡的布局方案是2 by 3,大家可以根據(jù)自己的喜好進(jìn)行選擇。選擇2 by 3方案之后,我們還需要做一些小調(diào)整,將Project窗口拖動(dòng)到Hierarchy窗口下方。當(dāng)然,這個(gè)調(diào)整只是出于我個(gè)人的習(xí)慣,讀者可以選擇不調(diào)整,也可以根據(jù)自己的喜好調(diào)整其他窗口,調(diào)整的方法都是鼠標(biāo)單擊窗口上方的選項(xiàng)卡,然后按住不放進(jìn)行拖動(dòng)。
??調(diào)整完成之后,再次點(diǎn)擊Layout,選擇Save Layout...,將其命名為Favorite,然后點(diǎn)擊Save。這樣,我們就新建了一個(gè)名為Favorite的布局,以后就可以通過選擇Favorite來快速恢復(fù)到我們現(xiàn)在調(diào)整的布局了。我們最終調(diào)整完成的布局如下所示:

創(chuàng)建游戲場(chǎng)景
??做好前期準(zhǔn)備之后,終于進(jìn)入我們今天的主題——?jiǎng)?chuàng)建游戲場(chǎng)景了。首先,我們右擊在Project窗口下的Assets文件夾,然后選擇Create->Folder來創(chuàng)建一個(gè)名為Scenes的文件夾,用于保存我們的游戲場(chǎng)景。然后直接按快捷鍵Ctrl + S,將Unity默認(rèn)打開的Untitled場(chǎng)景保存到Scenes文件夾下,并將其命名為SinglePlayerGameScene.unity。

設(shè)置Aspect
??接著,因?yàn)槲覀冏詈蟮哪繕?biāo)是做成一個(gè)Android手機(jī)游戲,所以我們還需要Game窗口下設(shè)置一個(gè)Aspect來預(yù)覽在手機(jī)上運(yùn)行的效果。這里,我們創(chuàng)建一個(gè)固定分辨率為1920x1080的Aspect,并將其命名為Android。

放置Sprite
??創(chuàng)建好Aspect之后,我們將Sprites\Environment目錄下的圖片env_bg從Project窗口直接拖動(dòng)到Hierarchy窗口里,可以看到在場(chǎng)景中出現(xiàn)了一張?zhí)炜盏谋尘皥D,但在Game窗口中,這張圖片的可見范圍很小。我們需要調(diào)大Main Camera的Size,使其能看到更大的范圍,這里,我們將其設(shè)置為11。

??調(diào)整完Camere之后,我們繼續(xù)通過拖拽往場(chǎng)景里面添加其他的素材。但奇怪的是,在添加素材的過程中,有可能出現(xiàn)后面拖進(jìn)去的素材在Scene和Game窗口里看不到的情況。這是因?yàn)樵赨nity里,攝像機(jī)按照從遠(yuǎn)到近的順序來渲染物體,后渲染的物體會(huì)覆蓋在先渲染的物體之上。而對(duì)于在攝像機(jī)投影方向上距離攝像機(jī)距離一樣的物體,它們的渲染順序是隨機(jī)的。
??想要保證物體A在物體B之后渲染,我們可以設(shè)置物體B在攝像機(jī)投影方向上與攝像機(jī)的距離比物體A近。在Unity的2D項(xiàng)目中,默認(rèn)使用的是Orthographic Camera,也就是正交攝像機(jī),其投影方向?yàn)?code>Z軸的正方向,默認(rèn)垂直于屏幕。因此,我們只需要按照物體的前后關(guān)系來設(shè)置它們的z坐標(biāo)的大小即可。但如果這樣做,當(dāng)場(chǎng)景中的物體增多時(shí)往往會(huì)出現(xiàn)記不清其他物體坐標(biāo)的問題,不僅難以管理,而且效率也低。
Sorting Layer
??為了解決這一問題,Unity在Sprite Renderer組件中提供了Sorting Layer和Order In Layer屬性讓我們使用。Unity在渲染Sprite時(shí),首先根據(jù)按照Sorting Layer的渲染順序來渲染Sprite,如果兩個(gè)Sprite處于相同Sorting Layer,那么就按照它們Order In Layer的值從小到大進(jìn)行渲染。倘若兩個(gè)SpriteOrder In Layer的值也相同,再按照在攝像機(jī)投影方向上距離攝像機(jī)距離的距離遠(yuǎn)近、也就是Z軸上的坐標(biāo)來渲染。
??選中場(chǎng)景中的env_bg,然后在Inspector窗口,點(diǎn)擊Add Sorting Layer...。打開Sorting Layer管理界面后,點(diǎn)擊右下角的+創(chuàng)建Background和Foreground兩個(gè)Sorting Layer,并用鼠標(biāo)選中Background將其拖到Default上方。創(chuàng)建完畢之后,已有的Sorting Layer如下所示:

??在Unity中,Sorting Layer的渲染順序?yàn)閺纳系较落秩?,也就是說,Unity會(huì)先渲染所有Sorting Layer為Backgroung的Sprite,然后繪制所有Sorting Layer為Default的Sprite,最后繪制所有Sorting Layer為Foreground的Sprite。
了解了
Sorting Layer的使用之后,我們往場(chǎng)景中添加剩下的所有Sprite,場(chǎng)景中所有的Sprite及其屬性如下:
- env_bg:
Position: (0, 0, 0)Sorting Layer:Backgroung,Order In Layer: 0- env_cloudTop:
Position: (0, 0, 0)Sorting Layer:Backgroung,Order In Layer: 1- env_BigBen:
Position: (0, 0, 0)Sorting Layer:Backgroung,Order In Layer: 1- env_Bank:
Position: (0, 0, 0)Sorting Layer:Backgroung,Order In Layer: 2- env_RiverBase:
Position: (0, -11, 0),Scale(2, 1, 1)Sorting Layer: Backgroung,Order In Layer: 3- env_TowerFull:
Position: (-22, 0, 0), Scale(1, 1, 1)Sorting Layer: Foreground,Order In Layer: 0- env_TowerFull (1):
Position: (22, 0, 0), Scale(-1, 1, 1)Sorting Layer: Foreground,Order In Layer: 0- env_PlatformBridge:
Position: (-12.3, -11.2, 0), Scale(1, 1, 1)Sorting Layer: Foreground,Order In Layer: 1- env_PlatformBridge (1):
Position: (12.3, -11.2, 0), Scale(-1, 1, 1)Sorting Layer: Foreground,Order In Layer: 1- env_PlatformTop:
Position: (-14.4, 0, 0), Scale(1, 1, 1)Sorting Layer: Foreground,Order In Layer: 1- env_PlatformTop (1):
Position: (14.4, 0, 0), Scale(-1, 1, 1)Sorting Layer: Foreground,Order In Layer: 1- env_PlatformUfo:
Position: (0, -4.62, 0)Sorting Layer: Foreground,Order In Layer: 2- env_UfoLegs:
Position: (0, -1.44, 0)Sorting Layer: Foreground,Order In Layer: 2
組織場(chǎng)景中的物體
??將所有的Sprite添加進(jìn)去之后,我們發(fā)現(xiàn)場(chǎng)景中的物體太多,不太雅觀。為了方便管理,我們可以使用Empty GameObject來組織場(chǎng)景中的物體。在Unity中,Empty GameObject只有Transform這一個(gè)組件,可以當(dāng)作空節(jié)點(diǎn)用來組織、管理其他的物體。
??在Hierarchy窗口右擊鼠標(biāo),選擇Create Empty,然后在Inspector窗口將其命名為Background,并Reset其Transform組件的屬性值。

??接著我們用同樣的方法,創(chuàng)建另外一個(gè)命名為Foreground的Empty GameObject,并重置其Transform組件的屬性值。創(chuàng)建完畢之后,我們?cè)?code>Hierarchy窗口中,將Sorting Layer為Background的物體拖到空物體Background下成為其子物體,將Sorting Layer為Foreground的物體拖到空物體Foreground下成為其子物體,最后,Hierarchy窗口的結(jié)構(gòu)如圖所示:

后言
??因?yàn)檫@是本系列第一篇講解項(xiàng)目具體制作過程的文章,有些地方寫得比較詳細(xì),也用了比較多的截圖來說明一些基礎(chǔ)操作。在后面的文章中,對(duì)于一些已經(jīng)介紹過、或者比較簡(jiǎn)單的基礎(chǔ)操作,將會(huì)使用文字描述。最后,本篇文章所做的修改,可以在PotatoGloryTutorial這個(gè)倉庫的essay1分支下看到,讀者可以clone這個(gè)倉庫到本地進(jìn)行查看。