本章節(jié)我們介紹一下“預制件”,也有人叫“預制體”,也就是Prefab。在游戲世界中,那些自然環(huán)境的游戲?qū)ο?,我們可以提前?chuàng)建在場景中,這個大家能夠理解。但是,有些游戲?qū)ο螅枰鶕?jù)游戲邏輯來通過代碼生成,例如刷新怪物,觸發(fā)機關(guān)等等。Unity 的預制件系統(tǒng)允許創(chuàng)建、配置和存儲游戲?qū)ο蠹捌渌薪M件、屬性值和子游戲?qū)ο笞鳛榭芍赜觅Y源(它的本質(zhì)就是一個資源文件,相當于編程里面的類文件,通過它可以實例化多個對象)。預制件資源充當模板,在此模板的基礎(chǔ)之上可以在場景中創(chuàng)建新的預制件實例。對預制件資源所做的任何編輯都會自動反映在該預制件的實例中,因此可以輕松地對整個項目進行廣泛的更改,而無需對資源的每個副本重復進行相同的編輯。
預制體是用來存儲一個游戲?qū)ο蟮乃薪M件,屬性和子對象,這樣就成為了一個可重復使用的資源文件。當需要多次重復使用這個游戲?qū)ο髸r,便可以使用預制體來創(chuàng)建。舉一個簡單的例子,我們會在游戲世界中創(chuàng)建同一種怪物模型的實例,顯然我們不可能將怪物模型一個個的拖拽到游戲世界中,并且這些怪物會死亡消失,也會重新刷新。因此,合理的解決方案應該是,每一種怪物都應該是一個預制體,然后我們可以通過預制體來創(chuàng)建不同的怪物實例,這就是預制體的優(yōu)勢。當然,預制體更重要的是對游戲?qū)ο蟮摹胺庋b”,預制體不僅僅是網(wǎng)格模型,同時還可以包含各種功能組件以及腳本,這樣的預制體就能承載更多的內(nèi)容。
接下來,我們回到ScriptDemo項目工程中,創(chuàng)建一個新的“SampleScene7”場景,然后創(chuàng)建一個“Cube”游戲?qū)ο蠛汀癈ubePrefab.cs”腳本文件,并將其附加在一起。
?
接下來,我們在“CubePrefab.cs”腳本文件實現(xiàn)Cube自旋轉(zhuǎn)的代碼,如下所示:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CubePrefab : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
transform.Rotate(new Vector3(0, 1, 0));
}
}
為了更好的觀察Cube,我們將攝像機向上Y軸方向移動5個單位,且X軸方向旋轉(zhuǎn)20度,這樣就能俯視Cube了。
接下來,我們保持相機選中狀態(tài),我們點擊菜單欄“GameObject”->“Align View to Selected”
然后我們Play當前工程,效果如下:
接下來,我們要做的就是創(chuàng)建十個這樣的旋轉(zhuǎn)立方體,粗暴的辦法就是再創(chuàng)建9個Cube,然后將“CubePrefab.cs”腳本文件分別附加到這9個Cube身上,顯然這種方式不太合理。此時,我們就需要借助預制體來實現(xiàn)了。首先我們要創(chuàng)建預制體,創(chuàng)建的方法非常簡單,就是將“Hierarchy”視圖中的Cube游戲?qū)ο笸献У健癙roject”視圖中。
這樣一個名稱為“Cube”的預制體就創(chuàng)建成功了,同時在“Hierarchy”視圖中“Cube”的名稱顏色會變成藍色,代表這個名稱為“Cube”的游戲?qū)ο笫且粋€預制體實例。
請注意,預制體本質(zhì)是一個資源文件,也就是“Project”視圖中的“Cube”文件,如果我們?nèi)ノ覀兊墓こ棠夸浵碌腁sset文件夾下面查看,就能看到一個“Cube.prefab”的預制體文件。
那么“Hierarchy”視圖中“Cube”又是什么呢,它其實就是預制體的一個實例而已。我們可以將預制體理解為面向?qū)ο笞兂芍械念愇募惥褪且粋€模板,我們可以根據(jù)這個類實例化很多很多的對象,這些對象都擁有類中實現(xiàn)的功能,只是每一個對象的內(nèi)部數(shù)據(jù)不一樣。既然“Cube.prefab”是一個預制體,它與類模板概念相同,我們就可以根據(jù)這個預制體來實例化很多很多的游戲?qū)ο?,也就是“Hierarchy”視圖中“Cube”。將一個預制體實例化為一個游戲?qū)ο?,需要借助“GameObject.Instantiate”方法,該方法有三個參數(shù),第一個就是預制體文件,第二個就是游戲?qū)ο蟮奈恢茫谌齻€就是游戲?qū)ο蟮某?。接下來,我們來實現(xiàn)這個功能。我們首先刪除調(diào)當前場景中的“Cube”游戲?qū)ο?。然后,我們?chuàng)建一個“CubePrefabManager.cs”的腳本文件,并將其附加到攝像機上面去。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class CubePrefabManager : MonoBehaviour
{
// 預制體文件
public GameObject prefab;
// 預制體實例數(shù)量
private int count;
// Start is called before the first frame update
void Start()
{
// 加載預制體文件
prefab = AssetDatabase.LoadAssetAtPath("Assets/Cube.prefab", typeof(GameObject)) as GameObject;
}
// Update is called once per frame
void Update()
{
// 按下空格鍵就生成一個自旋轉(zhuǎn)的Cube
if (Input.GetKeyDown(KeyCode.Space))
{
count++;
Vector3 pos = new Vector3(count * 2, 0, 0);
GameObject.Instantiate(prefab, pos, Quaternion.identity);
}
}
}
不要忘了,將“CubePrefabManager.cs”腳本附加到相機上。以上代碼有三點需要解釋。第一,我們的prefab文件需要載入,它的本質(zhì)就是GameObject類型。第二,我們按下空格鍵來根據(jù)prefab來創(chuàng)建一個游戲?qū)ο髮嵗5谌?,?chuàng)建的prefab實例的位置依次向右遞增,但是他們的朝向(旋轉(zhuǎn))統(tǒng)一是Quaternion.identity(不旋轉(zhuǎn)/默認值)。接下來,我們就可以Play當前工程,查看效果。
當我們實例化出來四個Cube游戲?qū)ο髮嵗臅r候,他們的名稱都是“Cube(Clone)”,也就是復制克隆出來的。這個應該比較容易理解。我們從Hierarchy層次面板中就能看到。
最后我們要說的就是關(guān)于prefab文件的加載。上面的代碼中,我們使用了AssetDatabase.LoadAssetAtPath方法(還有使用“using UnityEditor;”)。其實我們我們可以將“Cube.prefab”文件放置工程目錄“Assets/Resources”下。這個“Resources”目錄是一個特殊的目錄,它對應Unity API中的Resources類,該類有一個Load靜態(tài)方法,可以直接讀取下面的預制體文件。接下來,我們就創(chuàng)建“Resources”,并將“Cube.prefab”復制到這個文件夾下,重命名為“Cube2.prefab”,如下圖所示:
然后我們修改“CubePrefabManager.cs”代碼:
// 加載預制體文件
//prefab = AssetDatabase.LoadAssetAtPath("Assets/Cube.prefab", typeof(GameObject)) as GameObject;
prefab = Resources.Load<GameObject>("Cube2 ");
當然,此方法并不只是加載prefab資源文件,還可以加載其他文件(例如貼圖)。注意,這個方法不需要我們使用“using UnityEditor;”,并且參數(shù)為預制件名稱(不需要文件后綴)。為了更好的管理這些資源文件,我們可以繼續(xù)在“Assets/Resources”規(guī)劃子目錄管理他們。那么,在使用Resources.Load加載的時候,只需要在參數(shù)中按照“xxx/yyy”方式加載即可。這種方式還是比較推薦的。接下來,我們Play工程,看到之前一樣的效果了。
還有兩一種更加省時省力的辦法。由于我們聲明的prefab變量是public類型,因此可以在Inspector檢視面板中編輯這個prefab變量。我們在Hierarchy層次視圖中點擊選中相機,然后查看Inspector檢視面板,如下所示:
然后,我們可以直接將“Project”視圖中的“Cube”預制體拖拽到這個屬性值上面。
這樣,我們就不用使用代碼來加載這個預制體文件啦。
我們注釋調(diào)start中的代碼,如下文章來源:http://www.zghlxwxcb.cn/news/detail-478993.html
// Start is called before the first frame update
void Start()
{
// 加載預制體文件
//prefab = AssetDatabase.LoadAssetAtPath("Assets/Cube.prefab", typeof(GameObject)) as GameObject;
//prefab = Resources.Load<GameObject>("Cube2");
}
接下來,我們重新Play工程,就能看到之前一模一樣的效果了。我們就不添加效果圖了。文章來源地址http://www.zghlxwxcb.cn/news/detail-478993.html
到了這里,關(guān)于第十六章 Unity 預制件prefab(上)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!