Unity Game Development

第5~6話 Tile map & Prefab

Lecturer:水獺

目錄(可點)

本堂課內容

本堂課內容

Tile map(瓦片地圖)

這是什麼?

前一堂課我們教了使用GameObject建立遊戲場景的方式

但是大家應該都會覺得

這樣瘋狂複製、拉位置的無限循環很麻煩

所以今天我們要來用一個更方便的工具

也就是由格線系統和Tile(瓦片)所組成的「Tile map(瓦片地圖)」

可以讓你更有效率的構建心目中的遊戲場景

今天的操作皆可以用之前的專案延續

如果還沒上過課的就新開疑個吧!

如何獲得Tile?

Tile map,顧名思義就是Tile(瓦片)和Map(地圖||網格系統)

首先我們要先來取得能夠在地圖上放置的Tile

在Hierarchy裡點右鍵,按2D Object --> Tilemap --> Rectangular,創建一個矩形網格的Tile map

如何獲得Tile?

點選Grid(網格),可以看到網格圖出現在Scene介面裡

右邊的Grid Component裡可以調整一些如單個網格長寬、網格間隔、網格類型(六角、斜向、矩形)、空間座標編排等參數

單個網格長寬

網格間隔

網格類型

空間座標編排

如何獲得Tile?

要在網格系統上放置Tile首先需要TilePalette

可以理解為一個儲存各種瓦片待用的調色板

按左上角的Window --> 2D --> Tile Palette

開啟調色板視窗之後

可以把它丟去畫面右邊Inspector那個地方

調整你正在編輯的Tilemap

調整你正在使用的調色盤(這是我建立的,你們沒有正常)

調整你正在使用的筆刷(之後會用到)

如何獲得Tile?

第一個取得瓦片的方式是去Unity Asset Store

  匯入資源的部分請見之前簡報的11-9頁開始

假設我要用這個Pack:

如何獲得Tile?

Import之後如果你的Pack裡已經有附Palette

那就可以直接在下方選擇並開始放置瓦片

如果沒有出現可以去剛剛匯入的Pack資料夾裡

找找附檔名是.prefab、有很多物件在裡面的檔案(因為可能沒有讀到)

如何獲得Tile?

再來

如果你的Pack裡沒有Palette或者你有自己的圖像資源可以使用

那你可以選擇自己把待用的瓦片放上Palette

在「調整正在使用的Palette」那邊點一下

下拉選單選Create New Palette後

如果你的Sprite是正方形就直接按Create

如果是長方形就改短邊的Cell Size

(比如長方形x:y是1:0.8,就把y改成0.8)

如何獲得Tile?

在彈出視窗中選擇TilePalette資料夾,按「選擇資料夾」後

你就會得到一個全新的空白調色板

如果你的Sprite是正方形

將Sprite的Pixel Per Unit數值改成Sprite的大小

如果是長方形就改成長邊的長度

這樣才能確保放置Tile時不會超出範圍

這步不會的請見之前簡報的5-14第二個箭頭

接著在Assets資料夾裡創建兩個新資料夾

Tiles:用來存瓦片Assets檔

TilePalette:用來存調色板

如何獲得Tile?

之後將你有的Sprite直接拖進TilePalette視窗裡

在彈出視窗中選擇Tiles資料,按「選擇資料夾」後

就可以使用該瓦片了

如何獲得Tile?

第三種我覺得很酷

Unity有內建一個圖像切割器

可以幫你把找到的Tileset(一張有很多Tile的圖)

切成很多小塊,之後就可以一次放進Palatte裡

Tileset

如何獲得Tile?

先藉由Tile數量和Tileset圖片的總大小算出一個Tile的大小

比如這個就是512/32=16

之後將Tileset Sprite的Sprite Mode改成Multiple、

Pixel Pre Unite改成一個Tile的大小

改完後進入Sprite Editor

1

2

3

如何獲得Tile?

看到左上角的Slice

將Type改成Grid by Cell Size

Pixel Size改成剛剛計算好的單格大小

按下Slice之後記得右上角Apply

1

2

3

如何獲得Tile?

之後創建一個新的Palette

把整個Sprite拖進去

你會發現他非常整齊的分布在每個格子裡(舒服

就可以開始放置Tile啦~

如何使用?

選取Hierarchy中的「Tilemap」

Grid的子物件,不要選錯!

介紹一下Tile Palette介面的功能

選取

(大範圍刪除可使用)

移動選取範圍的Tile

畫筆

(筆刷)

選取同時放置瓦片

取色器

(會同時取到Tile跟畫筆)

橡皮擦

(無法大範圍)

封閉區域填充工具

就很像繪圖軟體的各種功能

大家可以自己試試看,不懂再問我

記得一切的編輯都在Scene介面中進行

專屬Collider

在建構好地圖之後

還沒上過課的同學可以將想放的遊戲角色一起放上去

並幫他加好Collider、Rigidbody等Component

再編寫一個移動程式

可參閱之前簡報

好了之後啟動遊戲

你會發現剛剛畫的地圖一點用都沒有

而且之前用在角色上的Collider也對Tilemap無效

這該怎麼辦?

專屬Collider

Unity為Tilemap做了一個專屬的Collider

就叫做Tilemap Collider

好了之後啟動遊戲

現在已經可以運作了!

選取Tilemap

在Add Component搜尋Tilemap Collider 2D並加入

把Rigidbody改成Kinematic或Static

然後還要記得

因為上次的RayCast我們是用platform這個Layer來判斷著地與否

所以記得把Tilemap物件的Layer也改成platform

專屬Collider

但是大家可以發現

現在的Collider是一個Tile一個

除了可能會吃到效能之外

也有可能會卡到角色移動

所以我們要把它變成Composite Collider

也就是一整個大的Collider

專屬Collider

把Tilemap Collider 2D的Used By Composite打勾

之後加入Composite Collider 2D

就大功告成啦

專屬Collider

另外,如果你不想要所有的瓦片都有Collider的話

Tile大小一樣的可以在同個Grid底下用多個Tilemap

(不一樣的則可以多開Grid)

畫的時候記得選到對的Tilemap

(然後不一定只能選一塊ㄛ

比如說我選那棵樹就可以一次畫整棵樹了)

調整顯示順序的方式跟Sprite相同

本堂課內容

本堂課內容

Prefab(預製件)

這是什麼?

Prefab,預製件,也就是預先製做好的遊戲物件

在做一些如預生場景、射擊功能之類的東西很好用

舉個例子

這是用上次的陷阱套用陷阱造型的一個陷阱

如果我要做一堆這種陷阱

那可以怎麼做?

複製一堆(X) 用Prefab(O)

這是什麼?

為何不用複製的?

因為這樣複製出來的物件如果要變動

就要一個一個手動改

非常麻煩

假設我現在覺得陷阱大小太大

或者我想要他變成紅色的

那就要連續改三次

雖然要多選編輯也可以

不過如果很多或者不同場景還是不方便

這是什麼?

那如果用Prefab呢

這樣就可以在修改Prefab的時候連帶修改其他由這個Prefab產生的GameObject

會方便非常多!

這樣就只要改一次就好ㄌ

(第二個刺再調暗一點直接開始陰人

如何使用?

簡單來說

預製件的原理就是把GameObject存成一個Asset
有點像模板的感覺

那我們要怎麼做一個預製件?

很簡單,如果你有GameObject

只要把它拖進Project頁面就行了

(記得創一個Prefab資料夾)

如果要直接在Project介面按Create --> Prefab之後在裡面編輯也可以

如何使用?

之後你就可以發現你的GameObject左邊的圖標

變成藍色了ㄌ

之後如果是從Project介面裡拉出來創建的GameObject圖標也會是藍色的

如何使用?

在Project介面裡點兩下Prefab之後可以打開編輯介面

在這裡你可以對這個Prefab做所有的常規調整

包含加入/移除Component、大小/旋轉/顏色等所有的Component參數調整之類的

調整後的參數「幾乎都會」應用到場景裡用這個Prefab生成的GameObject

比如我剛調了這個奇怪的樹幹顏色

如何使用?

為什麼說「幾乎都會」?

剛剛各位如果眼睛比較尖的可能有發現

17-1(也就是那隻貓)也是個Prefab

但他的左邊有一條藍色直線,這是為什麼?

如何使用?

這是因為當一個Prefab被生成之後還是可以個別編輯

如果有個別對其做更動,Unity Editor就會把它標出來

而且不僅是物件

連哪個Component的哪個參數不一樣都會有藍線標出來

並且不一樣的參數不會因為Prefab更動而改變

Prefab編輯介面Inspector

GameObject Inspector

即使Prefab從1改成2

這裡一樣是0.5

如何使用?

這裡的Overrides按下去之後可以看到跟Prefab不同的地方,繼續點可以看到更細的資訊

Revert All可以把這個GameObject還原成跟Prefab一樣的狀態

Apply All則可以把Prefab變成跟GameObject一樣的狀態

如何使用?

講了這麼多,如果你還是覺得一個一個複製比較好那我也尊重w

不過為了遊戲物件的一致性以及維護的人的肝著想,這邊建議把所有會重複出現的遊戲物件都做成Prefab是最好的

最後,如果一個Prefab有子物件

那在它被做成GameObject(實例化)的時候

子物件是不能被刪除的,但參數還是可以改

如果想解除一個GameObject的Prefab狀態

可以按Prefab --> Unpack/Unpack Completely

前後差別在前者只會解除最上層父物件的Prefab狀態

而後者會把所有子物件一起解除Prefab狀態

想還原的話則可以Reconnect Prefab然後選擇原本的Prefab

實例化

有了Prefab之後

我們當然不會希望每次只能在遊戲開始前從Unity Editor放置好Prefab

所以現在要開始教大家如何使用程式生成GameObject(實例化Prefab)

在這邊我們已知上次這隻貓已經成功拿到毛線球

並且成功練成可以射出毛線球的能力

要實作這個功能

我們需要有一個毛線球的Prefab

大家可以試著做做看類似的東西(子彈)

實例化

毛線球設定(僅供參考)

(記得儲存再測試,這裡一步沒弄好都可能讓你電腦死機,因為太多碰撞了)

實例化

射擊程式碼(給貓)

實例化

射擊程式碼(給貓)

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

public class YarnBallShooting : MonoBehaviour
{
    [SerializeField] GameObject yarnBallPrefab; //在Unity Editor中放入毛線球的Prefab
    GameObject cat; //玩家GameObject
    [SerializeField] float shootingForce = 0; //可在Unity Editor裡編輯的射擊力道
    void Start()
    {
        cat = GameObject.FindGameObjectWithTag("Player"); //以tag取得玩家角色
    }
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.I)){ //當按下I鍵時呼叫射擊函式
            Shooting();
        }
    }
    void Shooting(){
        GameObject yarnBall = Instantiate(yarnBallPrefab,cat.transform.position,Quaternion.identity); //在玩家位置實例化毛線球,不旋轉
        yarnBall.GetComponent<Rigidbody2D>().AddForce(Vector2.one*shootingForce*transform.localScale.normalized.x,ForceMode2D.Impulse);
        //取得毛線球剛體並加一個大小為射擊力道、方向與玩家同方向的力給毛線球
    }
}

實例化

毛線球程式碼

實例化

毛線球程式碼

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

public class YarnBall : MonoBehaviour
{
    void OnCollisionEnter2D(Collision2D col) {
        if(col.gameObject.tag == "platform"){
            Destroy(gameObject); //打到地形毛線球消失
        }
        if(col.gameObject.tag == "trap"){
            Destroy(col.gameObject); //打到尖刺使尖刺消失
            Destroy(gameObject); //毛線球消失
        }
    }
}

實例化

把程式碼附著到Prefab上

之後把該拖的拖進初始化框框

應該就可以運作啦

實例化

本堂課內容

本堂課內容

組合技

  • 安裝2D Tilemap Extra Pack
  • Random brush
  • Prefab random brush

安裝Git

這是一個版本控制的軟體

如果你有用Github的話

它也是Github的基礎

Git官方網站下載你的電腦對應的版本

然後安裝

就醬w

安裝2D Tilemap Extra Pack

這是一個Tilemap的延伸模組

裡面有一些很酷的東西

今天主要會教筆刷的延伸

首先開啟你的Unity Package Manager

左上排Window --> Package Manager

安裝2D Tilemap Extra Pack

按左上角的+

選Add package from git URL

安裝2D Tilemap Extra Pack

之後輸入以下網址

https://github.com/Unity-Technologies/2d-extras.git

安裝2D Tilemap Extra Pack

之後應該就可以看到一個Package出現在你的Package Manager裡

而且旁邊有一個「Git」的框框

Random Brush

那這個Package可以幹嘛?

有的時候我們可能需要做一些隨機生成的地形

這個時候如果一次點一種Tile去畫那就太慢了

這個Package提供了幾種筆刷

可以達成這種隨機的效果

首先要講的是單純的Sprite筆刷

Random Brush

首先大家可以先在Assets資料夾裡創一個Brushes資料夾來存筆刷

之後按右鍵 --> Create --> 2D --> Brushes --> Random Brush

創建一個隨機筆刷

首先大家可以先在Assets資料夾裡創一個Brushes資料夾來存筆刷

之後按右鍵 --> Create --> 2D --> Brushes --> Random Brush

創建一個隨機筆刷

Random Brush

使用非常簡單

點到Tile Palette介面

在筆刷處選擇剛剛新建的筆刷

之後選到畫筆功能一次拖曳選擇所有你想隨機放置的Tile

在我選了三個Tile之後

可以發現下面多了三個

這就是等等會被隨機放置的Tile

Random Brush

選好之後就可以把這個選項關掉

等到要換Tile的時候再打開選取

之後看你需要的範圍在Tile Palette裡隨便選取就能決定畫筆範圍大小

只看範圍不看裡面是否有Tiles

比如我選了一個1*10的範圍

不管裡面是空的還是有Tiles

畫筆的大小都會從1*1改成1*10

對於大範圍的放置很方便

大家就可以去畫自己心目中的地圖啦!

Prefab Random Brush

再來終於要進到這節的大重點

有的時候

在地圖上的一些物件如果要自己調整座標真的很麻煩

而且如果是Prefab的話在預設情況下就只能用手拉,沒有別的調整方式

如果這個時候有一個可以方便放置物件在特定位置上的工具就很棒

所以就有人發明了:

組合技——Tilemap + Prefab!!

也就是Prefab Brush/Prefab Random Brush

Prefab Random Brush

這個東西的重點是利用Tilemap的父物件

也就是Grid物件的Grid Component來計算Prefab的擺放位置

並且以計算好的位置實例化Prefab

所以要注意雖然說是Tilemap + Prefab

但是放置的東西並不是Tile而是Prefab

所以如果要大面積刪除須要直接用滑鼠拖曳而不是選取工具

Prefab Random Brush

使用方法跟Random Brush稍微有點不同

首先一樣在Brushes資料夾裡右鍵 --> Create --> 2D --> Brushes --> Prefab Random Brush

建立一個新筆刷

點一下之後右邊的Inspector應該長這樣

會被隨機放置的Prefab清單

依我自己使用的經驗,這一欄應該是代表放出不同Prefab的機率,可以自己調整看看

Prefab Random Brush

可以按一下Prefabs List下方的+,就會新增一個空欄位

可以按下右邊的圓圈,彈出視窗會把目前Project裡的Prefab列出來給你選,或者也可以直接把Prefab拖曳進去

Prefab Random Brush

好了之後會長這樣

之後回到Tile Palette

設定好Tile map跟Brush之後

再調整一下Perlin Scale到自己想要的效果

就可以開始放置隨機的Prefab了

那要如何調整單格的間距和長寬?

Prefab Random Brush

前面有講到,這個工具決定Prefab擺放位置的方式是Grid Component裡的參數

包含長寬、間距等

現在我們新開一個Tile map並進入Grid物件的Inspector

Prefab Random Brush

現在我想讓水果有個浮在空中的感覺

所以我把Cell Size的Y改成2

點回Tile map之後可以看到更改後的Grid

Prefab Random Brush

之後把Tile Palette的Tile map設成新的

就可以開始放了

注意:請確認好之後再放,之後如果要改要先全部刪掉、改Grid之後再重放,有點麻煩

這裡放的每個物件都不是Tile,而是一個獨立的Prefab,所以可以玩得非常有變化性,大家可以思考看看~

本堂課內容

本堂課內容

Prefab應用

Prefab應用

這Part算是給你們一些靈感

因為步驟有點繁瑣而且算是前面的知識融合

所以詳細步驟我沒放在簡報上

我會把這幾個東西都示範過一次

如果有興趣跟著做的就跟著做做看

會讓你更加熟悉這兩節課的操作

預生地圖

這個應用的重點是

你可以在Prefab中建立Tile map

之後可以選擇單純放置Tile或用Random Brush放置

也可以用Prefab Brush/Prefab Random Brush放置Prefab來達成更多變化的地圖

而當你有了各種不同預先畫好的地圖

就可以選擇用Instantiate方法指定/隨機生成地圖了

預生遊戲角色

遊戲角色先製作成Prefab之後

在遊戲開始時或者角色死亡重生時實例化在指定位置

也可以應用在生成敵人角色的情況上

當然等等的射擊也跟這個有關

射擊效果

把子彈製作成Prefab後

加上摧毀目標和消失等等的腳本

再偵測射擊按鍵按下

並實例化在遊戲角色的位置且同步方向

也可以搭配接下來的粒子效果

粒子效果

在Prefab內新增Partical System

設定好之後根據需求在某事件發生時實例化

如打擊碎裂的碎片效果、射擊的火花效果、跳躍落地的震波等

也可以利用粒子效果特殊的碰撞器做出一些很酷的效果

有興趣的話之後會細講

Q&A&DO

建北電資Unity遊戲開發小社第5、6堂

By MH Yang

建北電資Unity遊戲開發小社第5、6堂

  • 99