C# 如何创建模块化类列表属性
我可能问错了问题,因为我在网上找不到关于这个的任何东西 本质上,我的目标是在project\Schemas\move.cs中定义一个move类:C# 如何创建模块化类列表属性,c#,class,unity3d,modular-design,C#,Class,Unity3d,Modular Design,我可能问错了问题,因为我在网上找不到关于这个的任何东西 本质上,我的目标是在project\Schemas\move.cs中定义一个move类: public class Move { private int power; private float accuracy; private string type; private string style; public Move(int p, float a, string t, string s,
public class Move
{
private int power;
private float accuracy;
private string type;
private string style;
public Move(int p, float a, string t, string s, float sh)
{
this.power = p;
this.accuracy = a;
this.type = t;
this.style = s;
}
}
我希望可以从我的游戏引擎访问所有移动的集合,但我希望该移动集合能够基于project\moves\move.*下的其他文件自动生成
老实说,我不知道如何在C#中这样做。在另一种语言中,我只需初始化一个全局集合,并在每个移动文件中调用GlobalCollection.Add(newmove(…)
或类似的东西
希望有人能帮我 没有(好的)方法来做你想做的事。
备选案文1:
你自己亲手写出来。例如。这将始终有效,并且是您试图避免的事情
备选案文2:
反射性地检查程序集并加载它包含的所有类。但这很容易发生意想不到的事情。例如,在创建独立构建时,Unity会从编译中剔除这些类,因为它们没有在任何地方引用。或者无意中实例化了一个不应该出现的对象。或者忘记了“哦,是的,MoveXYZ有一个唯一的构造函数,需要一个额外的参数。”如果我理解正确,您尝试的是拥有一个,例如
列表
,您希望在这里“注册”每个创建的Move
实例。那么,为什么不简单地说
// This is a static class so it does not have to be instantiated
// but rather simply "lives" in the assets
public static class MoveManager
{
public static List<Move> Moves = new List<Move>();
}
public class Move
{
private int power;
private float accuracy;
private string type;
private string style;
public Move(int p, float a, string t, string s, float sh)
{
power = p;
accuracy = a;
type = t;
style = s;
// a static class member is simply accessed via the type itself
MoveManager.Moves.Add(this);
}
}
问题:什么时候从列表中删除它们?
通常,您希望在解构器中执行此操作,例如
~Move()
{
MoveManager.Moves.Remove(this);
}
但是在Unity中解构器不会自动调用-尤其是当任何东西仍在引用此
移动
实例时。。。扰流板警报:移动
列表将始终有效!因此,如果需要,您必须在每次确实要销毁移动
实例时“手动”清理移动
列表。添加derHugo给出的答案,以防其他人意外发现。我正在使用建议的方法,但发现为了在运行时“导入”类型,必须使用[RuntimeInitializeOnLoadMethod]
。可能还有其他的方法,但这里有3个移动文件,我最终得到的答案完成的采取
MoveManager.cs
move_basic.cs
下一步,既然我已经确认了这一点,那么将向注册的移动添加方法,这才是真正的魔力所在
当您需要创建一个易于扩展的对象库(可能需要包含可调用的方法)时,这似乎是一个非常理想的解决方案。如果不是出于这种需要,从csv或其他文件导入属性可能会更好
一般来说,我对unity和游戏设计非常陌生,因此我非常高兴编辑/更正/改进这篇文章,以帮助未来的搜索者。为什么你不能在C#中也这样做?我的意思是,为了初始化全局集合,您需要事先知道可能的移动列表(在
project\moves\move.*
中(PS:C中的名称move.
有点奇怪)因为在C#中,编译器不会接受在命名空间或类之外运行的函数,我希望避免将每一项作为类导入/初始化……我不会死气沉沉地使用move#或任何命名方案,主要目标是使父文件夹中的所有内容动态加载到gl中有意思的是,这让我有点思考和研究……这两个选项似乎都不是特别吸引人的,但我想如果它们是唯一的方法,那么这就是筹码下降的原因。我会继续寻找一点,如果我最终使用其中一个,我会接受答案。太棒了,这是真实的ly看起来正是我要找的!不需要从这个列表中删除移动,因为它将是全球注册商…谢谢@derHugo!
public static class MoveManager
{
public static List<Move> Moves = new List<Move>();
}
public class Move
{
public string name;
public string description;
public Target target;
public int power;
public float accuracy;
public int cost;
public game_Type type;
public Style style;
public Move(
string name
, string description
, int power
, float accuracy
, int cost
, string typeName
, string styleName
, string targetType
)
{
this.name = name;
this.power = power;
this.accuracy = accuracy;
this.description = description;
this.type = game_Types.getByName(typeName);
this.style = MasterStyles.getByName(styleName);
this.target = new Target(targetType);
// a static class member is simply accessed via the type itself
Debug.Log("Registering " + name + " type!");
MoveManager.Moves.Add(this);
}
}
class move_basic
{
[RuntimeInitializeOnLoadMethod]
static void OnRuntimeMethodLoad()
{
// Name this move
string name = "Attack!";
// Describe this move
string description = "Strike out at the enemy with tooth, claw, weapon, or whatever else is available!";
// Choose the type of target this move is for
// self/ally/selfAlly/enemy/enemies
string target = "enemy";
// The move typing - This determines cost reduction as well as potential attack bonuses
string typeName = "physical";
game_Type type = game_Types.Types.Find(x => x.name == typeName);
// The move style - This determines additional bonuses and modifiers
string styleName = "martial";
// Style style = ??
// Power of the move, base/'normal' power is 50.
int power = 50;
// Accuracy of the move, base/normal is 90
int accuracy = 90;
// MP Cost of the move
int cost = 0;
Move mv = new Move(name, description, power, accuracy, cost, typeName, styleName, target);
}
}