Collection of Properties in (C#) Class

Hi,

I need help on a spell system that I’m creating. Each spell has to have a list of unique AbilityEffects. These AbilityEffects need to have different properties like how much damage they do or how long the buff that the AbilityEffect inflicts on the target lasts. The properties of each AbilityEffect need to be able to be serialized so that they’re modifiable in the Editor. I’ve concluded that the best way to do this is to create a resizable list of properties, each element of which can be accessed by name or id.

I was wondering how one might go about creating this list of properties (floats and ints, nothing too complex) that can be accessed by name. X-UniTMX has a good one called PropertyCollection that lets you have a resizable amount of properties for MapObjects generated from a Tiled map. However I didn’t want to use this one since it says in the comments that games shouldn’t be able to use their PropertyCollection for some reason.

Any suggestions on how one might go about creating this PropertyCollection, or should I just use the X-UniTMX one?

I don’t know what your concept is but I have a weird but working idea:
You create an empty game object and attach to it a script like this one:

class Spell : MonoBehaviour {
     public string Name;
     public byte Damage;
     public float Buff;
     public float Range;

     void Update () {
          //some code
     }

     //some code
}

Now you just copy the empty object a few times so you have an object for each spell and you can individually change the variables in the editor. Little bit weird but simple enough and it should work.

First of all Karwler thanks a lot for the reply. Your solution definitely would work but the reason I need something like a PropertyCollection is that there are going to be different variables for each spell. For example, one spell might be a damage spell and would have variables ‘dmgAmount’. Another one might be a slow spell and have variables ‘slowDuration’ and ‘slowPercentage’. So this is why I can’t really have a nice simple method like that.

My approach was to make an abstract AbilityEffect class. Inherit various types from here. Each new spell, add the components you need. DamageEffect has properties for damageAmount and a damageType enum. SlowEffect has a slowPercentage and slowDuration. Each has an overridden ApplyEffect method that deals damage, slows the target, etc. All properties can be exposed to the editor very easily.

I am not a fan of your scripts guessing which properties the spell might have and trying to react accordingly. Let the spell be the driver - it knows what its job is. You can set up the properties of each component easily. All you need to do is get a collection of the AbilityEffects components attached to your spell, call the ApplyEffect method of each, and let them do their jobs.

Thanks Zaladur,

Right now I’ve done something similar to what you’ve said, each ability effect is a child of the AbilityEffect class. Each AbilityEffect has an id enum that determines which AbilityEffect it is, and I’m using a switch statement based on that id to expose the different variables of each AbilityEffect. However as more AbilityEffects are created that enum is going to grow, and it just seems really bad to hardcode those ids in. The question is how do I expose the variables in the editor efficiently (not having to use something as silly as a switch statement)?

two possible ways to get the serialization to work correctly the way you want do to it:

Use ISerializationCallbackReceiver to do the serialization you need yourself. Might be a bit boring work but gets you through.

Use ScriptableObject for each AbilityEffect and do something like Zaladur with having an abstract base class and deriving each effect you want from it. Added benefit is that you can then save your completed spell using AssetDatabase.CreateAssset and AssetDatabase.AddObjectToAsset like outlined in this unite talk to create an asset that behaves just like all other in unity’s project view.

A completely different approach was suggested a little bit by Karwler: You can write your monobehaviours the way you want it by making each abilityeffect a monobehaviour and combining them on the spell prefab as necessary (e.g. DamageEffect, ValueBuffEffect …).

The project I am currently working on has a completely generic “ability” system where you can define your abilities like

AbilityGenerator()
.WithAreaOfEffect(AbilityGenerator().WithDamage(25).WithBuff(BuffType.X, 3).Build())
.Build()

This system then exports this data (only defined in code due to lack of an editor) to JSON which is then read by the client and server at runtime.