0
\$\begingroup\$

I have ScriptableObjects with special code functions that all are slightly different in their interaction, all derived from one main ScriptableObject. This has lead to making the ScriptableObject script and then having to use the CreateAssetMenu attribute and then making the actual instance in the inspector. It creates a situation where I have two files bloating up the project, once I get many different derived ScriptableObjects it gets quite chaotic. How would I solve this?

To further clarify, I have "Pickups" that contain special functionality for what they do, some heal you, some give you bonuses, some move you in a certain direction, some change your gravity, work over time effects.. etc. so I'm using ScriptableObjects to handle the functions of them and the data. When you activate them they call an Activate function, a Tick function, and a Deactivate function, and all the special code is in there so it's not bloating up the player classes with each individual pickup code.

\$\endgroup\$
2
  • \$\begingroup\$ Can you tell us anything more about what these derived types represent or how they're used in your game? If all we know is how you've built them, then we can't tell which aspects of that strategy are vital to your game and which ones are optional or unwanted, making it hard to suggest alternatives that accomplish what's vital while minimizing the unwanted side effects. The more you can tell us about your use case and what you want to achieve, the better we can suggest ways to achieve it. \$\endgroup\$
    – DMGregory
    Oct 13, 2021 at 19:09
  • \$\begingroup\$ I've added more clarification for how I am using them in the scope of my game, thanks. \$\endgroup\$
    – baiomu
    Oct 14, 2021 at 0:34

2 Answers 2

0
\$\begingroup\$

I hear what you are saying; my solution is simply to keep the project organized so that the scripts are in one folder, and the objects themselves in another.

In the example below I have numerous "TileBehavior" scripts which all derive from an abstract base TileBehavior that derives from ScriptableObject.

ScriptableObject Scripts

Many (but not all) of the Objects that are created from them are singletons and I put them all at the root of a TileBehavior folder, in the case where there are multiple versions of an Object I put them in child folders named accordingly.

ScriptableObject Objects

To group similar types of objects into a single context submenu, you can use a path-like structure in the menuName parameter of the CreateAssetMenu attribute:

[CreateAssetMenu(menuName = "TileBehaviors/Break Up Tile Behavior")]

Create menu and submenus

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Any tips for how to manage all the distinct context menu entries for creating each unique variant? \$\endgroup\$
    – DMGregory
    Oct 13, 2021 at 20:05
0
\$\begingroup\$

I think your question is two parts: how do I deal with a massive number of subclasses and how do I deal with many data objects. I'll address the first question.

To further clarify, I have "Pickups" that contain special functionality for what they do, some heal you, some give you bonuses, some move you in a certain direction, some change your gravity, work over time effects.. etc

You could change the way you think about your behaviours to be less specific. Instead of a pickup that heals you, create one that modifies one of your stats for a period of time. Then a single ScriptableObject behaviour can heal, damage, decrease speed, increase damage, etc. The time period could accept a negative value meaning that it's permanent.

A stat could be another scriptable object -- while this adds a new family of scriptable objects, they'd be a smaller set that is less likely to grow and are heavily referenced in your pickup behaviours.

This would reduce the number of pickup ScriptableObject classes you write, but you'd have the same number of ScriptableObject instances. For those, put them in folders and use project search to keep them clean.


For another take on this problem: try using Unity's quicksearch to activate the "Create Asset" menu and to locate your ScriptableObject instances.

\$\endgroup\$
3
  • \$\begingroup\$ Can you explain more about making stats into their own scriptable objects? Right now I have a dictionary of strings with stat names and their associated "Stat" object, and do all of my referencing through there. Would stats being scriptableobjects be more beneficial? \$\endgroup\$
    – baiomu
    Mar 15 at 8:36
  • \$\begingroup\$ @baiomu: You could define a Stat ScriptableObject with multiple instances: Atk, Str, Def. Then you can reference those instances directly from other scriptable objects and find references to them. When a Pickup references a Stat, you'll only be able to pick valid ones and the picker shows the whole list (no "ATtack" typos from strings). It also makes it easy to group related info: Each stat object could have a colour for drawing it (in UI, debug prints, editor windows), a format string for how it's displayed (% vs +-), etc. \$\endgroup\$
    – idbrii
    Mar 17 at 19:27
  • \$\begingroup\$ You could even have different subclasses of Stat with behaviour like MergeStats(Stat a, Stat b) to merge two stat values together (Atk might sum, but Def might multiply) but that's going pretty far and might make the logic harder to understand. Just using the objects as tags (instead of strings or enums) is useful on its own. \$\endgroup\$
    – idbrii
    Mar 17 at 19:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .