所以我有一个名为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以便我可以重用代码,但是任何其他解决方案都值得赞赏。
答案 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
在函数上。