简体   繁体   English

具有静态实例创建的Unity3D C#抽象类无法正常工作

[英]Unity3D C# abstract class with static instance creation not working

Hello I am working on a objectpooling class has T "ObjectPooling". 您好我在一个对象池类上工作,该类具有T“ ObjectPooling”。 And made a child class. 并做了一个儿童班。 So I want to make automatic singleton for this class. 因此,我想为此课程制作自动单例。 So if I use "instance" it should check if m_instance is null. 因此,如果我使用“ instance”,则应检查m_instance是否为null。 If yes "spawn" the script and assign m_instance. 如果是,则“生成”脚本并分配m_instance。

public abstract class ObjectPooling<T> : MonoBehaviour
{

    public static float start = 30;
    public static bool extendable = true;

    public List<T> objects = new List<T>();

    public abstract T getNext();
    public abstract void Add(T obj);

    static T m_instance;
    public static T instance
    {
        get
        {
            return m_instance ?? (m_instance = CreateInstance());
        }
    }

    protected static T CreateInstance()
    {

        GameObject g = new GameObject("ObjectPooling");
        var c = g.AddComponent<T>();
        return c;
    }
}

The problem is at the last lines in the CreateInstance(). 问题出在CreateInstance()的最后几行。 It says 它说

An implicitly typed local variable declaration cannot be initialized with `UnityEngine.GameObject.AddComponent(System.Type)' 隐式类型化的局部变量声明不能使用“ UnityEngine.GameObject.AddComponent(System.Type)”初始化

I am not sure what can I do here now. 我不确定现在可以在这里做什么。 I tried with ObjectPooling before but thats gives no error but also is not working. 我之前尝试过ObjectPooling,但是多数民众赞成在没有任何错误,但也不起作用。

So my goal is that the child has also singleton. 所以我的目标是孩子也单身。 I did it currently manually but want I want to later should be like this (ofc the base class should do it instead of child class but still check it). 我目前是手动完成的,但希望以后再执行此操作(ofc基类应代替子类,但仍要检查它)。

public class BulletPooling : ObjectPooling<BulletBase>  
{
    public override void Add(BulletBase obj)
    {
        if(extendable)
            objects.Add(obj);
    }

    public override BulletBase getNext()
    {

        for(int i = 0; i < objects.Count; i++)
        {
            var bs = objects[i];
            if (!bs.gameObject.activeInHierarchy)
                return bs;
        }


        return null;
    }

    // this part
    static BulletPooling m_instance;
    public static BulletPooling instance
    {
        get
        {
            return m_instance ?? (m_instance = CreateInstance());
        }
    }

    protected static BulletPooling CreateInstance()
    {

        GameObject g = new GameObject("ObjectPooling");
        var c = g.AddComponent<BulletPooling>();
        return c;
    }
}

You can see here I am working with new Childclass which has T = BulletBase 您可以在这里看到我正在使用具有T = BulletBase的新Childclass

This is because GameObject.AddComponent requires an object of a specific type, rather than "any type". 这是因为GameObject.AddComponent需要特定类型的对象,而不是“任何类型”的对象。 In your ObjectPooling class, you only specify that it can be an object of any type, and the compiler cannot infer which types you are using beforehand. ObjectPooling类中,仅指定它可以是任何类型的对象,并且编译器无法推断出您正在使用的类型。

AddComponent is kind of a nasty function, since you can also pass it a string, which should be the name of a script class. AddComponent有点讨厌,因为您还可以向它传递一个字符串,该字符串应该是脚本类的名称。

You could specify the type that T must adhere to as UnityEngine.Component to get around this. 您可以将T必须遵守的类型指定为UnityEngine.Component来解决此问题。 that would look like this : 看起来像这样:

public abstract class ObjectPooling<T>: MonoBehaviour where T : UnityEngine.Component 
{

    public static float start = 30;
    public static bool extendable = true;

    public List<T> objects = new List<T>();

    public abstract T getNext();
    public abstract void Add(T obj);

    static T m_instance;
    public static T instance
    {
        get
        {
            return m_instance ?? (m_instance = CreateInstance());
        }
    }

    protected static T CreateInstance()
    {

        GameObject g = new GameObject("ObjectPooling");
        //this is where your compiler could not tell if T was the correct type by the way...
        var c = g.AddComponent<T>(); 
        return c;
    }
}

but that might break the functionality of adding scripts as game components using a string with their name. 但这可能会破坏使用带有名称字符串的脚本将脚本添加为游戏组件的功能。 (though i think in your case, it won't be a problem) (尽管我认为在您的情况下,这不会有问题)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM