- Home /
Should I be using Scriptable Objects that only contain a method implementation?
So, I want to create an ability system for my game (rpg) and I want it to be as modularized as possible, since I will be reusing a lot of functionality and I want to have an easy way of creating and tweaking them.
I have then decided to make this system heavily based on Scriptable Objects, with abilities being created as such and containing another Scriptable Object that has targeting data(such as range, Area of Effect, etc) as well as a list of On Use Effects.
Now comes my problem : I was about to create those On Use Effects as Scriptable Objects as well, when I realized that most of the time they will be nothing but a single method implementation (The OnUse method) and there is this voice in my head that keeps saying "Scriptable Objects are supposed to hold data", and I can clearly see there is a fundamental difference between this and my previously created Scriptable Objects, since with no fields I would be only ever having one instance for each implementation. This seems like I'm doing it the wrong way, but I still need to do it in a way that communicates well with the setup I have.
So, is it bad design to use Scriptable Objects that only hold a method implementation? Is there something more appropriate for this?
Answer by destructivArts · Jan 03, 2017 at 12:32 AM
I think it really depends on what you consider to be overkill.
As an aside, there's no reason you can't have a ScriptableObject contain methods though. I'm guessing there's a good chance you've seen it, but this talk is really great at showing a number of ways to use ScriptableObjects.
But back to my point, it all comes down to how far you want to go. If you want to have a plug-n-play behavior available to your designers, then giving them ScriptableObjects representing functionality isn't illegal or even discouraged. On the other hand, if you think you'll end up only having one OnUseEffect per ability, its not really worth it.
Another way around the problem is to create your OnUseEffect class as a straight C# class, which is created by a Construct method in an OnUseEffectSettings scriptable object. This way, if you need to, you can pass settings into it on create, and you aren't relying on the ScriptableObject for functionality (which opens up possibilities as far as tracking your own state go) (look up Dependency Injection for why this sort of thing is awesome).
In the end, don't worry so much about using Unity the way Unity wants you to use it. There's a lot of good stuff Unity put in, and knowing how they want you to go about things is a great starting point until you find that its getting in the way. And when that happens, do what you need to do. There's also a lot of great material out there describing other ways of using Unity. Even that talk I linked to above (which is by a Unity employee, talking about a different way to use Unity) is an example.
Anyways, I hope this helps! Best of luck
Thanks for the answer! Your suggestion for creating the OnUseEffectSettings seems like a cleaner approach to me, so just to see if I got it right, I would create the OnUseEffect as a straight class (which I forgot to mention, but its supposed to be an abstract class) and derive from it as usual, and then use the OnUseEffectSettings to instantiate, save and manage those classes, kind of like a database?
EDIT: Actually, after watching through the video you linked, I have made up my $$anonymous$$d and I'm sticking with my initial approach, thanks!
I basically did what you did. I have a super generic spell system that would allow anyone to create spells on the fly and makes it easier to develop as about 200+ spells have to be made. I made my Target system ScriptableObjects. They hold no data and have 1 function, Execute. I just create one target type, ex. TargetSelected. Then drag and drop it into the spell and now it's a Spell that requires a target. It seemed the easiest way without doing a if or switch statement and having a bunch of if or switchs would be less efficient. I'll take the 1kb scriptable object thing haha.