引言:在游戲設(shè)計中,需要用到的物體都可以用編輯器放在場景中。但很多時候,無法事先創(chuàng)建所有需要的物體,如子彈、刷新的怪物之類。這些要么是根據(jù)玩家操作而隨時創(chuàng)建,要么是根據(jù)游戲玩法在特定時刻創(chuàng)建,都無法事先確定它們在什么時候出現(xiàn)。
而用腳本動態(tài)創(chuàng)建物體,即在游戲進(jìn)行中創(chuàng)建物體,是一項(xiàng)基本技能,本文將詳細(xì)講解實(shí)現(xiàn)這一功能的基本方法
一、預(yù)制
預(yù)制就是一個物體的模版,在游戲開發(fā)中,一般將物體設(shè)為預(yù)制,詳細(xì)見這篇文章:Unity入門
二、創(chuàng)建物體
利用預(yù)制創(chuàng)建物體,需要使用實(shí)例化方法Instantiate()。它需喲一個預(yù)制體的引用作為模版返回值總是新創(chuàng)建的那個物體的引用。如果預(yù)制體以GameObject類型傳入,那么返回的結(jié)果也是GameObject類型。
在實(shí)際使用時,有時候要具體制定新建物體的位置、朝向和父物體,因此Intantiate()方法也有多重重載形式,區(qū)別在于參數(shù)不同。這里展示三種重載形式
重載形式 |
參數(shù)1 |
參數(shù)2 |
參數(shù)3 |
參數(shù)4 |
僅指定父物體 |
預(yù)制 |
父物體的Transform類型,null表示沒有父物體,置于場景根節(jié)點(diǎn) |
?文章來源地址http://www.zghlxwxcb.cn/news/detail-485657.html |
? |
指定位置和朝向 |
預(yù)制 |
空間位置,世界坐標(biāo)系,Vector3類型 |
朝向,Quaternion類型 |
? |
指定位置、朝向和父物體 |
預(yù)制 |
空間位置,世界坐標(biāo)系,Vector3類型 |
朝向,Quaternion類型 |
父物體的Transform類型,null表示沒有父物體,置于場景根節(jié)點(diǎn) |
預(yù)制體也可以用組件表示。由于組件可以代表所掛載的組件,因此如果以某個預(yù)制體上的組件作為模版,Instantiate方法依然會把該物體創(chuàng)造出來,同時返回新物體上同名的組件。這雖然保持了功能不變,但稍一不獲取組件的操作。
下面舉一個用腳本創(chuàng)建物體的例子
using UnityEngine;
?
public class TestInstantiate : MonoBehaviour
{
? ? ?public GameObject prefab;//設(shè)置為public,以便在編輯器中賦值
? ? ?void Start()
? ? ?{
? ? ? ?GameObject objA=Instantiate(prefab,null);//在場景根結(jié)點(diǎn)創(chuàng)建物體
? ? ? ?GameObject objB=Instantiate(prefab,transform);//創(chuàng)建一個物體,作為當(dāng)前腳本所在物體的子物體
? ? ? ?GameObject objC=Instantiate(prefab,new Vecrtor3(3,0,3),Quaternion.identity);//創(chuàng)建一個物體,確定位置和朝向
? ? ?}
}
用腳本創(chuàng)建物體在一些需要擺放精準(zhǔn)圖形的時候也會用到,下面是用腳本創(chuàng)建10個物體擺放成一個環(huán)形的例子
using UnityEngine;
?
public class TestInstantiate : MonoBehaviour
{
? ? ?public GameObject prefab;
? ? ?void Start()
? ? ?{
? ? ? ? ?for(int i=0;i<10;i++)
? ? ? ? {
? ? ? ? ? Vector3 pos=new Vector3(Mathf.Cos(i*(2*Mathf.PI)/10),0,Mathf.Sin(i*(2*Mathf.PI)/10);//用到了sin和cos在x-y坐標(biāo)系中的定義
? ? ? ? ? pos=pos*5;//半徑=5
? ? ? ? ?Instantiate(prefab,pos,Quaternion.identity);
? ? ? ?}
? ? ?}
}
三、創(chuàng)建組件
通常使用GameObject.AddComponent()方法,以下代碼先獲取Cube物體,再給它添加Rigidbody組件
using UnityEngine;
?
public class TestInstantiate : MonoBehaviour
{
? ? ?void Start()
? ? ?{
? ? ? ? GameObject go=GameObject.Find("Cube");
? ? ? ? ?go.AddComponent<Rigidbody>();
? ? ?}
}
四、銷毀物體或組件
使用Destroy()方法可以銷毀物體或組件,這里就不展開例子了。
但在這里有一個要點(diǎn)要注意:在執(zhí)行Destroy操作后,并不會立即銷毀該物體,而是稍后放在合適的時機(jī)去銷毀。這樣就保證了在那一幀里,對該物體的操作不會產(chǎn)生錯誤。
在個別情況下如果需要立即銷毀,Unity提供了DestroyImmediate()方法。
五、定時創(chuàng)建和銷毀物體
游戲中延遲創(chuàng)建物體和延遲銷毀物體是常見的需求。
延遲創(chuàng)建一般用于等待動畫結(jié)束和定時刷新怪物等。延遲銷毀物體則用于定時讓子彈、尸體消失等情況。
延遲需要準(zhǔn)確定時,如在未來的第幾秒執(zhí)行。這里舉例用簡易的Invoke方法。該方法有兩個參數(shù),第一個參數(shù)是以字符串表示的方法名稱,第二個參數(shù)表示延遲的事件,單位為秒。
Invoke方法可以延遲調(diào)用一個方法,但要求該方法沒有參數(shù)也沒有返回值
下面例子為用Invoke方法編寫一個每隔0.5秒生成一個物體的動態(tài)效果
Using UnityEngine;
public class TestInvoke : MonoBehaviour
{
? ?public Gameobject prefab;
? ?int counter=0;
? ?void Start()
? ?{
? ? ?Invoke("CreatePrefab",0.5f);
? ?}
? ?void CreatPrefab()
? ?{
? ? ? ? ?Vector3 POs=new Vector3(Mathf.Cos(counter*(2*Mathf.PI)/10),0,Mathf.Sin(counter*(2*Mathf.PI)/10));
? ? ? ? ? pos*=5;
? ? ? ? ? Instantiate(prefab,pos,Quaternion.identity);
? ? ? ? ? counter++;
? ? ? ? ? if(counter<10)
? ? ? ? ? {
? ? ? ? ? Invoke("CreatePrefab",0.5f);
? ? ? ? ? }
? ? }
}
延遲銷毀也可以用Invoke實(shí)現(xiàn),但由于延遲銷毀需求更加廠家,因此Unity為Destroy方法增添了延時的功能,Destroy的第二個參數(shù)用于制定銷毀延遲的事件,如:
Destroy(cube,0.5f);文章來源:http://www.zghlxwxcb.cn/news/detail-485657.html
?
到了這里,關(guān)于Unity用腳本創(chuàng)建物體的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!