Hello,
So I have been looking into ScriptableObjects and trying to figure out a good use case for an RPG magic system. Ideally, a designer friend would be able to jump into Unity, create some spells, define some characteristics (such as name, description and cost) and then I could write out the behavior.
Where I have the issue is how to get custom behavior out of each spell. I would like to do rather extensive behaviors of each spell, that take into account things such as player exp, health, and even play time to effect certain things. Basically things that can’t all feasibly be fields in the SO template.
So I think the idea would be to write a separate script for each spell. Ideally, if I could even drag the script onto the SO that would be great, but I don’t think that’s possible unless I’m missing something basic?
If that’s not possible, does anyone have any suggestions on achieving this sort of functionality?
Short version: I would like a designer to be able to create SO’s for spells to define basic things like name, cost and description, but I would like to be able to go in and write a script/very custom behavior for each spell and somehow associate them with the SO’s he’s created. If there’s no direct drag-drop way, any suggestions on how to achieve this? Thanks!
One way would be to set up your magic spell as a prefab.
You could have one script that’s the manager for the skill/spell, and that would be on the root object of the prefab. It’s this that’d you use to make any events to tie into, initialize all of the various components, and that outside scripts would use to interact with that spell, like starting the cast, canceling it prematurely, etc… Other objects in the prefab could be hitboxes, for calculating collisions (figure out which enemies are being hit by the spell as it’s going), sprites, models, particle systems for special effects, etc… Essentially, the prefab and components on the prefab are responsible for all of the real in-scene effects, so the main spell script on the root would be the one to control all of the logic and piece all of that together into a cohesive object. By having a prefab, you could instantiate as many of them as needed, including using them in object pooling systems in the scene so that you can avoid the cost of realtime instantiation and destruction (which can be quite expensive and cause lag).
The ScriptableObject, on the other hand, could store the reference to the specific prefab to use for that ‘spell identity’, along with any pure data you need to apply to the result, like damage multipliers, spell range, etc… In general, ScriptableObjects are best for storing things that don’t require runtime changes, configuration information that’s decided on in the editor and which nothing really messes with once the game is running, whereas the things that move/have timelines and affect objects with colliders and such need to be scene objects, or prefabs you can instantiate as scene objects.
That’s not to say you couldn’t put all of that information in the prefab itself, and not use a ScriptableObject at all, but the SO makes it easier to reference in code from anywhere in the game, so you don’t have to maintain scene references to all of your spells. It also means you separate out the data from the logic, which is nice from an organizational standpoint- if you just need to change the amount of damage the spell does, you can do that in the SO without messing with any of the mechanics of how the spell operates.