Hey folks,
I started working on a side project to learn how to make a modular spell system ages ago and after doing tons of research i ended up with a system that is entirely built from monobehaviours. One of the key features i wanted was a conditional effect system, so for example a healing aoe spell can only affect units in an area if they are the correct faction, or a vampiric attack would only heal a player if the damaging part of the attack hits. It all works nicely but i want to move the entire system over to scriptable objects because the entire system is just data (and i thought it would be a good opportunity to properly experiment with scriptable objects).
My problem is i’ve been fiddling around for a few days now and i can’t work out a way to make the same modular style system with scriptable objects. My original system uses the scripts below, which can all be extended to make any sort of effects and conditions i’ve wanted so far.
I’ve watched Richard Fine’s talk on Scriptable Objects, the Pluggable AI tutorials, the Ability System Tutorial and i tried pulling apart the adventure game demos condition/reaction system, but i’m really struggling to work out how to make a modular system to work with Scriptable Objects instead. Could anyone give me some help to point me in the right direction?
Ability
public class Ability : MonoBehaviour {
public List<Target> targets;
public void UseAbility(Unit caster)
{
//For each target script in ability
foreach (Target t in targets)
{
//initiate list and gather targetable units
List<Unit> tUnit = new List<Unit>();
tUnit = t.GetTargets(caster, requireLineOfSight);
//for each effect on a targeting script
foreach (Effect e in t.Effects)
{
//apply effect to each unit in targeting script
foreach (Unit u in tUnit)
{
e.ApplyEffect(caster, u);
}
}
}
}
}
Target
public class Target : MonoBehaviour{
List<Effect> _effects;
public List<Effect> Effects { get { return _effects; } }
public virtual List<Unit> GetTargets(Unit caster, bool requiresLos) {
}
}
Effect
public class Effect : MonoBehaviour {
public virtual void ApplyEffect(Unit caster, Unit effectTarget)
{
}
}
ConditionalEffect
public class ConditionalEffect : Effect {
[SerializeField]
List<Condition> condition;
public List<Condition> Condition { get { return condition; } }
[SerializeField]
List<Effect> effect;
public List<Effect> ConditionalEffects { get { return effect; } }
public override void ApplyEffect(Unit caster, Unit effectTarget)
{
bool canApply = true;
foreach (Condition c in condition)
{
if (!c.IsConditionTrue(caster,effectTarget))
{
canApply = false;
break;
}
}
if (canApply)
{
foreach (Effect e in effect)
{
e.ApplyEffect(caster,effectTarget);
}
}
}
}
Condition
public class Condition : MonoBehaviour {
public virtual bool IsConditionTrue(Unit caster, Unit target)
{
return true;
}
}