I would go so far as to say infuriating. I did not know this behaviour when I first learned about ScriptableObjects, and planned a whole saving system around them (this was long before the RPG course)… weeks of work tanked in a single Build.
Bonus tip: You may wish to consider bonus artifacts… you might have a staff that grants +2 to Fireball… The trouble with this is you’re having to check lots of areas for bonuses, and that’s not terribly convenient and could easily create cross dependencies… So you might want to consider an interface like the IModiiferProvider
public interface IAbilityLevelProvider
{
IEnumerable<int> GetAbilityModifer(InventoryItem ability);
}
Then your Talent Tree would be an IAbilityLevelProvider, as well as your StatsEquipableItem, and your StatsEquipment…
In StatsEquipableItem you just need to add something like:
[System.Serializable]
class Boost
{
public InventoryItem item;
public int modifier;
}
[SerializeField] Boost[] boosts;
Dictionary<InventoryItem, int> boostDict;
void PopulateBoostDict()
{
if(boostDict!=null) return;
boostDict = new Dictionary<InventoryItem, int>();
foreach(Boost boost in boosts)
{
boostDict[boost.item] = modifier;
}
}
public IEnumerable<int> GetAbilityModifier(InventoryItem ability)
{
PopulateBoostDict();
if(boostDict.ContainsKey(ability) yield return boostDict[ability];
}
Your StatsEquipment just needs to find any IAbilityLevelProvider equipped and yield return their values, and of course your talent tree would yield return the current value as well.