Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Create a list of Classes as property of a Scriptable Object?

Discussion in 'Scripting' started by MysticTortoise, Jun 29, 2023.

  1. MysticTortoise

    MysticTortoise

    Joined:
    Mar 29, 2023
    Posts:
    2
    I'm working on a little turn-based combat system, and I'm trying to implement status effects.
    Originally I was going to make a StatusEffect scriptable object (as I have done for most other types of assets in my project) however I wanted to have the code for status effects contained within themself rather than scattered in different parts of other code, so I instead wanted to use components all derived from a StatusEffect Mono Behavior.

    The problem is, since all of my attacks are stored as scriptable objects, I've had difficulty finding ways to allow attacks to apply status effects. What I would like to do is have a list of Scripts (classes derived from StatusEffect) stored as part of the Attack Scriptable Object but after lots of confused Google searches I don't really know how to do so, if that is even possible.

    What I have tried is making a property of the Scriptable Object that is just a List using the StatusEffect type, but then I am unable to set the StatusEffects in the editor, and while I did notice the "Assets" tab in the popup, it does not add any results, so I am assuming that fundamentally doesn't work (I assume that would be a list of already-created and instantiated StatusEffect components)
    I have also tried creating empty prefabs with nothing but said StatusEfffect-inherited component, and that doesn't appear in the pop-up either.

    Any help?

    Attack Scriptable Object code: upload_2023-6-29_0-46-24.png
    Status Effect code:
    upload_2023-6-29_0-46-40.png
    Results of what I've already tried:
    upload_2023-6-29_0-47-59.png

    (note: it's late for me, so i will not respond for several hours)
     

    Attached Files:

  2. Reid_Taylor

    Reid_Taylor

    Joined:
    Oct 9, 2019
    Posts:
    57
    Maybe this is too late, but I saw that this had no replies.
    If you no longer are working on this then feel free to ignore this :).

    I need some more information... So you have a bunch of attacks (which are scriptable objects created in your project) and that makes sense, but why do you want StatusEffect to be mono behavior? If you have prefabs with instances of StatusEffect that are instantiated, then that should work fine, but if you are just wanting data for status effects, then you shouldn't make the StatusEffect class derive from mono behavior and just make it [System.Serializable]. Then you would have to call Start, updateTurn, and effectEnd on some other mono behavior.
     
  3. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,881
    It can work, just Unity's limited Object picker doesn't show results for component types among assets. You will have to manually drag any prefabs with the right component on the root object into the field.

    Do note that scriptable objects can't reference scene objects, in case that's what you were trying to do.

    Though these statuses would probably be better off as scriptable objects as well. They could also be plain C# classes as well, though to do this require SerializeReference and some editor addons to make it usable.

    As for how to apply them, well, you're already getting both the target and the attacker in your
    GetDamage
    method, so why not re-frame to a 'PerformAttack' method? Instead of just returning an attack value, it could directly interface with the target and apply damage to it, alongside apply any status affects at the same time.
     
  4. Reid_Taylor

    Reid_Taylor

    Joined:
    Oct 9, 2019
    Posts:
    57
    Oh haha. After reading what spiney199 said, I get what your issue is :). Yeah, spiney199 is correct.
     
  5. MysticTortoise

    MysticTortoise

    Joined:
    Mar 29, 2023
    Posts:
    2
    The reason why I didn't want to do that is mostly future-proofing. Let's say I wanted to make a status effect that would, say, deal extra damage if you attack an enemy consecutively, or something like that. I could implement some kind of system inside of the Fighter object for this, but really I think that having individual code inside of each status effect is a simpler and cleaner method of doing this.

    But thanks for the help! I'll definitely see what I can do to clean up and fix what I ended up implementing (which is a bit of a sketchy system using statuseffect Names to create them)

    EDIT: Thank you! I got it working really easily and in a simpler way than before. (Although, having to make a prefab all the time might get annoying!)
     
    Last edited: Jul 8, 2023
    CodeRonnie likes this.
  6. CodeRonnie

    CodeRonnie

    Joined:
    Oct 2, 2015
    Posts:
    287
    This is just a thought, but you could have your status effect scriptable object assets act as a factory that creates and attaches the appropriate component to the fighter. You should be able to just implement that once in your base status effect asset which creates the appropriate, possibly generic MonoBehaviour. The scriptable object could inject itself into the created MonoBehaviour so that the relevant serialized property data can be easily accessed.
     
    spiney199 likes this.