- Home /
How do i best describe an object with modular components in Json or other text?
Hello! I am trying to learn how Json works and it is clearly very useful when trying to describe an object. For example, i could describe a basic enemy with
BasicEnemy: {
"attack": 24,
"health": 100
}
in C# it would translate to
class BasicEnemy
{
var attack = 24;
var health = 100;
}
But that can only describe values. If i want enemies to attack in different ways, for example, shooting with a bow and arrow, i want to be able to give them that as a component, like this:
class Property
{
}
class Projectile
{
int damage;
int speed;
}
class Turret : Property
{
int attackSpeed;
Projectile projectile;
}
class MeleeAttack : Property
{
int damage;
int reach;
int attackSpeed;
}
class OnDeathSpawn : Property
{
int enemyTypeToSpawn; int amount;
}
class ArcherEnemy : Enemy
{
List properties = Arrays.asList("new Turret()", "new OnDeathSpawn()");
}
Or just describe the enemy in Json like this:
ArcherEnemy:
{
"health": 100,
"properties": [
"Turret": {"damage" : 20, "attackSpeed": 10}
"OnDeathSpawn": {"enemyType ToSpawn" : 3, "amount": 2}
]
}
And here lies the problem: I can't seem to get this to work with Json because it is convinced that the list will consit of actual Property objects and not any objects that derive from it. I don't know if this approach is the best when it comes to component - oriented enemy/tower design, so if you have any other ideas pleease let me know! I am very much still learning how to approach problems like these, and i'd love all the help i could get!
Summary: I want to be able to describe an enemy or a tower (for example in a tower defence game) using different components. For example, for an Archer Enemy that could be a turret component that spawn projectiles derived from a projectile component. And that archer enemy could spawn two rat enemies when it dies. If you have any thoughts at all, even if they are barely related, i would love to read them! I am in deseprate need of knowledge when it comes to programming. Are there better ways to do this? If this is a good way, how do i achieve what i want to do?
Thank you for reading this wall of text and perhaps responding!
Actually the json you have there is not valid json:
ArcherEnemy:
{
"health": 100,
"properties": [
"Turret": {"damage" : 20, "attackSpeed": 10}
"OnDeathSpawn": {"enemyType ToSpawn" : 3, "amount": 2}
]
}
Note that you declared properties as a json array but the content in your array are not json values. You tried to put key / value pairs in it which only works in json objects, Apart from that you're missing a seperating comma. Json does not support any other types than what is mentioned over here. If you want / need to store the actual type of an object it would need to be part of the object itself.
Alternatively if you replace your array with an object your C# object would not contain an array but actual fields which could have the correct types. However in this case you don't have a dynamic list of properties. The JSONUtility simply isn't meant for any advanced serialization stuff.
Ins$$anonymous$$d you could use my SimpleJSON parser / builder where you can easily manually traverse the serialized data or define what data you want to store. I thought i had posted a more complex example on another answer but i can't find it.
Anyways in order to create the correct type you somehow need to store some information in the json which you can use to deter$$anonymous$$e the actual C# class that need to be created. This could be the actual full qualified class name or some sort of type name or id you have to manage yourself. A common thing would be to create some sort of factory that creates the right type based on the value of a certain json field.
Answer by eses · Sep 05, 2018 at 06:42 PM
Hi @Pigenator
I'm pretty much in the same boat - actually was learning this exact stuff a month ago (and should continue...).
"...because it is convinced that the list will consit of actual Property objects"
This is true, if we are talking about using JsonUtility, that comes built-in with Unity. It uses the same system as unity editor serialization, so similar things work or don't. I've understood that Unity's internal system works by field type, so that is what is happening with your Property... Unless you work with Scriptable Objects, but serializing these run-time seems to be a head ache.
There's an excellent post about Unity serialization by @Bunny83 - see this link:
https://answers.unity.com/questions/1107893/c-serialization-with-polymorphisminheritance.html
Then there are libraries like JSON Net, which I haven't used, which seem to be able to work with types a lot better than Unity JsonUtility.
"Are there better ways to do this? If this is a good way, how do i achieve what i want to do? "
I don't have many ideas but here are some (not yet battle tested):
A. Just use field that match your data. If you are saving turret properties - have a list for them, and another list for something else.
B. Use "dual serialization" (Note, not probably a correct term) - convert your different type objects into json, then store those as strings into your main save class and serialize it to json. This way you can also store type information in this data (this was a turret, that was something else), which you can use to put these back to correct place when loading your data.
Your answer
Follow this Question
Related Questions
javascript objects/json question 1 Answer
Multiple Materials on Multiple Objects -runtime- 1 Answer
Loadlevelasync - Application Hangs 2 Answers