C#Unity2D是否可以基于字符串调用脚本



是否可以在脚本中运行方法,其中方法的名称是从文本变量中找到的?

例如:


public text MyVariable;
public void Start()
{
MyVariable = RunMeBaby;
MyVariable();
} 
public void RunMeBaby()
{
Debug.Log("You did it!");
}

在上面的例子中,我将变量"MyVariable"分配给"RunMeBaby"(我要调用的方法的名称(,然后尝试调用它。

以上内容对我不起作用,但还有其他方法吗?


编辑以在下方添加其他澄清

我目前正在创建自己的纸牌游戏。我创建了一个可编写脚本的对象(CardAsset(来处理我所有填充的卡都需要的一些字段。类似:

卡名(字符串(

成本(int(

图像(图像(

描述文本(字符串(

我现在已经完成了原型的所有其他东西(游戏场地、牌组等(,我需要开始为我的卡片制作效果。由于每张牌都不同,但有些效果是相同的(例如,抽更多的牌和对角色造成伤害是非常常见的(,我想我可以更改我的脚本对象CardAsset,以包括一些脚本和变量:

卡名(字符串(

成本(int(

图像(图像(

描述文本(字符串(

Effect1(脚本(

Effect1Amount(int(

Effect2(脚本(

Effect2Amount(int(

Effect3(脚本(

Effect3Amount(int(

通过这种方式,我可以创建最多有3个效果的CardAssets(同样,比如对角色造成伤害或绘制卡片(,然后在玩家玩该卡时,使用游戏中的一些东西来调用这些带有相关变量的脚本。

我的问题是,我无法将脚本附加到我的CardAsset,所以我想一个合适的解决方法是在CardAsset的Effect1/Effect2/Effect3插槽中键入方法的名称(DealDamage、DrawCards((将它们更改为字符串(,然后让一些东西读取它们,并在其他地方调用关联的方法。

我知道这个解决方案容易出错,维护/更改可能会很痛苦,所以有更好的方法吗?

大家好,欢迎来到Stack Overflow,

我不知道你的文本类的细节,但根据你的问题,我认为它是一个字符串容器(可以这么说(。使用反射:,您可以完全按照要求执行操作(调用基于字符串的方法(

// You need the class name, so I just called it MyClass
public class MyClass 
{
public void Start()
{
string methodName = "RunMeBaby";
// Invoke the method using reflection
typeof(MyClass).GetMethod(methodName)?.Invoke(this, null);
} 
...

然而,这是一个非常昂贵(而且容易出错(的调用。我的建议是使用一种不那么通用的方法:

public void Start()
{
// assuming text.Text is your string property
string methodName = "RunMeBaby";

CallMethod(methodName);
} 
private void CallMethod(string methodName)
{
switch(methodName)
{
case nameof(RunMeBaby):
RunMeBaby();
break;
case nameof(SomeOtherMethod):
SomeOtherMethod();
break;           
}
}
private void RunMeBaby()
{
}
private void SomeOtherMethod()
{
}

注意:我不知道你的方法字符串是从哪里得到的,但如果它不是来自某种外部来源(例如用户输入(,最好使用nameof关键字,而不是硬编码的字符串。如果可能的话,你应该完全去掉字符串,并用一个表示可调用方法的枚举来替换它们,但这个解决方案取决于你的用例。

如果要按名称调用方法。你可以使用反射:

Test type = new Test();
typeof(Test).GetMethod("Hello").Invoke(type, new[] { "world" }); 

您可以通过C#中的反射来实现。但在我们到达那里之前,我建议如果可能,您可以使用操作代理(https://learn.microsoft.com/en-us/dotnet/api/system.action?view=netframework-4.7.2(,你可以将你的方法分配给它,然后在你想要的任何地方调用它。因此,您的代码将看起来像:

public Action MyVariable =RunMeBaby;
MyVariable();

现在的反射方式:

public string MyVariable = "RunMeBaby";
public void Start()
{
this.GetType().GetMethod(MyVariable).Invoke(this, null);
}

上面的代码假设要调用的方法(在您的情况下为"RunMeBaby"(是公共的。

https://learn.microsoft.com/en-us/dotnet/api/system.type.getmethod?view=netframework-4.7.1https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/reflection

最新更新