C#-さまざまなメソッドを呼び出す最良の方法

2020-06-30 c#

これがコードです。

    public abstract class GameFunction
    {
        public static GameFunction Factory(string name)
        {
            switch (name)
            {
                //case "AddItem":return new ;
                default:Debug.Log("Invalid GameFunction."); return null;    // unity log
            }
        }
        public abstract void Exec(object a, object b, object c);
    }

    // Functions for character: effect for a job
    public class GFAddRecipeItem : GameFunction
    {
        public override void Exec(object worker, object param2, object param3)
        {
            //(Character)a.Inventory.AddItem((ItemType)b, (int)c);                  // PROBLEM: Works fine with console. But I can't find a good way to feed different params from GameEffect
            ((Character)worker).Inventory.AddItem(((Character)worker).CurrentJob.Recipe.OutputInventory);       // PROBLEM: explicit cast
        }
    }

    // GetMarried(worker, Character target, object? param3)
    public class GetMarried : GameFunction
    {
        public override void Exec(object worker, object param2, object param3)
        {
            ((Character)worker).MarryTo(((Character)worker).CurrentJob.target);       // I have to write function for each stats without reflection
        }
    }

    // GFAddSTR, GFAddDEX ... a lot of functions
    public class GFAddSTR : GameFunction
    {
        public override void Exec(object worker, object f, object param3)
        {
            ((Character)worker).Strength += (float)f;       // I have to write function for each stats without reflection
        }
    }

    // Functions for buildings...
    // And a lot of functions...

    public class GameEffect
    {
        // call game function
        // add stats, move character, form party ...
        public GameEffectType GameEffectType { get; set; }
        public float CurrentDuration { get; set; }
        public float MaxDuration { get; set; }
        public object Subject { get; set; }
        public object Target { get; set; }
        // ... other props
        public void Start()
        {
            GameEffectType.GameFunctionStart.Exec(Subject, Target, null);
        }

        public void Updata()
        {
            //...
        }

        public void Finish()
        {
            GameEffectType.GameFunctionFinish.Exec(Subject, Target, null);
        }
    }

    public class GameEffectType
    {
        public string Name { get; set; }
        public GameFunction GameFunctionStart { get; set; }  // in game it's a ref
        public GameFunction GameFunctionFinish { get; set; }
    }

    public class GameEffectTypeXml
    {
        public string Name { get; set; }
        public string GameFunctionStart { get; set; }    // it's in xml
        public string GameFunctionFinish { get; set; }
        // ... same
        public GameEffectType ConvertFromXml(Dictionary<string,GameFunction> DictName2GFType)
        {
            GameEffectType res = new GameEffectType();
            // use reflection to convert xml serializations to game object
            // use a factory to create different functions
            return res;
        }
    }

ゲームが開始すると、各GameFunctionが新しいインスタンスを作成します。 GameEffectTypeオブジェクトはxmlから解析され、文字列から参照に変換されます。ゲームエフェクトインスタンスにはサブジェクトとターゲットがあり、ジョブ、ゲームイベントなどによって動的に作成されます。

統計情報ごとに1つ、AddSTR、AddDEX、AddINTなど、数百ものさまざまなゲーム関数を作成する必要があります。将来はさらに難しくなります。コードを実装するより良い方法はありますか?

コマンドパレットは次のようになります。

        <?xml version="1.0" encoding="utf-8"?>
    <ArrayOfManualCommand xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <ManualCommand>
        <ListCommand>
          <CommandSlot>
            <Type>Character</Type>
            <Name>CharName</Name>
          </CommandSlot>
          <CommandSlot>
            <Type>Item</Type>
            <Name>ItemName</Name>
          </CommandSlot>
          <CommandSlot>
            <Type>Int</Type>
            <Name>Amount</Name>
          </CommandSlot>
        </ListCommand>
        <Name>AddItem_Character</Name>
        <CommandName>AddItem</CommandName>
      </ManualCommand>
      <ManualCommand>
        <ListCommand>
          <CommandSlot>
            <Type>Character</Type>
            <Name>CharName</Name>
          </CommandSlot>
          <CommandSlot>
            <Type>JobType</Type>
            <Name>AssignJobType</Name>
          </CommandSlot>
          <CommandSlot>
            <Type>Recipe</Type>
            <Name>Recipe</Name>
          </CommandSlot>
        </ListCommand>
        <Name>AssignJobRecipe</Name>
        <CommandName>AssignJob</CommandName>
      </ManualCommand>
    </ArrayOfManualCommand>

異なるタイプはCharacter.AssignJobのオーバーロードメソッドのものです。

Answers

Related