如何使用可自定义的代码块创建 class?

How to create a class with a customizable codeblock?

我目前正在尝试为我的游戏制作一个控制台,并决定制作一个名为 Command 的 class,然后可以用来轻松创建命令是个好主意。我制作了 class 但当然这些 classes 会做截然不同的事情,因此我正在考虑制作一个 属性 基本上就像一个函数,也就是我可以构造一个带有属性 commandName、参数的命令,然后是可自定义的代码块,该代码块将在编写命令时执行。我该怎么做?

public class Command : MonoBehaviour
{
    string inputCommand;
    int arguments;

    void execution()
    {
      //this is where to codeblock to be executed upon typing the command would go
    }
}

编辑: 我取得了看似进步的进展,但似乎仍然无法做到正确。每个动作也需要能够有不同数量的参数(例如“runes.add”需要一个整数来添加符文,“updatestore”需要 none)。任何帮助将不胜感激

public class Command : MonoBehaviour
{
    public string InputCommand { get; set; }
    public int Arguments { get; set; }
    public Action ExecuteAction { get; set; }

}

public class Commands
{
    public List<Command> commandCollection = new List<Command>()
    {
        new Command()
        {
            InputCommand = "",
            Arguments = 1,
            ExecuteAction = new Action(()=>{code to execute goes here})
        }
    };
}

首先,如果你想用对象构造函数(而不是实例化)构造 Command,你不应该从 MonoBehaviour 派生 Command。

我认为你应该创建抽象命令 class 并创建命令作为从命令 class.

派生的 classes

您所谓的“代码块”也可以使用多态性来完成。

所以,你需要做的是:

  1. 创建命令class
public abstract class Command
{
    public abstract void Execute(string[] args);
}

Execute 方法是抽象的,因此我们可以在 subclasses 中覆盖此方法的实现。此方法将命令参数数组作为参数。

  1. 创建一些测试命令
public class TestCommand : Command
{
    public override void Execute(string[] args)
    {
        Debug.Log("Test command invoked, passed parameters count: " + args.Length);
    }
}
  1. 创建 CommandRegistry class(这是你的命令 class)
public class CommandRegistry
{
    private Dictionary<string, Command> _commands;
    
    public CommandRegistry()
    {
        _commands = new Dictionary<string, Command>();
    }

    public void RegisterCommand(string name, Command command)
    {
        // You should also check here if command already exists 
        if(_commands.ContainsKey(name))
        {
                // Print error here or throw an exception
                return;
        }

        _commands[name] = command;
    }

    public void RegisterAllCommands()
    {
        // Add here every new command to register it
        RegisterCommand("test", new TestCommand());
    }

    // Returns false if command not found
    public bool ExecuteCommand(string commandName, string[] args)
    { 
        if(_commands.ContainsKey(commandName) == false)
            return false;

        _commands[commandName].Execute(args);
        return true;
    }
}

就是这样。您需要调用 ExecuteCommand 方法来执行命令并传递命令的名称和参数。

您应该检查 Command.Execute 方法中的参数计数。

此外,如果您需要访问您的游戏 methods/fields(例如添加符文),您应该提供对此 fields/methods 的静态访问或创建类似 CommandContext class(或 GameContext ).

此 class 的一个实例将传递给每个命令,它包含对可以执行添加符文等操作的对象的引用。

然后您需要向 GameRegistry.ExecuteCommand 和 Command.Execute 方法添加一个新参数 (CommandContext)。