Wondering what's the best way to structure the code for items with effects?

Definitely don’t go the enum route. It will not scale well.

Your first approach is fine and is the general ‘wide but shallow inheritance hierarchy’ that is common in these types of situations. Only downside is that you do end up with lots of scriptable object types, and a very full Right-Click → Create menu.

The alternative is to use [SerializeReference], which lets you serialise plain C# objects with polymorphism. Upside is that you can have one scriptable object class that encapsulates a plain C# object. Downside is that it would need custom inspector support.

Fortunately I’ve written a reusable example here: abstract SkillList that can be edited in Inspector - #15 by spiney199

And applied to this use case:

public interface IArtifactEffect
{
	void ApplyEffect(Character character);
}

[CreateAssetMenu]
public sealed class Artifact : ScriptableObject
{
	[SerializeReference, SubclassSelector]
	private IArtifactEffect _artifactEffect;
	
	public void ApplyEffect(Character character)
	{
		_artifactEffect?.ApplyEffect(character);
	}
}

And then you just make serializable C# classes implementing IArtifactEffect whenever you need new effects and so on.

3 Likes