我有一个问题,我知道如何在C++中解决,但我不知道在C#中是如何工作的。以下是用C#编写的示例代码:
public class TowerTile<ScriptType, SpriteName> : Tile where ScriptType : MonoBehaviour {
private void Awake() {
gameObject = new GameObject();
gameObject.AddComponent<ScriptType>();
colliderType = Tile.ColliderType.None;
sprite = GameManager.shared.sprites[SpriteName];
}
}
示例中的SpriteName
应该是string类型,这样我就可以在Dictionary<string, Sprite> sprites
上的operator[]
中使用它。
下面是我用C++编写它的方式:
template <typename ScriptType, typename SpriteRef = std::string>
class TowerTile : public Tile {
private void Awake() {
gameObject = new GameObject();
gameObject.AddComponent<ScriptType>();
colliderType = Tile.ColliderType.None;
sprite = GameManager.shared.sprites[SpriteRef];
}
}
如何在C#中实现这一点?我不能将字符串作为构造函数参数传递,因为这些Tile对象是用ScriptableObject.CreateInstance<T>()
实例化的,它不能传递任何构造函数参数。
发布于 2018-01-22 09:53:57
为了使问题和答案更清楚,我想从example中模板这个类,因为它在Unity中使用ScriptableObject.CreateInstance<T>()
实例化的方式不允许构造函数参数。即使在C#中可以通过值进行特殊化(这是不可能的),它也不会有任何帮助,因为实例化方法无论如何都不能创建泛型类型(为什么是Unity?)。所以我使用的解决方案是一个带有模板方法的工厂,它返回基类'Tile‘。
public class TileFactory {
private TileFactory() {}
public static Tile CreateInstance<ScriptType>(string spriteName) where ScriptType : DefaultAI {
var tile = ScriptableObject.CreateInstance<TowerTile>();
tile.sprite = GameManager.shared.sprites[spriteName];
tile.gameObject.name = spriteName;
tile.gameObject.GetOrAddComponent<ScriptType>();
return tile;
}
}
与所讨论的示例相比,的变化是:
在我自己的工厂中封装这个方法,解决了无法将spriteName
传递到ScriptableObject.CreateInstance<T>()
中的问题。method.
ScriptableObject.CreateInstance<T>()
是用非泛型类型调用的,只有在将泛型类型脚本添加到object.
ScriptType
,现在应该是基类DefaultAI
,它是基类MonoBehaviour
(与这个答案的目的并不相关)。另一种选择是使用Buidler
,但由于我只需要传递1个必需的参数,构建器就没有多大意义了。然而,在其他一些情况下,这将是一个更好的解决方案。
附言:感谢Furkan Kambay提供的相关资源,帮助解决了这个问题
https://stackoverflow.com/questions/48366181
复制相似问题