如何创建模块化 class 列表 属性
How to create modular class list property
我可能问错了问题,因为我无法在网上找到任何关于此的内容...
基本上我的目标是在 project\Schemas\Move.cs:
中定义一个移动 class
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(new Move(...))
或类似的东西。
希望有人能帮帮我!
没有(好的)方法可以做你想做的事。
选项 1:
自己手写出来。例如。 like I did here。这将始终有效,并且是您要避免的事情。
选项 2:
反思性地检查程序集并加载它包含的所有 类,like this。但是这样会很容易做出意想不到的事情。例如,当您创建独立构建时,Unity 会从编译中剔除那些 类,因为它们没有在任何地方被引用。或者无意中实例化了一个不应该存在的对象。或者不记得“哦,是的,MoveXYZ 有一个独特的构造函数,需要一个额外的参数。”
如果我对你的理解正确的话,你正在尝试的是拥有一个,例如List<Move>
并且您想要 "register" 每个在此处创建的 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 中不会自动调用解构函数 - 特别是当任何东西仍然引用这个 Move
实例时......剧透警报:Moves
列表将永远如此!因此,如果需要,每次您真正想要销毁 Move
实例时,您都必须清理 Moves
列表 "manually"。
添加到 derHugo 给出的答案中,以防其他人偶然发现这个问题。我正在使用建议的方法,但发现为了 "import" 在运行时必须使用 [RuntimeInitializeOnLoadMethod]
设置的类型。可能还有其他方法,但这是我最终得到的 3 个移动文件,用于完成答案。
MoveManager.cs
public static class MoveManager
{
public static List<Move> Moves = new List<Move>();
}
Move.cs
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);
}
}
move_basic.cs
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);
}
}
下一步,既然我已经确认了这项工作,我将向已注册的动作添加方法,这才是 IMO 真正神奇的地方。
当您需要创建一个可能需要包含可调用方法的易于扩展的对象库时,这似乎是一个非常理想的解决方案。如果不是因为这个需要,从 csv 或其他东西导入属性可能会更好。
总的来说,我对统一和游戏设计还很陌生,所以我很高兴有这个 post edited/corrected/improved 来帮助未来的搜索者。
我可能问错了问题,因为我无法在网上找到任何关于此的内容...
基本上我的目标是在 project\Schemas\Move.cs:
中定义一个移动 classpublic 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(new Move(...))
或类似的东西。
希望有人能帮帮我!
没有(好的)方法可以做你想做的事。
选项 1:
自己手写出来。例如。 like I did here。这将始终有效,并且是您要避免的事情。
选项 2:
反思性地检查程序集并加载它包含的所有 类,like this。但是这样会很容易做出意想不到的事情。例如,当您创建独立构建时,Unity 会从编译中剔除那些 类,因为它们没有在任何地方被引用。或者无意中实例化了一个不应该存在的对象。或者不记得“哦,是的,MoveXYZ 有一个独特的构造函数,需要一个额外的参数。”
如果我对你的理解正确的话,你正在尝试的是拥有一个,例如List<Move>
并且您想要 "register" 每个在此处创建的 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 中不会自动调用解构函数 - 特别是当任何东西仍然引用这个 Move
实例时......剧透警报:Moves
列表将永远如此!因此,如果需要,每次您真正想要销毁 Move
实例时,您都必须清理 Moves
列表 "manually"。
添加到 derHugo 给出的答案中,以防其他人偶然发现这个问题。我正在使用建议的方法,但发现为了 "import" 在运行时必须使用 [RuntimeInitializeOnLoadMethod]
设置的类型。可能还有其他方法,但这是我最终得到的 3 个移动文件,用于完成答案。
MoveManager.cs
public static class MoveManager
{
public static List<Move> Moves = new List<Move>();
}
Move.cs
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);
}
}
move_basic.cs
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);
}
}
下一步,既然我已经确认了这项工作,我将向已注册的动作添加方法,这才是 IMO 真正神奇的地方。
当您需要创建一个可能需要包含可调用方法的易于扩展的对象库时,这似乎是一个非常理想的解决方案。如果不是因为这个需要,从 csv 或其他东西导入属性可能会更好。
总的来说,我对统一和游戏设计还很陌生,所以我很高兴有这个 post edited/corrected/improved 来帮助未来的搜索者。