Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question deserialized json with function as value

Discussion in 'Scripting' started by k123m, Sep 5, 2023.

  1. k123m

    k123m

    Joined:
    Aug 15, 2023
    Posts:
    13
    hi all,
    I'm having trouble deserialized json object that has a function as one of the value
    i have c sharp object called Ability that has a a delegate function type as one of its properties
    I need to deserialized json object that has a function as a value to Ability object
    the function doesn't have return type and only do calculation on damage parameter that I'm sending
    I tried sending the function as string but when I tested the json I receive a delegate with string return type
    any idea how to send function to c sharp class with json without turning the function into string

    my json object:
    Code (CSharp):
    1. @"""
    2.        {
    3.            Hermiticloner:{
    4.                name: Hermiticloner,
    5.                desc: Increases damage to Royal Knights by 20%,
    6.                handlers:{
    7.                onstart:function () {
    8.                    }
    9.                onModefiy:function(damage){
    10.                    var digimon_attack = damage;
    11.                    var amount_to_increas = digimon_attack * (attak_buff_percentage / 100);
    12.                    var new_attack = digimon_attack + amount_to_increas;
    13.                    return new_attack;
    14.                    }
    15.                }
    16.            }
    17.        }
    18.        """;
    my Ability Class
    Code (CSharp):
    1. [Serializable]
    2. public class Ability
    3. {
    4.     public string name { get; set; }
    5.     public string desc { get; set; }
    6.     public  Action onstart { get; set; }
    7.     public  Action onModefiy { get; set; }
    8. }
    9.  
    code returning from testing my json:
    Code (CSharp):
    1. public class Onstart
    2. {
    3.         public string func { get; set; }
    4. }
    5.  
    6. public class OnModefiy
    7. {
    8.         public string func2 { get; set; }
    9. }
    10.  
    11. public class Hermiticloner
    12. {
    13.         public string name { get; set; }
    14.         public string desc { get; set; }
    15.         public Onstart onstart { get; set; }
    16.         public OnModefiy onModefiy { get; set; }
    17. }
    18.  
    19. public class Root
    20. {
    21.         public Hermiticloner Hermiticloner { get; set; }
    22. }
    23.  
     
    Last edited: Sep 5, 2023
  2. Saeed-B

    Saeed-B

    Joined:
    Jul 12, 2021
    Posts:
    46
    You can't serialize function bodies to JSON or any other serialization format, because that's not what they're designed for. Instead of passing the whole function, try passing in values that hint towards using that function.
     
  3. k123m

    k123m

    Joined:
    Aug 15, 2023
    Posts:
    13
    would this work
    Code (CSharp):
    1. public class Ability
    2. {
    3.     public string name { get; set; }
    4.     public string desc { get; set; }
    5.     public string flag { get; set; }
    6.     public int onStatusModefiy(int dmgbuff_percentage,Digimon attacker,Digimon target,Move move,string status) {
    7.         int new_attack = attacker.baseStats[status];
    8.            foreach (string attribute in attacker.attribute)
    9.            {
    10.              if (attribute == this.flag)
    11.              {
    12.                 int digimon_attack = attacker.baseStats[status];
    13.                 double amount_to_increas = (double)digimon_attack * (double)(dmgbuff_percentage / 100);
    14.                 new_attack = (int)digimon_attack + (int)amount_to_increas;
    15.             }
    16.            }
    17.            if(attacker.type == this.flag)
    18.            {
    19.             int digimon_attack = attacker.baseStats[status];
    20.             double amount_to_increas = (double)digimon_attack * (double)(dmgbuff_percentage / 100);
    21.             new_attack = (int)digimon_attack + (int)amount_to_increas;
    22.            }
    23.            if(this.flag == "all")
    24.             {
    25.                 int digimon_attack = attacker.baseStats[status];
    26.                 double amount_to_increas = (double)digimon_attack * (double)(dmgbuff_percentage / 100);
    27.                 new_attack = (int)digimon_attack + (int)amount_to_increas;
    28.             }
    29.         return new_attack;
    30.     }
    31.  
    32. }
    my json :
    Code (CSharp):
    1. public string generateAbilityJson()
    2. {
    3.      var ability_json = @"""
    4.     {
    5.         Hermiticloner:{
    6.             name: Hermiticloner,
    7.             desc: Increases damage to Royal Knights by 20%,
    8.             flag: all
    9.         }
    10.     }
    11.     """;
    12.      return ability_json;
    13. }
     
  4. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,495
    Well, your class would probably work, though I haven't looked through your logic inside your "onStatusModefiy" method.

    This won't work since the text you've shown is not valid json. Note that json is a strict subset of javascript. JSON keys always need to be strings and they have to be in double quotes. String values also needs to be in double quotes. JSON is extremely simple as you can see here.
     
    k123m likes this.
  5. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    Rather than serialise delegates/methods (which I don't think you can do, or at least, something JSON can't to), you'd be better off serialising out references to plain C# classes with polymorphism. It takes extra work with JSON, but tools like the Odin Serialiser support by-reference serialisation out of the box.
     
    k123m likes this.
  6. k123m

    k123m

    Joined:
    Aug 15, 2023
    Posts:
    13
    hi all thanks for the replies, the code worked perfectly,the flag change per object so I used the flag to Triger deferent effects on my function
     
    Last edited: Sep 6, 2023
  7. Saeed-B

    Saeed-B

    Joined:
    Jul 12, 2021
    Posts:
    46
    Newtonsoft supports polymorphism as well. TypeNameHandling setting (newtonsoft.com)
    you can also write your own converter in Newtonsoft to handle polymorphism in a way that best suits your case
     
    k123m likes this.
  8. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    Yeah I know it does, I just prefer the Odin Serialiser as it handles all this with no extra work.

    And, weirdly enough, it apparently can serialise and deserialise delegates. So who knows, maybe that's the solution to OP's problem.
     
  9. Saeed-B

    Saeed-B

    Joined:
    Jul 12, 2021
    Posts:
    46
    I had no idea it serializes delegates! that's really cool, and yes, seems to be the actual answer to OP's question