2016-03-22 18 views
1

DontDestroyOnLoad ile garip bir sorunum var. Bir başlangıç ​​sahnesi olarak bir haritanım var. Oradan, kullanıcı belirli harita nesnelerini tıklayabilir ve Application.LoadLevel() ile yeni bir seviye yükleyebilir. Seviye bittiğinde harita tekrar yüklenir. Ancak, DontDestroyOnLoad ekli nesneler ikinci yükte çoğaltılır.DontDestroyOnLoad() nedeniyle çoğaltmalar()

Güncel komut dosyası: Çevrimiçi arama ve çiftleri kaldırmak için bu olası bir çözüm buldu

void Awake() 
{ 
    DontDestroyOnLoad(transform.gameObject); 
} 

:

public class NoDestroy : MonoBehaviour { 

    public static NoDestroy instance; 

    void Awake() 
    { 
     if (instance == null) 
     { 
      instance = this; 
     } 
     else 
     { 
      Destroy(this.gameObject); 
      return; 
     } 

     DontDestroyOnLoad(this.gameObject); 

    } 
    } 

yukarıdaki script sadece çalışmaz. Sorunu nasıl düzeltebilirim? daha kötüsü, aynı davranışı kullanmayı deneyin diğer nesneleri sileceğiz - Yukarıdaki komut dosyası static örneğini kullandığından

+0

asla, bir zamanlar Unity'de statik kullanmayın. *** OO sistemi değil, ECS. *** Unity'de asla "this" anahtar sözcüğünü kullanmayın, eğer bunu yaparsanız tamamen yanlış bir şey yapıyorsunuz demektir. *** bir OO sistemi değildir, bu bir ECS değildir. *** http://stackoverflow.com/a/35723305/294884 – Fattie

+0

(heh) Not: "kopyaları" kaldırmak için * teknik olarak kesinlikle mümkün değil * en azından, çerçevelerin içinde değil, bu yüzden de bunun sonu) - sık sık, "tekli gibi bir şey" in olduğu OO'daki gibi bir durum oluşturmak için insanların "kopyaları çıkarmaya" çalıştıkları gülünç kod örnekleri görüyorsunuz. ECS tamamen farklı. – Fattie

cevap

1

, sadece `tek GameObject o ekledi eğer çalışacağız.

En büyük sorun, bir sahneyi her yüklediğinizde, o sahnedeki tüm nesnelerin yüklenmesidir. Eğer kaldırılmamışlarsa (DontDestroyOnLoad sayesinde) çoğaltılacaklardır, çünkü sahne "zaten var" olduklarını bilmediğinden

Yukarıdaki komut, persistant nesnelere şemsiye ve sadece şemsiye nesnesi (genellikle Toolbox olarak adlandırılır) yok edilmez. Bununla birlikte, bu çoğunlukla yönetici betikleri için uygundur.

Yok edilmemesi gereken nesneleri biliyorsanız, bunları bir "Yükleme" manzarasıyla yüklemeyi düşünün. Bu, kalıcı nesneleri harita sahnesinin dışına taşıdığından, harita sahnesini yeniden yüklerken çoğaltılamazlar. Perdeyi düşürmeyi kolaylaştırdığından bu desene bonus. Eğer basit bir davranış komut dosyası olarak bu uygulamak istiyorsanız

yanı, bu zaten var aynı ID değere sahip bir nesnenin tekrarını önleyecek böylece

public class NoDestory : MonoBehaviour 
{ 
    private static Dictionary<string, GameObject> _instances = new Dictionary<string, GameObject>(); 
    public string ID; // HACK: This ID can be pretty much anything, as long as you can set it from the inspector 

    void Awake() 
    { 
     if(_instances.ContainsKey(ID)) 
     { 
      var existing = _instances[ID]; 

      // A null result indicates the other object was destoryed for some reason 
      if(existing != null) 
      { 
       if(ReferenceEquals(gameObject, existing) 
        return; 

       Destroy(gameObject); 

       // Return to skip the following registration code 
       return; 
      } 
     } 

     // The following code registers this GameObject regardless of whether it's new or replacing 
     _instances[ID] = gameObject; 

     DontDestroyOnLoad(gameObject); 
    } 
} 

gibi bir kimlik eklemeyi düşünün söz konusu nesne başka bir yerde Destory -ed ise rekreasyona izin vermek gibi. Bu, senaryo her uygulandığında yeni bir ID'u teslim etmek için özel bir Editör komut dosyası ekleyerek daha da geliştirilebilir.

+0

Cevabınız için teşekkürler, ancak komut dosyanız yeni seviyeye geçtiğimde sadece nesneyi yok ediyor. Neden kodunuzun herhangi bir yerinde 'DontDestroyOnLoad (transform.gameObject); ' –

+0

Düzenlendi - bu sistemin kendini bir çarpışma olarak görmesini engellemeli, 'Awake' iki kez çağrıldığında oluşabilecek – David

+0

Not: Sonunda TODO'ya dikkat etmeliydim. Bu mevcut "DontDestroyOnLoad" betiğinizin yanında. Eğer durum böyle değilse, 'TODO ~ satırını, örneğinizdeki çağrıyla değiştirin – David

İlgili konular