使用类作为变量

时间:2019-09-23 18:33:44

标签: c# unity3d

所以我有一个名为InstalledObjects的类,所有对象(如墙壁,门等)都将从该类继承。现在,我想在一个方法中实例化一个GameObject,并在该方法中询问一个InstalledObject,因为它们都从InstalledObject继承,所以它可以是Wall或Door。

我的问题是我可以在脚本中存储一个脚本。

首先,此方法称为

public void CreateBasicWall()
{
     buildHandler.installedObject = new Wall();
}

它存储在这里:

public InstalledObject installedObject;

最后被叫到这里

BuildTile(t, buildModeTile);

然后这样做:

void Build(Tile tile, InstalledObject installedObject)
{
    if(installedObject == null)
    {
        Debug.LogError("No se va a construir nada");
        return;
    }
    GameObject go = new GameObject();
    go.AddComponent<installedObject>();

}

忽略磁贴。因为是var而不是类型,所以它不会让我添加installedObject。

我记得Wall类是从InstalledObject继承的,我希望将其作为var以便我可以重用代码,但是任何其他解决方案都值得赞赏。

2 个答案:

答案 0 :(得分:3)

正如已经说过的那样,仅使用generic就不可能直接为reflection方法(AddComponent<T>)使用动态变量,但是我不建议这样做。 C#的新手。


假设InstalledObject的类型为MonoBehaviour,因为您正尝试将其用于AddComponent,因此您的代码仍然无效!

对于类型new Wall()的类,不能使用MonoBehaviour。只能使用AddComponent<ClassName>()或使用类型AddComponent(typeof(ClassName))的重载来创建它。

因此,您可以做的就是不存储“实例”(正如您所说无论如何都不能使用new),而只能存储相应的类型

public Type typeToInstall;

然后像

public void CreateBasicWall()
{
     buildHandler.typeToInstall = typeof(Wall);
}

void Build(Tile tile, Type typeToInstall)
{
    if(typeToInstall == null)
    {
        Debug.LogError("No se va a construir nada");
        return;
    }

    GameObject go = new GameObject().AddComponent(typeToInstall);

    // or even a bit shorter
    //new GameObject("New GameObject", typeToInstall);
}

您还可以使此方法本身为generic,并将constraint passed the type设置为Component(可以附加到GameObject的任何对象的母类)来确定。传入任何其他类型将已经引发了编译器错误。然后,您也可以再次使用AddComponent<T>

void Build<T>(Tile tile, T typeToInstall) where T : Component // or maybe even InstalledObject ;)
{
    if(typeToInstall == null)
    {
        Debug.LogError("No se va a construir nada");
        return;
    }

    new GameObject().AddComponent<T>();

    // or still use
    //new GameObject("New GameObject", typeof(T));
}

答案 1 :(得分:0)

可以通过多种方法来实现,但是,如果要保留当前的体系结构,则需要虚拟或抽象函数。

每个类都知道自己的类型,但是您对其调用的函数取决于保存该类的变量的类型,除非它是抽象或虚函数。

我建议阅读this

这里是一种方法:

void Build(Tile tile, InstalledObject installedObject)
{
    Assert.IsNotNull(installedObject,
        "No se va a construir nada");

    GameObject go = new GameObject();
    installedObject.AddSelfToGameObject(go);
}

和您的Build.cs

public abstract class Build
{
    [...]
    public abstract void AddSelfToGameObject(GameObject go);
}

public class Building:Build
{
    [...]
    public override void AddSelfToGameObject(GameObject go)
    {
        go.AddComponent<BuildingScript>();
    }
}

仅当您从不单独创建abstract的子类时,才需要Build类上的Build。您可以删除类上的Build并将其替换为abstract在函数上。