Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question Designing a modular abilities system (Scriptable Objects, Serialization problems.)

Discussion in 'Scripting' started by polypixeluk, Mar 4, 2021.

  1. polypixeluk

    polypixeluk

    Joined:
    Jul 18, 2020
    Posts:
    53
    I can see I’m heading into murky waters with my Abilities system and could benefit from some feedback / advice. Here is where I’m at:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3. using UnityEngine.UI;
    4.  
    5. public enum StatAdjustType { Burst, OverTime };
    6. public enum TargetStat { Health, Mana, CastTime };
    7. public enum Target { Self, Enemy };
    8. public enum SpawnPoints { BelowCaster, BelowTarget, Projectile };
    9.  
    10. [System.Serializable]
    11. public class AbilityComponent
    12. {
    13.     public Target target;
    14.     public float initialCastTime; //How long it takes before the effect manifests
    15.     public float effectLifetime;
    16.     public bool disableCastsWhileActive; //If true, CastTimer adds effectLifetime onto time it disables casting
    17.     public StatAdjustType statAdjustType;
    18.     public float power;
    19.     public TargetStat targetStat;
    20.  
    21.     //Visual components
    22.     public GameObject visualEffect;
    23.     public SpawnPoints spawnPoint;
    24.     public float endDelay; //Start delay = castTime
    25. }
    26.  
    27. [CreateAssetMenu(fileName = "New Ability", menuName = "Abilities/New Ability", order = 2)]
    28. public class Ability : ScriptableObject
    29. {
    30.     public string abilityName;
    31.     public string description;
    32.     public float manaCost;
    33.     public Sprite icon;
    34.  
    35.     public List<AbilityComponent> abilityComponents = new List<AbilityComponent>();
    36.  
    37. }
    When I make a new Ability I can add AbilityComponents in the inspector and then set all the relevant per component settings just fine. In game a UseAbility method takes in an Ability and processes each AbilityComponent in turn. So far so good.

    However!

    I want to start doing more specialized abilities. I thought I’d use AbilityComponent as a base class that more specialized abilities (such as a Shield Spell) can derive. I think these more specialized ability components will need monobehaviour’s methods but if I have AbilityComponent derive from monobehaviour then the inspector no longer shows (serializes?) the properties of each AbilityComponent.

    Is there really no way to get the inspector to show the properties of an Ability’s AbilityComponents if they derive from MonoBehaviour?

    If so can anyone suggest a better way of approaching what I'm trying to do here?

    Many thanks.
    D
     
  2. Adrian

    Adrian

    Joined:
    Apr 5, 2008
    Posts:
    1,098
    Unity serialization doesn't support polymorphism, i.e. all deserialized objects will be of the exact field type and any subclasses will be lost.

    You could turn AbilityComponent into a scriptable object. References to Unity objects do support polymorphism.

    With Unity 2019.4+ you can also use the [SerializeReference] attribute. Do read the documentation, it comes with its own limitations.