2016-03-15 19 views
5

classes deriving relationsGenerikleri desteklemek için Unity singleton taban sınıfı nasıl yapılır?

Projemde, resimde gösterildiği gibi bir sınıf yapısına sahibim.

Yeşil sınıflar, çok iyi çalışan eski kodlardır. Kırmızı kutulardaki sınıflar yeni eklenen kodlardır. Derleyici hataları yoktur, ancak Unity içinde oynat ve yeni kodda çalıştırıldığında, üç sınıf doğru şekilde başlatılamaz.

Ve birlik konsolu, "DataMgrBase`2" adlı sınıfın genel olduğunu bildiren uyarı verir. Genel MonoBehaviours desteklenmez! UnityEngine.GameObject: AddComponent() "bu satırda:" instance = obj.AddComponent(); "

Bu sorunu nasıl çözebilirim?

Referans için bazı kodlar aşağıdadır, teşekkürler! Singleton taban sınıfın

Uygulama: DataMgrBase ait

using UnityEngine; 
using System.Collections; 

public class UnitySingletonPersistent<T> : MonoBehaviour where T : Component 
{ 
    private static T instance; 

    public static T Instance { 
     get { 
      if (instance == null) { 
       instance = FindObjectOfType<T>(); 
       if (instance == null) { 
        GameObject obj = new GameObject(); 
        obj.name = typeof(T).Name; 
        obj.hideFlags = HideFlags.DontSave; 
        instance = obj.AddComponent<T>(); 
       } 
      } 
      return instance; 
     } 
    } 

    public virtual void Awake() 
    { 
     DontDestroyOnLoad (this.gameObject); 
     if (instance == null) { 
      instance = this as T; 
     } else { 
      Destroy (gameObject); 
     } 
    } 
} 

Uygulama:

public class DataMgrBase<TKey, TValue>: UnitySingletonPersistent<DataMgrBase<TKey, TValue>> { 

    protected Dictionary<TKey, TValue> dataDict; 

    public override void Awake() 
    { 
     base.Awake(); 

     dataDict = new Dictionary<TKey, TValue>(); 
    } 

    public TValue GetDataForKey(TKey key) 
    { 
     TValue data; 
     if (dataDict.TryGetValue(key, out data)) 
     { 
      return data; 
     } 
     else 
     { 
      data = LoadDataForKey(key); 
      if (data != null) 
      { 
       dataDict.Add(key, data); 
      } 

      return data; 
     } 
    } 

    virtual protected TValue LoadDataForKey(TKey key) 
    { 
     if (dataDict.ContainsKey(key)) 
     { 
      return GetDataForKey(key); 
     } 
     else 
     { 
      return default(TValue); 
     } 
    }  
} 

cevap

1

ben şöyle kendim çözdük:

temel sınıf değiştirme, yeni bir genel tip olsun (ondan elde edecekleri sınıfın ve tekil temel sınıf için bu tür geçmesi) için

ondan türetmek isteyen tüm diğer üç sınıfa için
public class DataMgrBase<TKey, TValue, TClass>: UnitySingletonPersistent<TClass> where TClass: Component 

aşağıdaki formu olarak bunları değiştirin:

public class MobSettingDataMgr : DataMgrBase<int, MobSettingData, MobSettingDataMgr> 
+0

Bu harika bir çözümdür, ancak küçük bir his var, Unity3D bir şey yapmanın pek yolu değil. Her neyse problemi çözmek için congratz! –

+0

Teşekkürler :) @JerrySwitalski – ArtS

0

Sen istediğim bir şey gibi: En somut sınıfta Sonra

public abstract class UnitySingletonPersistent<T> : MonoBehaviour where T:UnitySingletonPersistent<T> 
{ 
... 
} 

:

public class DataMgrBase<TKey, TValue> : UnitySingletonPersistent<DataMgrBase<TKey, TValue> > 
{ 
... 
} 
+0

Nasıl bu OP farklılık nedir? – Everts

+0

Teşekkürler! Denedim, hala aynı uyarı. Başlatma hala "instance = obj.AddComponent ();" konumunda başarısız oldu. – ArtS

0

Bu bir şekilde sorununuzu çözmüyor, ancak sorunu açıklayacaktır.

MonoBehaviour

en az iki nedenden dolayı jenerik olamaz:

1. Eğer Unity3D editörden Inspector'da jenerik bileşen eklemek istediğiniz düşünün. Artık motorun, bu bileşendeki tüm türleri tam olarak bilmesi gerekiyor, sadece bu noktada derlenecek değil, aynı zamanda eksik alanlarla kamusal alanlara sahip olmanıza da neden olacak. UnitySingletonPersistent'unuzu doğrudan Inspector'a atamaya çalışın ve bunun uygun olmadığını görürsünüz. T işe yarayabilir gibi genel görünüşü olan AddComponent<T> kullanma

2. değil, aynı zamanda bu motorda bu kadar örneklenmiş GameObjects dışına prefabrik denilen bir hale getirebilir ve bu GameObject içeriyorsa jenerik bileşeni Unity3D motoru çeşit desteklemek gerekir Pişirme türlerinin ve bu uygulamada, her biri farklı tipte senaryolar üretmeye ve projenin içinde büyük karışıklıklara yol açacaktır. Umarım beni takip edersin.

Ancak neden yeşil renkle işaretlediğiniz bileşenler için çalışıyor? Unity3D motorunun, bu bileşeni GameObject'e eklerken tüm türleri bilmesini sağlayın.

Bütün bu Unity Technologies teknolojilerini desteklemek için Unity3D motorunda çekirdek değişiklikleri yapmak gerekir, şimdi nasıl çalışıyor. Unity3D, şimdi olduğu gibi motoru tamamen farklılaştıracaktı.

Sorununuzu çözmek için yalnızca tek bir yol vardır: çalışma zamanı genel bileşenlerinde ekleme yok ve DataMgrBase sınıfından kurtulmak. Bu yüzden her bir bileşene DataMgrBase mantığını uygulamanız gerekecek.

+0

Paylaştığınız için teşekkürler, ancak zaten çözdüm. Lütfen cevabımı kontrol et. Genel türler derlendikten sonra değişmez, bu yüzden aslında "çalışma zamanı" jenerik değildir. – ArtS

İlgili konular