2017-06-15 55 views
3

實施例

在Unity5,假設名稱爲「SomeObject」一個遊戲物體在Assets/Resources/SomeObject.prefab存儲爲一個預製的,我知道我可以如下創建該預製的一個實例:非實例化的加載的Prefab如何與實例化的比較?

GameObject prefab = Resources.Load<GameObject>("SomeObject"); 
GameObject instance = GameObject.Instantiate(prefab); 

一旦執行,遊戲對象instance將是原始「SomeObject」預製件的副本,並將被放置在當前活動場景中,名稱爲「SomeObject(克隆)」。


據我瞭解,在GameObject prefab代表實際的預製資產,並把它(設置名稱,添加成分等)寫入到原來的預製資產,而這些變化堅持,即使之後所做的任何更改退出編輯器播放模式。

問題

  1. 由於所有GameObjects通常存儲在一個場景,並在上面的例子中scene財產上GameObject prefab似乎被卸載/無效/未命名的,正是我應該考慮這個特殊的遊戲對象,以是?我似乎能夠用它做所有事情,我可以用普通的GameObjects完成任何事情,但在層次結構/場景視圖中顯示不出來。

    它有效地處於某種緩衝狀態,還是一種特殊的PseudoScene?它似乎通過LoadSceneMode.Single場景變化持續存在,但並不像DontDestroyOnLoad場景那樣當對象被傳遞到GameObject.DontDestroyOnLoad(...)時被移動到該場景。

  2. 是否有在上述的例子prefabinstance之間的任何其它值得注意的差異,比壽命的變化,無效場景其他並且是從一個不同的對象另一個(具有不同的GetInstanceID()等)?

  3. 由於呼籲prefabGameObject.Instantiate(...)產生一個遊戲對象是是一個有效的場景,是有什麼辦法可以手動創建一個類似的「無現場」狀態GameObjects?我知道Unity打算讓所有GameObjects出現在場景中,所以這純粹是一個學術問題。

我試圖翻翻functionsinvolveddocumentation,但沒有進入具體是什麼正在發生的技術細節,當你對一個預製資源調用Resources.Load

+0

正如你大概可以告訴我有效地一次推出3個問題,我現在處於一個缺乏直覺的位置,以便真正知道我不知道的是什麼,如果這是有道理的。再試一次:因爲Resources.Load產生的GameObject處於無法手動創建的狀態,所以我很好奇這些差異的確切性質,並希望有更多關於幕後操作的知識的人可以提供洞察力進入這裏玩的系統,這些系統在正常文檔中可能不會立即顯現出來。我很抱歉無法更清楚地說出這一點。 – Johannes

回答

3

1.我到底該考慮這個特殊的GameObject嗎?

它在一個單獨的文件中,並沒有在場景中引用。一旦調用Resources.Load<GameObject>("SomeObject");,它將被加載到調用GameObject.Instantiate時等待使用的內存中。

如果它被聲明爲public GameObject prefab;並從編輯器中分配而不是GameObject prefab Resources.Load<GameObject>("SomeObject");,它將在場景加載時自動加載到內存中。

2.預製件和對象之間是否還有其他值得注意的區別?

是的。

預製件不能用DestroyDestroyObject功能銷燬。它必須通過傳遞true其第二arguement與DestroyImmediate功能被破壞:DestroyImmediate(prefab, true);

3.Is有什麼辦法可以手動創建一個類似的「無現場」狀態GameObjects?

不,沒有辦法手動創建處於類似「無場景」狀態的GameObjects。

雖然你可以僞造它。

最接近的事情就是通過修改GameObjects的hideFlags變量,然後停用遊戲物體,使遊戲對象的編輯層次督察標籤不可見。

GameObject obj = new GameObject("SomeObject"); 
obj.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector; 

之後,停用遊戲對象:

obj.SetActive(false); 

現在,遊戲對象是在編輯器中不可見的,它也是在場景和遊戲觀無形。


預製件和典型的遊戲對象之間確實沒有太大的區別。 Prefab只是一個容納GameObject的容器,因此它可以在場景之間重複使用和共享。修改一個預製件會更新它的任何實例。

想象一下,當您在場景中有數百個相同類型的GameObjects並需要修改所有這些類型時。使用預製,您只需修改其中一個或只是預製,然後單擊應用即可更新其他實例。這是你應該考慮預製的唯一的事情。

+0

我也很好奇預製件gameObject和原始預製件之間的聯繫如何建立,以及它如何立即序列化。戳在https://github.com/MattRix/UnityDecompiled看起來'Resources.Load'最終導致extern函數,所以它在Unity的C++端的某個地方。一位朋友指出,預製可能是一個專門的C++對象,與一個GameObject .net接口一起生活。有什麼想法嗎? – Johannes

+1

我不得不通過'.Net反射器'來驗證。它調用一個本地C++函數,該函數接受prefab的路徑和prefab的預製類型:'public static extern Object Load(string path,Type systemTypeInstance);'。我認爲C++端將用提供的路徑加載文件,然後將該預製文件中的數據反序列化到內存中,然後將其作爲「Object」返回。預製文件格式是專有的,除非你爲Unity工作並且擁有C++源代碼,否則很難猜測它的內部結構。 – Programmer

+0

只是對於第一次在這裏學習'hideFlags'的人來說,它可能也值得追加'HideFlags.HideFlags.DontSave'或者只是使用'HideFlags.HideAndDontSave'來代替,因爲有物體你看不到堆積可能是一個潛在的問題。 – Johannes