首页 > 解决方案 > C# Unity2D 是否可以基于字符串调用脚本?

问题描述

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

例如:


public text MyVariable;

public void Start()
{
    MyVariable = RunMeBaby;
    MyVariable();
} 

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

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

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


编辑以在下面添加其他说明

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

卡名(字符串)

成本(整数)

图像(图像)

描述文本(字符串)

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

卡名(字符串)

成本(整数)

图像(图像)

描述文本(字符串)

效果1(脚本)

Effect1Amount (int)

效果2(脚本)

Effect2Amount (int)

效果3(脚本)

Effect3Amount (int)

这样,我可以创建最多具有 3 种效果的 CardAsset(例如对角色造成伤害或绘制卡片),然后在我的游戏中使用某些东西在玩家打出该卡片时调用具有相关变量的脚本。

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

我知道这个解决方案容易出错并且维护/更改可能会很痛苦,那么有没有更好的方法可以做到这一点?

标签: c#unity3d

解决方案


您好,欢迎来到 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 关键字而不是硬编码字符串。如果可能的话,您应该完全摆脱字符串并将它们替换为表示可调用方法的枚举,但此解决方案取决于您的用例。


推荐阅读