Really interested in when and why would you use XML for unit/game stats instead of Inspector values?
Example:
You build an RTS game and you have units, buildings, soldiers and they need health, speed, damage and many other stats.
Would you just expose their values to their prefab Inspector and tweak it there? Or use XML for their data, so you have it in one place? Both have advantages as well as disadvantages.
The Inspector is designed to configure GameObjects and their Components. It’s great at that. It’s not really so great at navigating and editing large sets of data, because it’s not designed for that.
At work we have some objects which are defined with thousands of pieces of data that can be nested to an arbitrary level. Could the Inspector display this? Probably. Would I want to try to find, tweak and save just one of those values in the Inspector? Heck no!
Plus, as @Kiwasi says, we don’t just use those objects in Unity. They’re used by multiple teams on potentially unrelated projects, so even if we could use the Inspector effectively for our work there’s other requirements it doesn’t meet.
Though with built in .NET serialisation that cost is still pretty low.
When you store game stats in XML, do you have separate, static variables that are loaded with this values contained in XML at application initialization?
Or the separate classes (bullet, units, whatever) have their own values and at start they assign the XML values to them selves. (This could however lead to bullets always assigning values within a large set of data for example.)
Depends on what you mean by “game stats” (your example is for spawning static data and xml and json is fine for that if it’s too large of a data set to be managable in the inspector). If instead you had some runtime data that changed as the player progressed the lightest weight option in Unity that is cross-platform is playerprefs. If you have a large set of data, xml or json is just fine but are you intending to store local or on a webserver somewhere? Local is certainly fine for things like tracking how many levels you’ve unlocked, static data like you spawn info, etc, but nowadays it is nicer to store these or shadow these (if you want to let them also play offline) in the cloud. That way things like high scores, etc. are easy to see for everyone, or if you wanted to tweak your game you could just modify the value on your webserver and it would be picked up the next time they started the game (you’d setup this logic). It also has the side benefit of having a place under your control to verify people aren’t cheating.
As far as when to load that is entirely up to your specific application. If it’s a small set of data and take very little processing time usually you can load it whenever you want. The larger the amount of data the longer it will take and it will be noticeable so it’s usually done in the background while you display a loading screen or have something else going on.
Ah no, I dont mean saving game. Civilization IV is great example, in their assets folder, they have bunch of XML, loaded with unit, building technology stats etc. So building costs 20 gold, it builds for 7 turns, the lion has 2 speed etc.... That sort of this, and this is done at application initialization, though Im really interested how people handle this big sort of data, because if you would have in your scripts:
public static string lion_name;
public static int lion_health;
public static int lion_speed;
public static int lion_damage;
public static float lion_animationSpeed;
and imagine you have 30 variables per unit, and game can have hundred of units, buildings technologies and what not.
Do you store it as these type of static variables and initialize the fields from XML at game start? Or put them into some dictionary, and have some IDs, or maybe there is another technique.
If things are of types that relate to one another I would use inheritance to reduce complexity. Speed, health, damage would be declared in an abstract base class (or concrete if it made sense on it’s own) and the other types (lion, infantry, etc.) would inherit from the base class as appropriate. If they weren’t closely related but there were a few common themes/verbs (ie. consume, attack, etc.) that ran through your game, instead of class inheritance, I would use a set of useful interfaces that each type would implement.
Since it’s very likely in your example that they are related I would use inheritance with most of the logic implemented in the base class (including loading from the xml or json).
Static simply means the variable is at the class level not the instance level. Why do you invision needing these declared at the class level? Couldn’t you possibly have different speeds of lions? Or do you envision all of them being the same so these are really attributes of the class and not the instance? All of these would factor into the schema of your xml/json. The xml/json files are just data so if you wanted them to just define the “types” you could do that or you could have them be essentially partial Unity hierarchy substitute and the data in them would define the “scene instances” instead of just the types. The scope of what you are breaking out into data files is up to you and generally will be tailored to your requirements.
Since what you describe it probably going to be a lot of data if you really have that many types/instances you are probably going to have to be aware of how much data there is and how much memory it is using when loading (especially on mobile) so the OS doesn’t terminate the game. Generally speaking, you’ll probably have a loading screen that belongs to the scene in question parked in front of the camera while the real data loads in the background and signals when complete to actually show the user the game. This will happen when all of the awake() and start() functionality you wrote to read from the data files completes.
@greggtwep16 I know these things I wasnt asking because I dont know how to do it, but how do you, other users do it, since I was interested in, what kind of practices or methods other people have.
When you have that unit class, you have one health for all units but that health can be different for all units (usually is).
So when you start your game you need to get that data from XML, and store it inside variables of lion, swordsman1 swordsman 2, tank, plane etc.
All have the same parent class, but damage, speed, health is different across all types of these units.
Having done this before too, I am now confused as to what specifically you are asking for then? You read the file and populate each instance (swordsman1, 2, tank1, etc.) with the data in the file if that’s how you have it setup. So if you know how to read the file and you have the variables to populate in your class that is derived from Monobehavior simply map the variables across.
You can do this many ways in any of the unity provided hooks (start(), onlevelwasloaded(), etc). The “lookup” to the file can either be in a standalone manager class that reads and populates all your instances data at once, or each instance can lookup an “id” in the file and grab their own data. Really the implementation is up to you there are many ways to do this and it sounds like you are aware of them so choose the one that suits your situation best.