转载 雨松mono Unity获取游戏对象详解(来自我的长微博)
?Unity獲取游戲?qū)ο笤斀?#xff08;來(lái)自我的長(zhǎng)微博)
轉(zhuǎn)載 自 雨松mono
- 本文固定鏈接: http://www.xuanyusong.com/archives/2768
- 轉(zhuǎn)載請(qǐng)注明: 雨松MOMO 2014年06月16日 于 雨松MOMO程序研究院 發(fā)表
?
?
我覺(jué)得Unity里面的Transform 和 GameObject就像兩個(gè)雙胞胎兄弟一樣,這倆哥們很要好,我能直接找到你,你也能直接找到我。我看很多人喜歡在類(lèi)里面去保存GameObject對(duì)象。解決GameObject.Find()無(wú)法獲取天生activie = false的問(wèn)題。
? ? ?private?GameObject?root?;
我覺(jué)得你最好不要保存GameObject ,而是去保存Transform ,因?yàn)門(mén)ransform下的方法要比GameObject多,使用頻率也要高很多。
? ??private?Transform?root?;
其實(shí)我心里一直有個(gè)疑問(wèn),為什么unity不把GameObject和Transform合并成一個(gè)對(duì)象。
1.GameObject.Find()
通過(guò)場(chǎng)景里面的名子或者一個(gè)路徑直接獲取游戲?qū)ο蟆?/strong>
? ??GameObject?root?=?GameObject.Find(“GameObject”);
我覺(jué)得如果游戲?qū)ο鬀](méi)再最上層,那么最好使用路徑的方法,因?yàn)橛锌赡苣愕挠螒驅(qū)ο髸?huì)有重名的情況,路徑用“/”符號(hào)隔開(kāi)即可。
? ??GameObject?root?=?GameObject.Find(“GameObject/Cube”);
GameObject.Find()使用起來(lái)很方便,但是它有個(gè)缺陷如下圖所示,就是如果你的這個(gè)GameObject天生acive = false的話。那么你用GameObject.Find()是永遠(yuǎn)也無(wú)法獲取它的對(duì)象的。如果對(duì)象都獲取不到,那么對(duì)象身上腳本啊 組件啊啥的都是獲取不到的,變成了沒(méi)有意義的對(duì)象。
?
就這個(gè)問(wèn)題我查過(guò)很多資料,最終也無(wú)果。。但是我用另外一個(gè)巧妙的辦法可以解決它。(后面詳解)或者你也可以提前把所有的游戲?qū)ο蟊4嬖趦?nèi)存中。
GameObject.Find()方法在游戲中的使用頻率很高。但是它也很消耗性能,你可以想想它的原理肯定也是用類(lèi)似遞歸的形式來(lái)做的,那么我們就要盡量更少的調(diào)用GameObject.Find()方法,可以把獲取的游戲?qū)ο?#xff0c;保存在內(nèi)存里,這是再好不過(guò)的選擇了。 尤其是在Update方法中不要去 Find()游戲?qū)ο?#xff01;!
2 .Transform.Find()
還記得上面我說(shuō)過(guò)用GameObject無(wú)法獲取天生acive = false的游戲?qū)ο?#xff0c;如果你用Transform.Find()的話就可以很好的獲取,另外Unity還提供了一個(gè)Transform.FindChind()的方法,這個(gè)方法未來(lái)會(huì)被unity廢棄,大家最好就別用了,用Transform.Find()可以取代。
如下代碼,我們先獲取頂級(jí)對(duì)象root 。接著用Find()去找它的子節(jié)點(diǎn)”xxxx”的對(duì)象,無(wú)論”xxxx”對(duì)象是否active = true 都是可以直接找到對(duì)象的。
? ? ? ?
C#| 1 2 3 4 | ?????? GameObject root = GameObject.Find("GameObject");?????? ???????? GameObject xxxx =??root.transform.Find("xxxx").gameObject; ??????????xxxx.SetActive(true); |
?
Find()方法只能直接去找子節(jié)點(diǎn),如果你想找 孫節(jié)點(diǎn),那么可以用”/“符號(hào)把層級(jí)關(guān)系隔開(kāi),找起來(lái)很方便。同樣無(wú)論”xxxx”對(duì)象是否active = true 都是可以直接找到對(duì)象的。
C#| 1 | ????GameObject cube =??root.transform.Find("xxxx/Cube").gameObject; |
值得注意的是,unity規(guī)定了比如父節(jié)點(diǎn)active = true 并且子節(jié)點(diǎn)的 active = true 都滿足的情況下 才能全部顯示。使用Transform.Find()可以很方便的獲取游戲?qū)ο?#xff0c;因?yàn)橛辛擞螒驅(qū)ο?#xff0c;那么它身上的腳本啊組件啊什么的都可以很方便的獲取到。
但是Transform.Find()必須要保證你的頂級(jí)父對(duì)象的activity = true。舉個(gè)例子,你做了一個(gè)場(chǎng)景有一些地圖你在場(chǎng)景里面預(yù)先activie = false了, 你希望在游戲中的某個(gè)時(shí)間點(diǎn)把它們都打開(kāi) setActive(true)
你可以把“map”節(jié)點(diǎn)放在一個(gè)active = true的GameObject上,無(wú)論是關(guān)閉 或者 顯示 代碼中寫(xiě)起來(lái)都很方便。 假如你的map節(jié)點(diǎn)就是頂級(jí)節(jié)點(diǎn),那么它一旦天生acive = false ,那么你將無(wú)法得到它的對(duì)象,更無(wú)法設(shè)置它的屬性了。
?GameObject?root?=?GameObject.Find(“GameObject”);????????
GameObject?map?=??root.transform.Find(“map”).gameObject;???????
?map.SetActive(true);
3. unity 還提供了幾個(gè)獲取游戲?qū)ο蟮姆椒?#xff0c;但是我個(gè)人覺(jué)得使用頻率不高,這里也簡(jiǎn)單說(shuō)兩句。
GameObject.FindGameObjectsWithTag(“tag”)
GameObject.FindWithTag(“tag”)
根據(jù)一個(gè)標(biāo)記來(lái)獲取游戲?qū)ο?#xff0c;返回一個(gè) 或者 一個(gè)數(shù)組,我個(gè)人覺(jué)得這個(gè)兩個(gè)方法沒(méi)啥用,因?yàn)榧热恍枰玫綐?biāo)記那么相比這個(gè)游戲?qū)ο蟊厝皇欠浅L厥獾囊粋€(gè),所以我會(huì)把它存在內(nèi)存中。
Object.FindObjectOfType
Object.FindObjectsOfType
Resources.FindObjectsOfTypeAll?
根據(jù)一個(gè)類(lèi)型返回Object,比如 GameObject 、Texture、Animation 、甚至還可以是你自己寫(xiě)的一個(gè)腳本 的范型。它找起來(lái)很方便,可以返回一個(gè) 或者一個(gè)數(shù)組。 我覺(jué)得這幾個(gè)方法其實(shí)游戲中也沒(méi)啥用,不過(guò)在編輯器中使用的確實(shí)很頻繁,比如你要做批量檢查場(chǎng)景的工具,查找場(chǎng)景中有沒(méi)有使用某個(gè)特殊類(lèi)型的對(duì)象。 或者查看內(nèi)存的占用量,看看當(dāng)前內(nèi)存中那些Texture沒(méi)有被釋放掉。 等等。
還有一個(gè)方法,如果你知道自對(duì)象的索引,還可以用下面的方法來(lái)獲取,參數(shù)是index的索引。
transform.GetChild(0)
找到了一個(gè)即使隱藏root節(jié)點(diǎn)gameObject也能進(jìn)行查找的方法。http://answers.unity3d.com/questions/52560/gameobjectfind-work-on-inactive-objects.html
C#| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | GameObject[] pAllObjects = (GameObject[])Resources.FindObjectsOfTypeAll(typeof(GameObject)); ???????? foreach (GameObject pObject in pAllObjects) ???????? { if (pObject.transform.parent != null) ???????????? { ???????????????????? continue; ???????????? } if (pObject.hideFlags == HideFlags.NotEditable || pObject.hideFlags == HideFlags.HideAndDontSave) ???????????? { ???????????????? continue; ???????????? } if (Application.isEditor) ???????????? { ???????????????? string sAssetPath = AssetDatabase.GetAssetPath(pObject.transform.root.gameObject); ???????????????? if (!string.IsNullOrEmpty(sAssetPath)) ???????????????? { ???????????????????? continue; ???????????????? } ???????????? } Debug.Log(pObject.name); ???????? } |
?
轉(zhuǎn)載于:https://www.cnblogs.com/dudu580231/p/6627768.html
總結(jié)
以上是生活随笔為你收集整理的转载 雨松mono Unity获取游戏对象详解(来自我的长微博)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: html5做的太阳系
- 下一篇: 有趣的时间