How to structure Enemy code using Scriptable Objects?

I am creating a simple platformer with multiple kinds of enemies. I am learning about scriptable objects and have implemented them for Items in my game following a tutorial.

I am trying to implement Enemies in the same way, but I’m not sure which (if either) structure is correct. And when I’d use one over the other. I was sketching it out on paper, so you can see that in the Imgur link below, otherwise I’ll summarize here.

Item Implementation

  • Item scriptable object with itemNname, description, icon, and a Use() method
  • Consumable script which derives from Item. This is what appears in the Create Asset menu. This script just defines what happens in the Use() method.
  • HealthPotion Consumable asset that runs the Use() method when clicked

Proposed Enemy Implementation

  • Enemy scriptable object with name, description, health, damage, (what methods should go in here? Attack()?)
  • FlyingEnemy script which derives from Enemy. This is what appears in the Create Asset menu. I’m not really sure what should be defined in this script. I have things like enemy movement, animations, setting health values, floating combat text, etc. that I want to implement. I don’t think those go here, right? It doesn’t appear I can use Start() and Update() methods on scripts that derive from scriptable objects
  • Eyeball Enemy asset where I set the values

Am I on the right path here? I have a current implementation set up without using scriptable objects, but it doesn’t seem scalable. Thanks for the help and any advice!

It depends a great deal on how similar your enemies are. I found that since I would want custom animations for each enemy it wasn’t practical to have the enemies mostly driven by scriptables (not impossible, but more work than it was worth). However, if your enemies are very similar in behavior code wise, yeah you can certainly go that route. The thing you just want to avoid is having massive script that amount to:
If enemy X
do enemy X stuff
else if enemy Y
do enemy Y stuff

That defeats much of the purpose of merging the enemies.

Usually I don’t put logic on Scriptable Objects at all. The SO holds the data and a monobehaviour handler class reads the data and performs the actions.