在Unity 5中,什麼是「乾淨」的方式來管理動態創建的遊戲對象?統一5:清理方式來管理動態創建的GameObjects
我寫了一個組件(MonoBehavior
),它創建/銷燬幾個GameObjects
。這些對象作爲自定義定製系統的一部分加載,用於選擇角色的部分 - 頭髮/衣服等。這些對象對播放器是可見的,在編輯器中可見,但不應在編輯器中編輯。正在加載的對象與骨架網格。
腳本的行爲以這種方式:
-
從資源
- 負載GameObjects(確切的對象是在腳本中確定,他們不是預製件)
- 它們附着在現場的某些部分(不一定是其自己的節點)
- 刪除時被刪除。
刪除:
protected void unloadLastResource(){
if (lastResourceInstance){
if (Application.isEditor){
GameObject.DestroyImmediate(lastResourceInstance);
}
else
GameObject.Destroy(lastResourceInstance);
Resources.UnloadUnusedAssets();
lastResourceInstance = null;
}
}
創作:
GameObject target = getEffectiveTargetNode();
Object resource = Resources.Load(newResourceName);
instance = Instantiate(resource) as GameObject;
instance.hideFlags = HideFlags.HideAndDontSave;
instance.transform.parent = target.transform;
instance.transform.localPosition = Vector3.zero;
instance.transform.localRotation = Quaternion.identity;
instance.transform.localScale = Vector3.one;
銷燬處理:
void OnDestroy(){
unloadLastResource();
}
這似乎在編輯器工作正常,但是當我從遊戲模式切換回以edito模式,我收到很多警告:
Destroying object multiple times. Don't use DestroyImmediate on the same object in OnDisable or OnDestroy.
UnityEngine.Object:DestroyImmediate(Object)
我也得到許多新對象樹(本應在那些被刪除 - 樹木,將其與原來的「資源」一起加載,並附着對象起源)在現場hieararchy的頂層。
那麼,我該如何幹淨地處理動態創建的gameobjects?
我需要知道我需要設置哪些標誌,以及我應該採取哪些步驟來確保對象不會「泄漏」到場景中,並在刪除創建它的組件時正確銷燬。
建議?通過「資源加載」使用
全部基類
public class BaseResourceLoader : MonoBehaviour {
public GameObject targetNode = null;
protected GameObject lastTargetNode{
get{return lastTargetNodeInternal;}
}
private GameObject lastTargetNodeInternal = null;
protected bool targetNodeChanged(){
return targetNode != lastTargetNode;
}
protected string lastResourceName{
get{return lastResourceNameInternal;}
}
private string lastResourceNameInternal = "";
//private Object lastResource;
private GameObject lastResourceInstance;
protected GameObject getEffectiveTargetNode(){
if (targetNode == null)
return this.gameObject;
return targetNode;
}
public void reloadResource(){
loadNewResource(lastResourceNameInternal, true);
}
protected void unloadLastResource(){
if (lastResourceInstance){
if (Application.isEditor){
GameObject.DestroyImmediate(lastResourceInstance);
}
else
GameObject.Destroy(lastResourceInstance);
Resources.UnloadUnusedAssets();
lastResourceInstance = null;
}
lastResourceNameInternal = "";
}
protected void loadNewResource(string newResourceName, bool forceReload){
if ((newResourceName == lastResourceNameInternal) && !forceReload)
return;
GameObject instance = null;
if (newResourceName != ""){
GameObject target = getEffectiveTargetNode();
Object resource = Resources.Load(newResourceName);
instance = Instantiate(resource) as GameObject;
instance.hideFlags = HideFlags.HideAndDontSave;
instance.transform.parent = target.transform;
instance.transform.localPosition = Vector3.zero;
instance.transform.localRotation = Quaternion.identity;
instance.transform.localScale = Vector3.one;
}
unloadLastResource();
lastResourceInstance = instance;
lastResourceNameInternal = newResourceName;
lastTargetNodeInternal = targetNode;
}
void OnDestroy(){
unloadLastResource();
}
}
感謝您的摘錄。我正在分析它並尋找與我的代碼片段相比的差異(我也將對象實例存儲在變量中,所以它們應該做同樣的事情) – SigTerm 2015-03-31 04:58:19
我調查了你的腳本,發現它的工作原理與礦。不過,如果你有興趣,我已經解決了這個問題。看到答案。 – SigTerm 2015-03-31 14:31:20