- Home /
Storing and Accessing Abilities
Hi, I am making a card system in c# and want to assign the cards attributes based on an ID as a new card object is created.
Basically each ability will have (roughly) Name Ability Image Description Text Target Method (how you select a target) Ability Method (the ability does stuff here)
I mean, do I just make an ability class that stores this info and then generate an array of abilities in one long file of code?
Should each ability have a class of it's own? Should I somehow implement it with prefabs?
I can think of ways to do it, but they seem inefficient and weird. I am just wondering what the best way would be?
My other issue is I want this to be pretty modular as I might want to use it to store character abilities in another game for example.
Answer by MrDiVolo · Apr 17, 2016 at 03:36 PM
There are three potential ways I would do this; a class array in the Inspector, a database, or a text file. The first of those is the easiest, but if you're planning a large project and you're going to have a lot of these cards, I'd try option number 2, and a text file as your last resort (as it's the same as a database but with less structure).
Inspector example
In the above example, I've created a CardManager that stores an array of Card. Each card has the example fields you listed above, with the exception of AbilityMethod; I didn't know if this and TargetMethod were meant as actually methods, however, if they were meant as fields, you could use a switch statement on the Ability enum, to determine the method? (just a suggestion as I don't know much about the project)
If you want an example of a database then I can try to draw one up for you, but the basics of it would be a setup similar to the classes listed above, a table each for; Card, Ability and Targetting. (In modern database programs you should be able to link the image field in the table to an actual image on the HDD, but it depends what you're working with). Once read using something like OLE DB, you will still have to load the images using the string that will likely be the actual version of the 'image' used in the database.
And finally for the text (CSV) file you would have to use a string path for the location of the image instead, and use a StreamReader for reading/writing.
Update - 17/04/16 (20:50)
As @Soraphis mentioned, using an Excel spreadsheet/Google Sheets file to create the data would be a good idea. Then export the spreadsheet as a .csv file (alternatively, as I'm about to explain, you could just use the CardManager, and then Serialize the data). Next I would create a custom inspector, that allowed you to browse for this CSV file, and import the data into a List of your Card class. From here you can then re-export the data read in, but in a binary file format. This secures the data as only you know what the data structure of the Card class is, how you wrote this list to the file, and how to read it back out. Below is an example a full solution for this, so if you want to try it for yourself first then here are the links;
The derived solution would take up way too much room, as such here is a video of me walking through what I came up with;
As for directly pointing to methods, I still think it would be best to just have a separate class that knows what methods each enum ability and target point to.
I hope this helped.
Heya, this is a very concise and informative answer, so thank you!
Ideally I would want a direct pointer to the method used for targeting and for the ability itself. i.e. I might make a card called Fireball that uses Target_Enemy() and Ability_Fireball() that would use those when perfor$$anonymous$$g the action, though I would likely have to make it more complex as it goes.
In terms of the database, would there be any risk of the player modifying values within it? For example, if I ended up storing the damage of the Fireball card in the database, could they go in and edit it? $$anonymous$$y thought was I would have to have all of the data built into the executable.
if all your data is local on the player's system, theres always a method to cheat. so i would not bother with that. (you could implement some checksum tests or whatever, but given enough time theres always a way around)
your card has knows the primary key of the ability. search the database for this key and fill a ability-objekt with the data of the database.
you'll run into problems if you want to do animation and stuff, when using an ability. there are some solutions: hardcode those animations in an AbilityAnimation class finding them via reflections by the ability's name
use some kind of scripting language (e.g. LUA) to script the animations. save those scripts as strings in the database(or where ever, see my other answer)
there may be more solutions (e.g. animation assets) but i think the above solutions would be the best/easiest
Answer by Soraphis · Apr 17, 2016 at 05:55 PM
As an alternative @MrDiVolo's Textfile solution:
Create a class "AbilityDatabase" extending from ScriptableObject. the database holds an array of "Ability" objects (your ability class), which should be serializeable.
add the "createassetmenu" attribute to the AbilityDatabase and create an instance of it. now you have a prefab which holds all your abilities.
well, this solution has the same flaws as the database solution and the the textfile solution.
what you COULD do:
create a excel/google-docs table where you hold all your data, export it to csv and as text asset into unity, parse this file and generate a c# file with the abilities in it.
if you add or change an ability just generate the c# file new. you can access all abilities from code.
i'd prefere this solution instead of writing the code file all myself
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Fastest way to store huge amounts of data? 2 Answers