我正在制作RTS游戏。 RTS游戏中的每个单元都可以执行某些操作,例如 Patrol , Attack 或 Build 。在统一中,您可以轻松地为C#脚本手动填写string
和integer
数组。
正因为如此,我认为最简单的单位是string[] str_actions
数组,首次初始化单位时,将此数组转换为Action[] actions
。
我可能do this:
string className = "Attack"
Assembly assembly = Assembly.Load("Actions");
Type t = assembly.GetType("Actions."+className);
Action action = (Action)Activator.CreateInstance(t);
但这并不能解决两个问题:
className
引用不属于Action
我该如何处理?
答案 0 :(得分:1)
回答发布的问题:
多好啊!使用Activator.CreateInstance:MSDN的这个重载,您可以传入一个object [],它将找到最适合的构造函数。有一个默认的构造函数是一个好主意,特别是如果你打算使用序列化。
你无法“处理”它,因为你可以避免它发生。但是,如果转换失败,您编写的代码将抛出InvalidCastException
。为避免这种情况,请使用as
运算符:
Action action = Activator.CreateInstance(t) as Action;
如果演员表无效,action
将只保留null
,而不是投掷。
现在请注意:Activator.CreateInstance
很少是C#的正确选择。通常,您希望使用直接实例化或反序列化。当然,反序列化利用反射;但所有凌乱的细节都被抽象掉了。
答案 1 :(得分:0)
所以我已经弄明白了。我将其作为静态方法Action.fromString
。我缺少的是Type.GetConstructor
方法,它返回ConstructorInfo
对象。
public static Action fromString(string className, string defName, WorldObject actor)
{
//Get the Assembly (namespace)
Assembly assembly = Assembly.Load("Actions");
//Get the exact class Type
Type t = assembly.GetType("Actions." + className);
//Get the info about constructor (using array literal)
// - for every accepted parameter enter typeof(parameterType)
ConstructorInfo constructor = t.GetConstructor(new Type[] { typeof(string), typeof(WorldObject) });
//Initialise the Type instance
System.Object action = constructor.Invoke(new System.Object[] { defName, actor });
//If it's child of the main class
if (action is Action)
return (Action)action;
//Error otherwise
else
{
Debug.LogError("'" + className + "' is not child of Action!");
return null;
}
}